在Twitter,他们使用复制日志来解决分布式系统中存在的一系列问题。比如,他们有一个 Manhattan分布式键值数据库 。该系统采用了一种灵活的最终一致性数据模型,允许开发者以一致性换取低延迟。写入操作会单独应用到数据集的所有副本,Manhattan会保证各个副本的数据最终一致。但是,应用程序在查询一个刚刚更新过的数据集时可能会因为读取的副本不同而获取到不同的数据。为了防止这种不一致的情况,他们必须针对每个副本以同样的顺序应用所有更新。日志(一个严格有序的操作记录)是实现序列化更新的一种简单方式。在Twitter,还有其它有类似情况的应用程序需要某种日志服务基础设施。于是,他们构建了DistributedLog,一个高性能的“复制日志(replicated log)”服务。近日,Twitter消息团队高级软件工程师 Leigh Stewart 撰文 分享了他们构建该服务的经验。
他们根据自己构建分布式系统的经验,对复制日志服务提出了如下要求:
为了满足上述需求,他们评估了几种可选方案,其中包括:(一)使用类似Kafka的发布/订阅系统;(二)使用类似 Paxos 或 Raft 的一致性算法构建新的服务或库;(三)使用一种像 Apache BookKeeper 那样的底层日志服务。对于Kafka,他们对其I/O模型心存疑虑,并认为它缺乏强有力的稳定性保证;Paxos和Raft颇具吸引力,但从头构建一个新系统需要一个很长的开发周期。于是,选项仅剩了Apache BookKeeper。这个最初为HDFS设计的事务日志后台唯一关注的是存储效率和日志段(称为Ledger)检索。另外,不同于Kafka,它并不关注发布/订阅系统中的一些高级特性,如“分区归属(partition ownership)”、面向流的抽象等。以下是Apache BookKeeper的核心优势:
因此,他们认定,BookKeeper是一个日志存储的上佳选择。不过,它虽然满足了上面列出的大部分关键需求,但是还缺少一些关键的特性,比如高级抽象、日志归属等。为此,他们在BookKeeper之上构建了一个服务层 DistributedLog ,提供一种可以满足上述需求的、端到端的服务,如下图所示:
BookKeeper 提供稳定性和高可用的日志段存储;DistributedLog提供简单的抽象,如命名、数据分割、保留策略等;应用程序层负责分区、路由、偏移量管理等高级特性。其中, DistributedLog 具有如下特性:
在过去的两年里,DistributedLog解决了许多分布式系统中颇具挑战性的问题,其本身也在发展。事实证明,基于DistributedLog的一致性写入路径非常可靠,而且性能令人称赞。将DistributedLog引入Manhattan的写入路径平均仅仅增加了10毫秒的写入延迟。
感谢郭蕾对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群 )。