BookKeeper是一个可靠的日志流记录系统,用于将系统产生的日志(也可以是其他数据)记录在BookKeeper集群上,由BookKeeper这个第三方Storage保证数据存储的可靠和一致性。典型场景是系统写write-ahead log,即先把log写到BookKeeper上,再对log做处理,比如将log写到内存的数据结构中。BookKeeper同时适用于任何单点写入并要求保证高性能和数据不丢失(Strong Durabilty Guarantees)的场景。
BookKeeper诞生于Hadoop2.0的namenode HA。在Hadoop中,出于故障恢复的考虑,Namenode在对它的记录做修改前都会先将本条修改的日志写到磁盘上。但是这里有一个潜在问题,当Namenode发生故障时,很可能连本地磁盘也不能访问,这时之前的记录的日志也就没用了。基于上述考虑,可以将Namenode的日志信息保存在一个可靠的外部Storage中。最初业界通过NFS这样的Share Storage来实现日志同步。之所以选择NFS,一方面因为可以很方便地实现数据共享,另外一方面是因为NFS相对稳定成熟。虽然如此,NFS也有缺点不能满足HDFS的在线存储业务:网络单点及其存储节点单点。为了满足共享日志的高可用性,社区引入了BookKeeper。除此之外还有默认的HA方案:QJM。
BookKeeper介绍
BookKeeper带有多个读写日志的server,称为 bookies。每一个bookie是一个BookKeeper的存储服务,存储了写到BookKeeper上的write-ahead日志,及其数据内容。写入的log流(称它为流是因为BookKeeper记录的是byte[])称为 ledgers,一个ledger是一个日志文件,每个日志单元叫 ledger entry,也就是bookies是存ledgers的。ledger只支持append操作,而且同时只能有一个单线程来写。ZK充当BookKeeper的元数据存储服务,在zk中会存储ledger相关的元数据,包括当前可用的bookies,ledger分布的位置等。
BookKeeper通过读写多个存储节点达到高可用性,同时为了恢复由于异常造成的多节点数据不一致性,引入了数据一致性算法。BookKeeper的可用性还体现在只要有足够多的bookies可用,整个服务就可用。实际上,一份entry的写入需要确保N份日志冗余在N个bookie上写成功,而我们需要>N个bookie提供服务。在启动BookKeeper的时候,需要指定一个ensemble值,即bookie可用的最小节点数量,还需要指定一个quorums值,即日志写入BookKeeper服务端的冗余份数。BookKeeper的可扩展性体现在可以增加bookie数目,增加bookies可以提升读写吞吐量。
下面这张图,展示了序列化日志怎样写入到Bookie上。
Ledger记录首先写入到Journal,然后再写入到Indexes和Entry Log。写入到Journal是同步落盘持久化的。写入到Entry Log的是先缓存在Page Cache中,异步刷盘。一般建议Journal与日志实体(Entry Log/Ledger Indexes)分开存储,避免写入IO竞争。另外,为了写入的高性能,Journal选择SSD保存;日志实体可以存储在通用的硬盘设备上,比如JBOD。
由于不同Ledgers的记录都是汇聚到一起写入Entry Log的,即Bookies是顺序写,随机读的。为了提升读取性能,Bookies给每个Ledger维护了一个Ledger Indexes。这个索引映射日志实体(entries)位置与Ledger的关系(即entry log上哪个位置开始到哪个位置结束的数据属于哪个Ledger)。
BookKeeper 在yahoo的消息系统应用
雅虎多租户分布式消息系统,也叫云消息服务(CMS)。CMS在yahoo内部被60多个应用使用,包含移动消息系统,天气系统和广告平台、个性化平台、主页和存储系统比如 Sherpa。
CMS提供尽力投递(Best-Effort)和保证投递(Guaranteed message delivery)。保证投递需要适应网络,磁盘和服务器故障。CMS使用BookKeeper作为存储消息,作为可靠消息队列。另外,在BookKeeper上维护每个消息的消费位置,在至少一次(at-least-once)投递场景下。
CMS使用BookKeeper的原因:
1、 CMS已经部署在10+个数据中心,全网络备份。
2、 大约100亿消息/天通过BookKeeper交换,预计到2015年底1000亿消息/天。
3、 CMS已经部署了250+台。到2015年底,期望部署1500+台。
4、 CMS目前有25000个队列,将增长到百万队列。
5、 CMS应用在雅虎的60多个服务器应用中。
6、 到目前为止,BookKeeper在CMS运行良好,使得有信心达到2015的目标。
未来的挑战
BookKeeper在可扩展性和可靠性,有一些挑战。下面是可以提升点:
1、 优化Cache,提升每台Bookie的吞吐量到10倍
2、 每台bookies上,增加5倍的ledgers。
3、 提升租户隔离性能,保证高读负载
4、 降低发布时延到1ms以下。
参考:
1、 https://yahooeng.tumblr.com/post/109908973316/BookKeeper-yahoos-distributed-log-storage-is
2、 http://BookKeeper.apache.org/docs/master/BookKeeperOverview.html
3、 http://BookKeeper.apache.org/docs/master/BookKeeperLedgers2Logs.html