知识卡片
分布式日志的三大核心需求与负载类型
内容
在[[用日志解决最终一致性系统的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的表现。