您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關怎么實現Kafka和Twitter新開源的DistributedLog技術對比,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
我們簡單地介紹一下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中的數據流。
Kafka與DistributedLog有什么不同?
因為同類事物才有可比較的基礎,所以我們只在本文中把Kafka分區和DistributedLog流相對比。下表列出了兩套系統之間最顯著的不同點。
數據模型
Kafka分區是存儲在代理服務器磁盤上的以若干個文件形式存在的日志。每條記錄都是一個鍵-值對,但對于輪詢式的數據發布可以省略數據的主鍵。主鍵用于決定該條記錄會被存儲到哪個分區上以及用于日志壓縮功能。一個分區的所有數據只存儲在若干個代理服務器上,并從主代理服務器復制到從代理服務器。
DistributedLog流是以一系列日志分片的形式存在的虛擬流。每個日志分片都以一條BookKeeper賬目的形式存在,并被復制到多個Bookie上。在任意時刻都只有一個活躍的日志分片接受寫入請求。在特定的時間段過后,或者舊日志分片達到配置大小(由配置的日志分片策略決定)之后,或者日志的屬主出故障之后,舊的日志分片會被封存,一個新的日志分片會被開啟。
Kafka分區和DistributedLog流在數據分片和分布的不同點決定了它們在數據持久化策略和集群操作(比如集群擴展)上的不同。
圖二顯示了DistributedLog和Kafka數據模型的不同點
數據持久化
一個Kafka分區中的所有數據都保存在一個代理服務器上(并被復制到別的代理服務器上)。在配置的有效期過后數據會失效并被刪除。另外,也可以配置策略讓Kafka的分區保留每個主鍵的***值。
與Kafka相似,DistributedLog也可以為每個流配置有效期,并在超時之后將相應的日志分片失效或刪除。除此之外,DistributedLog還提供了顯示的截斷機制。應用程序可以顯式地將一個日志流截斷到流的某個指定位置。這對于構建可復制的狀態機非常有用,因為可復制的狀態機需要在刪除日志記錄之前先將狀態持久化。Manhattan就是一個用到了這個功能的典型系統。
操作
數據分片和分布機制的不同也導致了維護集群操作上的不同,擴展集群操作就是一個例子。
擴展Kafka集群時,通常現有分區都要做重新分布。重新分布操作會將Kafka分區挪動到不同的副本上,以此達到均衡分布。這就要把整個流的數據從一個副本拷到另一個副本上。我們也說過很多次了,執行重新分布操作時必須非常小心,避免耗盡磁盤和網絡資源。
而擴展DistributedLog集群的工作方式則截然不同。DistributedLog包含兩層:存儲層(Apache BooKeeper)和服務層(寫入和讀出代理)。在擴展存儲層時,我們只需要添加更多的Bookie就好了。新的Bookie馬上會被寫入代理發現,并立刻用于寫入新的日志分片。在擴展數據存儲層時不會有任何的重新分布操作。只在增加服務層時會有重新分布操作,但這個重新分布也只是移動日志流的屬主權,以使網絡代寬可以在各個代理之間均衡分布。這個重新分布的過程只與屬主權相關,沒有數據遷移操作。這種存儲層和服務層的隔離不僅僅是讓系統具備了自動擴展的機制,更讓各種不同類型的資源可以獨立擴展。
寫與生產者
如圖一所示,Kafka生產者把數據一批批地寫到Kafka分區的主代理服務器上。而ISR(同步復制)集合中的從代理服務器會從主代理上把記錄復制走。只有在主代理從所有的ISR集合中的副本上都收到了成功的響應之后,一條記錄才會被認為是成功寫入的。可以配置讓生產者只等待主代理的響應,還是等待ISR集合中的所有代理的響應。
DistributedLog中則有兩種方式把數據寫入DistributedLog流,一是用一個Thrift的瘦客戶端通過寫代理(眾所周知的多寫入)寫入,二是通過DistributedLog的核心庫來直接與存儲節點交互(眾所周知的單獨寫入)。***種方式很適合于構建消息系統,第二種則適用于構建復制狀態機。你可以查閱DistributedLog文檔的相關章節來獲取更多的信息和參考,以找到你需要的方式。
日志流的屬主會并發地以BookKeeper條目的形式向Bookie中寫入一批記錄,并等待多個Bookie的Quorum結果。Quorum的大小取決于BookKeeper賬目的ack_quorum_size參數,并且可以配置到DistributedLog流的級別。它提供了和Kafka生產者相似的在持久性上的靈活性。在接下來的“復制”一節我們會對比兩者在復制算法上的更多不同之處。
Kafka和DistributedLog都支持端到端的批量操作和壓縮機制。但兩者之間的一點微妙區別是對DistributedLog的寫入操作都是在收到響應之前都先通過fsync刷到硬盤上的,而我們并沒發現Kafka也提供了類似的可靠性保證。
讀與消費者
Kafka消費者從主代理服務器上讀出數據記錄。這個設計的前提就是主代理上在大多數情況下***的數據都還在文件系統頁緩存中。從充分利用文件系統頁緩存和獲得高性能的角度來說這是一個好辦法。
DistributedLog則采用了完全不同的方法。因為各個存儲節點之間沒有明確的主從關系,DistributedLog可以從任意存儲著相關數據的存儲節點上讀出數據。為了獲得可預期的低延遲,DistributedLog引入了一個推理式讀機制,即在超出了配置的讀操作時限之后,它會在不同的副本上再次嘗試獲取數據。
這就可能會對存儲節點導致比Kafka更高的讀壓力。不過,如果將讀超時時間配成可以讓99%的存儲節點的讀操作都不會超時,那就可以極大程度地解決延遲問題,只帶來1%的額外讀壓力。
對于讀的考慮和機制上的不同主要源于復制機制和存儲節點的I/O系統的不同,在下文會繼續討論。
復制
Kafka用的是ISR復制算法:將一個代理服務器選為主。所有寫操作都被發送到主代理上,所有處于ISR集合中的從代理都從主代理上讀取和復制數據。主代理會維護一個高水位線(HW,High Watermark),即每個分區***提交的數據記錄的偏移量。高水位線會不斷同步到從代理上,并周期性地在所有代理上記錄檢查點,以備恢復之用。在所有ISR集合中的副本都把數據寫入了文件系統(并不必須是磁盤)并向主代理發回了響應之后,主代理才會更新高水位線。
ISR機制讓我們可以增加或減少副本的數量,在可用性和性能之間做出權衡。可是擴大或縮小副本的集合的副作用是增大了丟失數據的可能性。
DistributedLog使用的是Quorum投票復制算法,這在Zab、Raft以及Viewstamped Replication等一致性算法中都很常見。日志流的屬主會并發地把數據記錄寫入所有存儲節點,并在得到超過配置數量的存儲節點投票確認之后,才認為數據已成功提交。存儲節點也只在數據被顯式地調用flush操作刷入磁盤之后才會響應寫入請求。
日志流的屬主也會維護一個日志流的***提交的數據記錄的偏移量,就是大家知道的Apache BookKeeper中的LAC(LastAddConfirmed)。LAC也會保存在數據記錄中(來節省額外的RPC調用開銷),并不斷復制到別的存儲節點上。DistributedLog中復本集合的大小是在每個流的每個日志分片級別可配置的。改變復制參數只會影響新的日志分片,不會影響已有的。
存儲
每個Kafka分區都以若干個文件的形式保存在代理的磁盤上。它利用文件系統的頁緩存和I/O調度機制來得到高性能。Kafka也是因此利用Java的sendfile API來高效地從代理中寫入讀出數據的。不過,在某些情況下(比如消費者處理不及時、隨機讀寫等),頁緩存中的數據淘汰很頻繁,它的性能也有很大的不確性性。
DistributedLog用的則是不同的I/O模型。圖三表示了Bookie(BookKeeper的存儲節點)的I/O機制。寫入(藍線)、末尾讀(紅線)和中間讀(紫線)這三種常見的I/O操作都被隔離到了三種物理上不同的I/O子系統中。所有寫入都被順序地追加到磁盤上的日志文件,再批量提交到硬盤上。在寫操作持久化到磁盤上之后,它們就會放到一個Memtable中,再向客戶端發回響應。
Memtable中的數據會被異步刷新到交叉存取的索引數據結構中:記錄被追加到日志文件中,偏移量則在分類賬目的索引文件中根據記錄ID索引起來。***的數據肯定在Memtable中,供末尾讀操作使用。中間讀會從記錄日志文件中獲取數據。由于物理隔離的存在,Bookie節點可以充分利用網絡流入帶寬和磁盤的順序寫入特性來滿足寫請求,以及利用網絡流出代寬和多個磁盤共同提供的IOPS處理能力來滿足讀請求,彼此之間不會相互干擾。
以上就是怎么實現Kafka和Twitter新開源的DistributedLog技術對比,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。