天天看點

Twitter 開源分布式高性能日志複制服務

日前,twitter在github上基于apache 2許可證協定開源了其日志服務distributedlog(dl)。

dl是一個高性能的日志複制服務,提供了持久化、複制以及強一緻性的功能,這對于建構可靠的分布式系統都是至關重要的,如複制狀态機(replicated-state-machines)、通用的釋出/訂閱系統、分布式資料庫以及分布式隊列。

distributedlog會分類維護記錄的序列(sequences of records),并将其稱為log(又叫做log stream),将記錄寫入到dl log的程序稱之為writer,從log中讀取并處理記錄的程序稱之為reader。是以,它整體的軟體棧如下所示:

Twitter 開源分布式高性能日志複制服務

具體來講,它包含如下幾個組成部分:

log

log是有序的、不可變的日志記錄(log record),它的資料結構如下所示:

Twitter 開源分布式高性能日志複制服務

日志記錄

每條日志記錄都是一個位元組序列。日志記錄會按照序列寫入到日志流中,并且會配置設定一個名為dlsn(分布式序列号,distributedlog sequence number)的唯一序列号。除了dlsn以外,應用程式還可以在建構日志記錄的時候設定自己的序列号,應用程式所定義的序列号稱為transactionid(txid)。不管是dlsn還是transactionid都能用來定位reader,使其從特定的日志記錄開始讀取。

log分段(log segments)

log會被分解為log分段,每個分段中包含了其記錄的子集。log分段是分布式的,應該放到log分段存儲中(如bookkeeper)。distributedlog會基于配置好的政策來輪詢每個log分段,要麼是可配置的時間段(如每兩個小時),要麼是可配置的最大規模(如每128mb)。是以log的資料将會分為同等大小的log分段,并且均勻分布到log分段存儲節點上。這樣,log的存儲就不會局限于單台伺服器的限制,同時,能夠在叢集中分散讀取的流量。

log的資料可以永遠儲存,直到應用程式顯式地将其截斷,也可以在一個可配置的時間段内儲存。對于建構複制狀态機來說,顯式截斷會非常有用,如分布式資料庫。在資料何時能夠截斷這一點上,它們往往有着嚴格的控制。基于時間保留log對于實時分析的場景更為有用,它們隻關心一定時間内的資料。

命名空間

屬于同一組織的log流通常會歸類在同一個命名空間(namespace)下,并據此進行管理。dl的命名空間基本上就是用來定位log流在何處的。應用程式可以在某個命名空間下建立和删除流,也能将某個流截斷到給定的序列号上(dlsn或transactionid均可以)。

writer

writer會将資料寫入到它們所選擇的log中。所有的記錄都會按照順序添加到log之中。序列号是由writer所負責的,這就意味着對于某個log,在給定的時間點上,隻能有一個激活的writer。當出現網絡分區(network partition),導緻兩個writer試圖往同一個log進行寫入的時候,dl會保證其正确性,這是通過log分段存儲的屏障(fencing)來實作的。

writer由名為write proxy的服務層來提供和管理,write proxy用來接受大量用戶端的fan-in寫入。

reader

reader會從它們所選擇的log中讀取記錄,這會在一個給定的位置開始。這個給定的位置可以是dlsn,也可以是transactionid。reader将會嚴格按照log的順序讀取記錄。在同一個log中,不同的reader可以在不同的起始位置讀取記錄。

與其他的訂閱/釋出系統不同,distributedlog并不會記錄/管理reader的位置,它将跟蹤的任務留給了應用程式本身,因為不同的應用在跟蹤和協調位置上可能會有不同的需求,很難用一種方式就将這些需求全部解決。在應用程式層面,借助各種存儲(如zookeeper、filesystem或key/value存儲)能夠很容易地跟蹤reader的位置。

log記錄可以緩存在名為read proxy的服務層中,進而應對大量reader的讀取。

fan-in與fan-out

distributedlog的核心支援單writer、多reader的語義。服務層建構在distributedlog core之上,支援大量的writer和reader。服務層包含write proxy和read proxy,write proxy管理log的writer,并且在機器當機時,能夠對它們進行故障恢複。它能夠從衆多來源聚集writer,允許不必關心log的所有權(又稱為fan-in)。read proxy通過将記錄放到緩存中,優化了reader的讀取路徑,以應對成百上千的reader讀取同一個log流的狀況。

作為一個日志服務,distributedlog的優勢可以總結為:

高性能:面對大量的并發日志時,在可持久化的writer上dl能夠提供毫秒級的延遲,同時還能應對上千用戶端每秒大量的讀取和寫入操作。

持久化和一緻性:消息會持久化到磁盤上,并且以副本的形式存儲多份,進而避免丢失。通過嚴格的順序,保證writer和reader之間的一緻性。

各種工作負載:dl支援各種負載,包括延遲敏感的線上事務處理(oltp)應用(如分布式資料庫的wal和基于記憶體的複制狀态機)、實時的流提取和計算以及分析處理。

多租戶:針對實際的工作負載,dl的設計是i/o隔離的,進而支援多租戶的大規模日志。

分層架構:dl有一個現代化的分層設計,它将有狀态的存儲層與無狀态的服務提供層進行了分離,能夠使存儲的擴充獨立于cpu和記憶體,是以支援大規模的寫入fan-in和讀取fan-out。