我们在2016年五月开源了 DistributedLog 项目,引起了社区的广泛关注。大家常常问起的问题之一就是DistributedLog与 Apache Kafka 相对比,各有什么优劣。从技术上来讲DistributedLog并不是一个象Apache Kafka那么成熟的、有分区机制的广播/订阅系统。DistributedLog是一个复制日志流仓库,它用 Apache BookKeeper 来做日志分区仓库。它关注的是构建可靠的实时系统所需要的持久性、副本和强一致性。可以把DistributedLog用于构建或尝试各种不同的消息通信模型,比如队列、广播/订阅等。
因为两者都是处理日志,数据模型也类似,所以这篇文章主要从技术角度讨论Apache Kafka与DistributedLog的不同点。我们会尽量做到客观,但由于我们不是Apache Kafka的专家,因此我们可能会对Apache Kafka存在误解。如果发现有错,也请大家直接指出。
首先,让我们简单地介绍一下Kafka和DistributedLog的概况。
Kafka是什么?
Kafka是最初由Linkedin开源出来的一套分布式消息系统,现在由 Apache软件基金会 管理。这是一套基于分区的发布/订阅系统。Kafka中的关键概念就是Topic。一个Topic下面会有多个分区,每个分区都有备份,分布在不同的代理服务器上。生产者会把数据记录发布到一个Topic下面的分区中,具体方式是轮询或者基于主键做分区,而消费者会处理Topic中发布出来的数据记录。所有数据都是发布给相应分区的主代理进程,再复制到从代理进程,所有的读数据请求也都是依次由主代理处理的。从代理仅仅用于数据的冗余备份,并在主代理无法继续提供服务时顶上。图一的左边部分显示了Kafka中的数据流。
DistributedLog是什么?
与Kafka不同,DistributedLog并不是一个基于分区的发布/订阅系统,它是一个复制日志流仓库。DistributedLog中的关键概念是持续的复制日志流。一个日志流会被分段成多个日志片段。每个日志片段都在Apache BookKeeper中存储成Apache BooKeeper中的一个 账目 ,其中的数据会在多个Bookie(Bookie就是Apache BookKeeper的存储节点)之间复制和均衡分布。一个日志流的所有数据记录都由日志流的属主排序,由许多个写入代理来管理日志流的属主关系。应用程序也可以使用核心库来 直接追加日志记录。这对于复制状态机一类对于顺序和排他写有着非常高要求的场景非常有用。每个追加到日志流末尾的日志记录都会被赋予一个序列号。读者可以从任何指定的序列号开始读日志流的数据。读请求也会在那个流的所有存储副本上做负载均衡。图一的右半部分显示了DistributedLog中的数据流。
图一:Apache Kafka与Apache DistributedLog
Kafka与DistributedLog有什么不同?
因为同类事物才有可比较的基础,所以我们只在本文中把Kafka分区和DistributedLog流相对比。下表列出了两套系统之间最显著的不同点。
(点击放大图像)
数据模型
Kafka分区是存储在代理服务器磁盘上的以若干个文件形式存在的日志。每条记录都是一个键-值对,但对于轮询式的数据发布可以省略数据的主键。主键用于决定该条记录会被存储到哪个分区上以及用于 日志压缩 功能。一个分区的所有数据只存储在若干个代理服务器上,并从主代理服务器复制到从代理服务器。
DistributedLog流是以一系列日志分片的形式存在的虚拟流。每个日志分片都以一条BookKeeper账目的形式存在,并被复制到多个Bookie上。在任意时刻都只有一个活跃的日志分片接受写入请求。在特定的时间段过后,或者旧日志分片达到配置大小(由配置的日志分片策略决定)之后,或者日志的属主出故障之后,旧的日志分片会被封存,一个新的日志分片会被开启。
Kafka分区和DistributedLog流在数据分片和分布的不同点决定了它们在数据持久化策略和集群操作(比如集群扩展)上的不同。
图二显示了DistributedLog和Kafka数据模型的不同点
(点击放大图像)
图二:Kafka分区与DistributedLog流