
实时应用中的状态副本带来隐性成本
来源标题:Real-time state has a cost your memory bill won’t show
实时应用常组合Kafka、Flink、Redis和数据库等工具,但跨组件的数据副本会产生隐性成本。文章指出,为容错和恢复而保留的副本值得付出代价,真正值得质疑的是因处理与读取分离而维护的重复状态。以Flink计算支付卡五分钟交易次数为例,欺诈评分服务还需另行读取结果。
以下正文由 AI 翻译自 The New Stack(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
实时应用常常组合使用角色各异的工具。典型配置可能用 Kafka 处理事件,用 Flink 处理数据,用 Redis 提供最新状态,再用数据库维护系统记录。使用向量搜索的应用可能还会加一个向量存储。
这种职责划分带来了灵活性和独立扩展能力。但当数据在组件之间移动,或在多个位置维护重叠状态时,也会产生成本。
“值得质疑的副本,是那些主要因为处理发生在一个系统中、而应用从另一个系统读取结果才被维护的副本。”
其中一些副本是必要的。副本用于防止故障,检查点帮助系统恢复,持久事件日志保留历史。这些成本值得付出。值得质疑的副本,是那些主要因为处理发生在一个系统中、而应用从另一个系统读取结果才被维护的副本。
以跟踪支付卡过去五分钟交易的速度计数器为例。Flink 计算计数并维护键控状态来支持该计算。
但欺诈评分服务也需要获取结果。Flink 的内部状态并非为通用服务而设计,而且 Flink 在 1.18 中弃用了 Queryable State 功能。常见解决方案是将计数发布到 Redis。
这为应用提供了专用的服务层,但也带来了自身的扩展和运维要求。Flink 的工作状态与 Redis 中的值可能重叠,但并不完全相同,而且每次发布更新都涉及序列化、网络传输和处理,之后消费者才能看到。
一致性变得复杂的地方
当应用跨越可用区时,保持状态同步会变得更加复杂。
设想一个假设的支付系统,它从多个可用区的异步副本提供读取,以减少跨区流量。一笔退款完成了,但更新仍在传输到其中一个副本。
从该副本读取的服务可能认为交易尚未退款,并再次发起退款,尽管第一笔已经处理完毕。如果退款路径之间没有协调,客户可能会被退款两次。
“如果退款路径之间没有协调,客户可能会被退款两次。”
只要决策依赖于异步复制的状态,这就是一个应用设计问题。将处理和存储放在同一平台上并不一定能避免它。
直接问题是副本滞后,再加上应用在没有原子性地检查和更新授权退款的状态的情况下做出决策。如果退款调用外部支付服务,该服务还需要幂等请求机制,以便重试不会导致同一笔退款被处理两次。
分离的处理和服务设计还引入了发布延迟:处理器可能在服务存储收到更新值之前就已计算出该值。这是导出滞后,不同于服务存储内部的副本滞后。在这段滞后期间,一波欺诈交易可能依据过时的计数进行评分。导出滞后和副本滞后都可能让应用读取到过期数据,但两者都不应与可能导致重复退款的“检查后执行”竞态条件混淆。
对于计算直接针对已存储状态运行的工作负载,Hazelcast 可以避免单独的发布步骤。其条目处理器可以在持有相关键的成员上原子性地更新单个映射条目。不过,这并不会使系统在网络分区期间自动具备强一致性。
需要更强协调的应用可以使用 Hazelcast 基于 Raft 的 CP 子系统中适当配置的数据结构。使用它并不会将普通的 IMap 变成强一致性映射,也不会使映射更新与外部支付成为原子操作。分离的处理和存储系统也可以使用强一致性协调。
移动状态的代价
在讨论内存架构时,内存往往占据主导地位,但 CPU 和网络成本同样重要。
加州大学伯克利分校和 Databricks 于 2025 年发表的论文《Rethinking the Cost of Distributed Caches for Datacenter Services》使用合成工作负载、Meta 追踪数据和 Databricks Unity Catalog 的生产数据,考察了缓存的经济性。
“在讨论内存架构时,内存往往占据主导地位,但 CPU 和网络成本同样重要。”
根据论文中 Google Cloud 的定价假设——每 vCPU 每月约 17 美元,每 GB 内存每月约 2 美元——研究人员发现,增加内存缓存将运营成本降低了三到四倍。节省的 CPU 成本超过了额外 RAM 的成本。
这并不是 Hazelcast 与 Flink 和 Redis 的对比;该研究比较的是有缓存与无缓存的情况。其远程缓存与链接缓存的比较支持了一个更窄的论点:通信和序列化消耗 CPU。
论文还发现,为实现更强一致性而进行的每次读取版本检查可能会抵消大部分成本收益,因此比较需要在同等一致性要求下进行。
Google 研究人员 2019 年的论文《Fast Key-Value Stores: An Idea Whose Time Has Come and Gone》报告称,在从远程键值存储迁移到将应用逻辑和内存状态放在一起的架构后,Google 应用组件 ProtoCache 的 p99.9 延迟降低了 40%。
另一个说明性计算展示了维护两个等效工作集的内存成本。按照论文假设的内存价格,400 GB 仅内存一项每月就约需 800 美元,还不包括备份、检查点和其他基础设施。
在处理层和服务层都维护同等数量的数据会使该数字翻倍,尽管 Flink 的中间状态和发布到 Redis 的结果可能差异很大。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。