周五去Hadoop in China 2011打酱油,下午听了一场来自Yahoo!巴塞罗那研究院科学家Flavio Junqueira先生的演讲。他演讲的主题是《Apache BookKeeper: High-performance reliable write-ahead logging》,主要是介绍了一种高可靠日志记录存储系统也就是BookKeeper(BookKeeper is a system to reliably log streams of records)。
开发Bookkeeper最初是源于这样一个问题:在Hadoop中,因为故障恢复的考虑,Namenode在对它的记录做修改前都会先将本条修改的日志写到磁盘上。但是这里有另一个潜在问题,当Namenode发生故障时,很可能连本地磁盘也不能访问,这时之前的记录的日志也就没用了。基于上述考虑,可以将Namenode的日志信息保存在一个可靠地分布式存储系统中——也就是BookKeeper。当然BookKeeper除了适于上述场景,其它任何单点写入并要求保证高性能和数据不丢失(Strong Durabilty Guarantees)也都可以使用。
BookKeeper中的一些术语:
BookKeeper最初就做了分布式容错考虑,每一个Ledger Entry都会复制到多个Bookie中,所以系统中的个别Bookie挂掉不会影响其中存储的记录。与好多其它的分布式系统类似,BookKeeper的元信息也是存储到ZooKeeper中。
BookKeeper也有一些操作上的限制:1)Ledger只能按照追加的方式写入(Append Only)。2)一个Ledger只有能有一个写操作者。提供的操作接口如下:
通过上边的介绍可以看出BookKeeper实际上是一个消息队列系统(Pub/Sub System),所以BookKeeper依赖于另一个子项目:Hedwig。Hedwig是一个相对更通用一些的Pub/Sub系统。那么为什么既然已经存在好多类似的Pub/Sub系统了,还要重写一个呢?主要原因是作为Bookeeper的子系统,对这个消息队列有着更为苛刻的要求,主要有以下几个方面:
看到上边这四条特性,顿时觉得似曾相识:P 按作者的说法目前没有任何一个开源的实现能同时达到上述四种特性。Hedwig的结构大致是这样子的:
Hedwig中存在多个逻辑上的Region,这些Region可以分布在整个Internet上。每个Region都是由一系列Hub Server组成,这些Hub Servers才是真正负责存储消息并接受发布和订阅的实体。这里有个限制,就是客户端只能连接本地Region中的hub server。所以如果客户端要订阅别的Region中的Topic,就必须有本地Hub Server做一次中转才行。也就是先让本地Hub Server去订阅一个远程Region中的Topic,然后在转交这个Client。Hedwig的元信息同样使用ZooKeeper存储,整个系统一共包含六个模块:
网络I/O模块:使用一个基于Java NIO的网络库Netty提供高性能的网络吞吐
Topic管理模块:管理Topic的所属关系,能够自动进行failover
订阅管理模块:记录当前系统中存在的每个订阅者的信息,包括每个订阅者订阅消息点
持久化管理模块:将消息持久化并提供个后续的订阅
远程订阅者管理模块:将远程Region中的主题中转到本地Hub Server,并交由本地Client
投递管理模块:负责将消息投递到订阅者
BookKeeper和Hedwig项目都还在进行中,目前只完成了部分代码,更多内容可以参考下边链接。
http://zookeeper.apache.org/bookkeeper/
https://cwiki.apache.org/confluence/display/BOOKKEEPER/HedWig
https://cwiki.apache.org/confluence/download/attachments/27832576/bookkeeper-hic-2011.pdf?version=1&modificationDate;=1322809384000