知识卡片

分布式日志的三大核心需求与负载类型

普通读书笔记卡

内容

在[[用日志解决最终一致性系统的CAS冲突]]这个动机之上,要把日志构建成一个可供所有分布式系统复用的基础设施,首先要想清楚需要满足哪些基本需求。Twitter梳理出三条核心需求,且这三条需求之间存在递进依赖关系:一是持久化(Durability)——作为基础设施,日志中的数据必须持久化,否则宕机就会丢数据;二是多副本(Replication)——单机持久化对分布式系统基础设施而言远远不够,必须把数据复制到多台机器上以提高可用性;三是强一致性(Consistency)——一旦数据被复制到多台机器,就必须保证这些副本之间的强一致性,否则丢数据或数据不一致会波及所有构建在这个日志之上的系统,”如果连日志都不能相信了,你的生活还能相信谁呢”。之所以强调这三者,是因为Twitter原有的消息中间件(Kestrel用于在线系统、Kafka用于离线分析)都不支持严格的持久化,只靠定期回刷磁盘或依赖文件系统这类弱手段,一旦出事故就丢数据,运维人员经常被追问”到底丢了多少数据”却答不上来。除了这三条基本需求,日志系统还需要理解自己核心负载的构成,才能谈”高性能”——日志系统的核心负载可以归为三类:write(把数据追加到日志)、tailing read(从日志尾部读最新数据)、catch-up read(从较早的位置开始读日志,比如重建副本)。write和tailing read在意的是延时(Low Latency),因为它们关系到消息从写入到被读到的时间间隔;catch-up read在意的是吞吐量(High Throughput),因为它关系到能否追上日志的尾部。理想情况下系统只需要应付write和tailing read两种负载,但现实中(尤其在多租户环境)catch-up read往往是影响系统的重要因素——比如流式计算任务重启后从很早的位置开始大量读取数据,这类大批量扫描会导致文件系统做大量预读取到Page Cache里,反而挤掉最新数据、拖累写操作和tailing read的表现。

参考来源

- 位置:《高可用架构(第1卷)》第1章《高可用架构案例精选》"1.1 Twitter高性能分布式日志系统架构解析"节,"1.1.1 为什么需要分布式日志"及"1.1.2 Twitter如何考虑这个问题"(源文件:_epub-src/OEBPS/Text/Chapter1_1_2.xhtml、Chapter1_1_3.xhtml) - 结论依据:原文说明"首先,作为一个基本设施,存储在日志中的数据需要持久化……我们需要将数据复制到多台机器上……当数据被复制到多台机器上,就要保证数据的强一致性",并给出"日志系统的核心负载可以归为3类:write、tailing read和catch-up read"及各自对延时/吞吐量的侧重,直接支撑本卡片结论。 - 原始内容:write和tailing read在意的是延时(latency),因为它关系到一个消息从被写入到被读到的时间。因此前文中说的High Throughput指的是catch-up read,而Low Latency指的是tailing read和write。