我們?cè)?016年五月開源了 DistributedLog 項(xiàng)目,引起了社區(qū)的廣泛關(guān)注。大家常常問起的問題之一就是DistributedLog與 Apache Kafka 相對(duì)比,各有什么優(yōu)劣。從技術(shù)上來講DistributedLog并不是一個(gè)象Apache Kafka那么成熟的、有分區(qū)機(jī)制的廣播/訂閱系統(tǒng)。DistributedLog是一個(gè)復(fù)制日志流倉庫,它用 Apache BookKeeper 來做日志分區(qū)倉庫。它關(guān)注的是構(gòu)建可靠的實(shí)時(shí)系統(tǒng)所需要的持久性、副本和強(qiáng)一致性??梢园袲istributedLog用于構(gòu)建或嘗試各種不同的消息通信模型,比如隊(duì)列、廣播/訂閱等。
因?yàn)閮烧叨际翘幚砣罩?,?shù)據(jù)模型也類似,所以這篇文章主要從技術(shù)角度討論Apache Kafka與DistributedLog的不同點(diǎn)。我們會(huì)盡量做到客觀,但由于我們不是Apache Kafka的專家,因此我們可能會(huì)對(duì)Apache Kafka存在誤解。如果發(fā)現(xiàn)有錯(cuò),也請(qǐng)大家直接指出。
首先,讓我們簡單地介紹一下Kafka和DistributedLog的概況。
Kafka是什么?
Kafka是最初由Linkedin開源出來的一套分布式消息系統(tǒng),現(xiàn)在由 Apache軟件基金會(huì) 管理。這是一套基于分區(qū)的發(fā)布/訂閱系統(tǒng)。Kafka中的關(guān)鍵概念就是Topic。一個(gè)Topic下面會(huì)有多個(gè)分區(qū),每個(gè)分區(qū)都有備份,分布在不同的代理服務(wù)器上。生產(chǎn)者會(huì)把數(shù)據(jù)記錄發(fā)布到一個(gè)Topic下面的分區(qū)中,具體方式是輪詢或者基于主鍵做分區(qū),而消費(fèi)者會(huì)處理Topic中發(fā)布出來的數(shù)據(jù)記錄。所有數(shù)據(jù)都是發(fā)布給相應(yīng)分區(qū)的主代理進(jìn)程,再復(fù)制到從代理進(jìn)程,所有的讀數(shù)據(jù)請(qǐng)求也都是依次由主代理處理的。從代理僅僅用于數(shù)據(jù)的冗余備份,并在主代理無法繼續(xù)提供服務(wù)時(shí)頂上。圖一的左邊部分顯示了Kafka中的數(shù)據(jù)流。
DistributedLog是什么?
與Kafka不同,DistributedLog并不是一個(gè)基于分區(qū)的發(fā)布/訂閱系統(tǒng),它是一個(gè)復(fù)制日志流倉庫。DistributedLog中的關(guān)鍵概念是持續(xù)的復(fù)制日志流。一個(gè)日志流會(huì)被分段成多個(gè)日志片段。每個(gè)日志片段都在Apache BookKeeper中存儲(chǔ)成Apache BooKeeper中的一個(gè) 賬目 ,其中的數(shù)據(jù)會(huì)在多個(gè)Bookie(Bookie就是Apache BookKeeper的存儲(chǔ)節(jié)點(diǎn))之間復(fù)制和均衡分布。一個(gè)日志流的所有數(shù)據(jù)記錄都由日志流的屬主排序,由許多個(gè)寫入代理來管理日志流的屬主關(guān)系。應(yīng)用程序也可以使用核心庫來 直接追加日志記錄。這對(duì)于復(fù)制狀態(tài)機(jī)一類對(duì)于順序和排他寫有著非常高要求的場景非常有用。每個(gè)追加到日志流末尾的日志記錄都會(huì)被賦予一個(gè)序列號(hào)。讀者可以從任何指定的序列號(hào)開始讀日志流的數(shù)據(jù)。讀請(qǐng)求也會(huì)在那個(gè)流的所有存儲(chǔ)副本上做負(fù)載均衡。圖一的右半部分顯示了DistributedLog中的數(shù)據(jù)流。

圖一:Apache Kafka與Apache DistributedLog
Kafka與DistributedLog有什么不同?
因?yàn)橥愂挛锊庞锌杀容^的基礎(chǔ),所以我們只在本文中把Kafka分區(qū)和DistributedLog流相對(duì)比。下表列出了兩套系統(tǒng)之間最顯著的不同點(diǎn)。
(點(diǎn)擊放大圖像)

數(shù)據(jù)模型
Kafka分區(qū)是存儲(chǔ)在代理服務(wù)器磁盤上的以若干個(gè)文件形式存在的日志。每條記錄都是一個(gè)鍵-值對(duì),但對(duì)于輪詢式的數(shù)據(jù)發(fā)布可以省略數(shù)據(jù)的主鍵。主鍵用于決定該條記錄會(huì)被存儲(chǔ)到哪個(gè)分區(qū)上以及用于 日志壓縮 功能。一個(gè)分區(qū)的所有數(shù)據(jù)只存儲(chǔ)在若干個(gè)代理服務(wù)器上,并從主代理服務(wù)器復(fù)制到從代理服務(wù)器。
DistributedLog流是以一系列日志分片的形式存在的虛擬流。每個(gè)日志分片都以一條BookKeeper賬目的形式存在,并被復(fù)制到多個(gè)Bookie上。在任意時(shí)刻都只有一個(gè)活躍的日志分片接受寫入請(qǐng)求。在特定的時(shí)間段過后,或者舊日志分片達(dá)到配置大小(由配置的日志分片策略決定)之后,或者日志的屬主出故障之后,舊的日志分片會(huì)被封存,一個(gè)新的日志分片會(huì)被開啟。
Kafka分區(qū)和DistributedLog流在數(shù)據(jù)分片和分布的不同點(diǎn)決定了它們?cè)跀?shù)據(jù)持久化策略和集群操作(比如集群擴(kuò)展)上的不同。
圖二顯示了DistributedLog和Kafka數(shù)據(jù)模型的不同點(diǎn)
(點(diǎn)擊放大圖像)

圖二:Kafka分區(qū)與DistributedLog流