Apache Kafka 广泛应用于实时数据管道、流处理、实时监控等方面,是大数据实时处理领域的重要工具。然而,在云计算和云原生技术日新月异的今天,Kafka的传统存储架构面临成本和弹性的新挑战。分层存储曾被认为能提供解决方案,但实践证明它并未根治问题,反而增加了复杂性。
本文作者 Richard Artoul 剖析分层存储的复杂性与高昂成本,直指各大供应商的分层存储解决方案“换汤不换药”。分层存储到底有没有用?怎么用?本文也许能提供一些新思路。
分层存储似乎是个好主意
分层存储是数据流处理系统领域的热门话题,是有道理的。云磁盘(真的)很贵,对象存储很便宜,而且在大多数情况下,实时消费者只是读取最近写入的数据。支付昂贵的云盘来存储历史数据并不划算,因此应该将历史数据(分层)移动到对象存储。从理论上来看,这非常合理。
但首先,分层存储在流式系统中究竟意味着什么?分层存储的基本思想是仅将最近的数据保存到磁盘,并将历史数据异步转移到可以低成本保存的对象存储中。
分层存储的实际应用
这种优化在 Kafka 的主要扩展维度是存储方面,例如当你需要长期保留主题(topic)时。这种情况下,分层存储可以(有时是显著地)减少所需的 EBS 卷数量,从而(有时是显著地)降低成本。
理论上,分层存储还可以减少存储在每个代理的本地磁盘上存储的数据量,以此减轻运营负担,这(以及其他优化)应该可以加快集群的扩展和缩小速度。一些特别热心的用户甚至乐观认为,从逻辑上讲,分层存储可以将 Kafka 变成一个现代数据湖。
Apache Kafka 中新增的分层存储功能令人兴奋不已,很可能是因为过去几年 Kafka 领域几乎没有创新,但用户仍然对成本、复杂性和运营负担方面的现状感到沮丧。分层存储会是大家期待已久的灵丹妙药吗?
不幸的是,答案似乎是否定的。去年,我与数百名 Kafka(和其他流处理系统)用户进行了交谈,其中不乏来自世界上最大、最先进的工程组织的人,但我没遇到一个对分层存储满意的用户。
我确实发现,许多人对分层存储评估后,意识到它不能大幅降低成本,于是就放弃了。我还发现,有些人尝试采用这种方案,但遇到了许多操作问题和痛点,于是认为它不值得被采用。我甚至发现一些人设法将它投入生产,但他们因此多了不少白发,而且几乎所有人都对最终结果感到失望。
我意识到我所说的一切都与业界的普遍观点相悖,所以让我解释一下我的思路。
陷入泥潭
分层存储可以降低某些工作负载的成本,但最终却因小失大。具体来说,分层存储的主要问题在于,它并没有解决人们目前使用 Kafka 时遇到的两个主要问题:
1. 复杂性和运营负担
2. 成本(特别是区域间网络费用)
事实上,我认为它不仅没能解决这些问题,反而使问题变得更加严重。
增加复杂性和运营负担
分层存储的第一个问题是,它并没有让 Kafka 变得更简单和容易处理,反而使其变得更困难和复杂。对 Apache Kafka 这样的现有系统进行改造时,考虑到部分数据存储在完全不同的存储介质中,成本和性能特征完全不同的事实,这就变得异常复杂。最终结果是,系统变得棘手而脆弱,存在一系列无止境的限制、尖锐边缘和难题。
例如,性能推理变得非常困难。假设一个 Kafka 消费者想要从头开始读取一个主题。在正常情况下,从 Kafka 获取一批记录只需几十或几百毫秒。但是启用分层存储后,读取第一批记录可能需要几十秒甚至几分钟。
造成这种情况的原因是,许多分层存储解决方案不支持从对象存储中增量读取数据。相反,这些实现要求在提供任何读取之前,从远程对象存储下载整个日志段。这是有问题的,因为日志段的大小可能是数百兆字节甚至数千兆字节。在下载这些大段日志时,消费者会被完全阻塞,无法取得任何进展。
有些分层存储实现通过分块机制支持增量读取,但日志段分块在从对象存储分页后仍需下载并缓存在磁盘上。将下载的分块写入磁盘会与实时工作负载争夺 Kafka 代理上有限的 IOPS(和磁盘空间)。这意味着单个消费者重放少量历史数据时,很容易干扰所有为生产流量提供服务的实时消费者。这也意味着,虽然分层存储确实减少了代理服务器上的磁盘空间,但这些磁盘的容量是有限的。我们需要为实时和历史工作负载留出足够的空间。
使问题更复杂的是,云盘的可用 IOPS 通常与配置存储量有关。但分层存储的重点是减少首先需要调配的磁盘存储量!
这类问题可以通过非常谨慎的容量规划、基准测试和配置调整来解决,但这很痛苦。此外,我所描述的问题一开始往往处于潜伏状态,然后在最糟糕的时候出现:出错时,需要在不牺牲实时工作负载可靠性的情况下重放历史数据。
需要读取历史数据的情况也不仅仅发生在紧急情况下。在过去的几个月里,我遇到过三个不同的组织,他们正试图从分层存储数据流处理系统迁移出来,他们描述道,无法迁移到新的解决方案,因为他们无法在不中断实时流量的情况下从分层存储中读取数据。
最后,也许最糟糕的是,分层存储引入的额外复杂性是附加的。除了你目前遇到的所有操作问题之外,还包括:
分区重新平衡复杂的共识机制性能问题缺乏弹性热点Broker负载不均衡ETC分层存储增加了一系列全新的附加故障模式和操作任务,但不会消除任何现有的故障模式和操作任务。
网络连接费用昂贵
除了运营之外,分层存储还有望降低 Kafka 的总体成本。不幸的是,它通常也无法兑现这一承诺,原因可能会让人大吃一惊——云网络费用。
如果你认为云盘价格昂贵,那么云网络(的费用)将令你大跌眼镜。区域间网络费用是数据流处理工作负载的无形杀手。具体来说,在标准 HA 三个可用区设置中的 Apache Kafka 集群每写入一个 GiB 的数据,成本为每 GiB 5.3 美分。相比之下,在 S3 中存储一个月的1 GiB 数据仅需 2 美分。
在三个可用区域中运行的标准 HA Kafka 集群的数据路径
那么,分层存储如何帮助降低区域间网络成本呢?遗憾的是,根本没有。为了确保高可用性和耐用性,你写入启用了分层存储的集群中所有数据仍必须复制到三个不同可用区域中的三个磁盘,然后才能被确认并被视为持久。分层在稍后才会实施,这是一个大问题,因为区域间网络通常占流式工作负载总成本的 80% 以上。
这意味着,无论broker的本地磁盘有多小,或无论分层存储将数据复制到对象存储的速度有多快,对于任何不绑定存储的工作负载,利用分层存储架构的流系统成本通常几乎与传统 Kafka 集群完全相同,就算它们将数据在本地磁盘上只存储一分钟也是如此。
无法启用新的用例
好吧,也许分层存储并没有如你所愿节省那么多钱,性能也难以预测,但你可以配置具有专用 IOPS 的 EBS 卷,进行一些非常谨慎的测试,并查看一切是否按预期运作。虽然处理起来有点复杂,但好处是完全值得的,对吧?毕竟,分层存储不仅仅是为了降低成本,它还能够让你做许多新的事情。
例如,由于所有数据都存储在对象存储中,因此理论上,你也可以直接针对这些数据运行批处理作业/查询,完全绕过brokers。这样,你的数据流就变成了一个数据湖。
如果可能的话,这确实很有用,但实际上并非如此。对象存储中的数据由broker主动“管理”(压缩、强制保留等),因此直接查询数据文件会导致异常:丢失和重复的记录,特别是由于缺乏快照隔离。除非你弄清楚如何在Broker磁盘和对象存储之间提供一个统一的视图,否则你只能查询热集之外的数据,这意味着你只能查询过期的数据。
你仍然可以使用 Kafka API 查询所有数据,但实际上,你的查询将受限于托管你想要查询的主题分区的Broker的最大吞吐量。例如,如果你只想查询部分主题,而这些主题只托管在你的Broker子集上,即使你的其他Broker都处于空闲状态,你可能也只能使用集群总容量的一小部分来运行查询。
理论上,当你需要扩展读取容量时,你可以临时将一些Broker标记为特定主题分区的“只读副本”,这样它们就拥有所有数据层级化到对象存储的元数据,并可以提供读取服务,但不参与任何领导者选举,你只需要确保它们不要复制尚未层级化的数据,以避免浪费太多磁盘空间,而且……这一切听起来是一项艰巨的工作。
伪装的分层存储
我不是唯一一个对数据流处理领域分层存储虚假承诺感到失望的人。许多用户和业内专家开始认识到,分层存储并不是他们所期望的万能钥匙。因此,许多系统和供应商都选择了阻力较小的道路:重新包装他们的分层存储解决方案。
请留意以下短语:
1.“云优先存储”(即分层存储)
2.“基本无状态”(即分层存储)
3.“将磁盘用作对象存储的前置缓存”(即分层存储)
这些术语实际上都只是变相的老式分层存储,我以前写过这个问题,但值得重复:对于现有参与者来说,进行增量修改,然后重新包装、重塑品牌要比为用户做正确的事情(即为云完全重建数据流处理系统)容易得多。
零磁盘会更好
希望你现在已经相信,尽管分层存储确实有一些好处,即降低某些工作负载的存储成本,但它并不是向你所承诺的那种根本性改进。虽然它可能会降低成本,但肯定不会简化操作或让你的生活更轻松。实际上恰恰相反,它会让你的 Kafka 工作负载更加不可预测、更难管理。
最后我总结一下:分层存储的关键在于使用更少的磁盘。但是,如果你能从头开始为云重建数据流处理系统,那么你可以实现比更少磁盘更好的东西——零磁盘。一些磁盘和零磁盘之间的差异是天壤之别。零磁盘,即所有内容都直接通过对象存储运行,没有中间磁盘,会更好,会好得多。
作者丨Richard Artoul 编译丨onehunnit
来源丨warpstream.com/blog/tiered-storage-wont-fix-kafka
*本文为dbaplus社群编译整理,如需转载请取得授权并标明出处!欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn