Kafka 对比 ActiveMQ
Kafka 將消息流按Topic 組織,保存消息的服務器稱為Broker,消費者可以訂閱一個或者多個Topic。為了均衡負載,一個Topic 的消息又可以劃分到多個分區(qū)(Partition),分區(qū)越多,Kafka并行能力和吞吐量越高。
Kafka 集群需要zookeeper 支持來實現(xiàn)集群,最新的kafka 發(fā)行包中已經(jīng)包含了zookeeper,部署的時候可以在一臺服務器上同時啟動一個zookeeper Server 和 一個Kafka Server,也可以使用已有的其他zookeeper集群。
和傳統(tǒng)的MQ不同,消費者需要自己保留一個offset,從kafka 獲取消息時,只拉去當前offset 以后的消息。Kafka 的scala/java 版的client 已經(jīng)實現(xiàn)了這部分的邏輯,將offset 保存到zookeeper 上。每個消費者可以選擇一個id,同樣id 的消費者對于同一條消息只會收到一次。一個Topic 的消費者如果都使用相同的id,就是傳統(tǒng)的 Queue;如果每個消費者都使用不同的id, 就是傳統(tǒng)的pub-sub.
如果在MQ的場景下,將Kafka 和 ActiveMQ 相比:Kafka 的優(yōu)點
分布式可高可擴展。Kafka 集群可以透明的擴展,增加新的服務器進集群。 高性能。Kafka 的性能大大超過傳統(tǒng)的ActiveMQ、RabbitMQ等MQ 實現(xiàn),尤其是Kafka 還支持batch 操作。下圖是linkedin 的消費者性能壓測結果: 容錯。Kafka每個Partition的數(shù)據(jù)都會復制到幾臺服務器上。當某個Broker故障失效時,ZooKeeper服務將通知生產(chǎn)者和消費者,生產(chǎn)者和消費者轉(zhuǎn)而使用其它Broker。Kafka 的不利
重復消息。Kafka 只保證每個消息至少會送達一次,雖然幾率很小,但一條消息有可能會被送達多次。?
消息亂序。雖然一個Partition 內(nèi)部的消息是保證有序的,但是如果一個Topic 有多個Partition,Partition 之間的消息送達不保證有序。?
復雜性。Kafka需要zookeeper 集群的支持,Topic通常需要人工來創(chuàng)建,部署和維護較一般消息隊列成本更高
=-=======================================================================
00
今天讓我們來談談身份高貴,舉止優(yōu)雅的消息中間件,主要還是淺談,消息中間件這塊水太深。大體上我們結合互聯(lián)網(wǎng)業(yè)務做一些探討,從互聯(lián)網(wǎng)主要關心的消息安全性,服務器的穩(wěn)定性容錯性以及吞吐量三方面來講。
由于這塊產(chǎn)品非常多,我只挑選兩個我使用過的產(chǎn)品結合使用經(jīng)驗做一些研究,他們是ActiveMQ和Kafka,前者完全實現(xiàn)了JMS的規(guī)范,后者看上去有一些“野路子”,并沒有糾結于JMS規(guī)范,劍走偏鋒的設計了另一套吞吐非常高的分布式發(fā)布-訂閱消息系統(tǒng),目前非常流行。接下來我們結合三個點(消息安全性,服務器的穩(wěn)定性容錯性以及吞吐量)來分別談談這兩個消息中間件。今天我們談Kafka,ActiveMQ的文章在此。
01 性能怪獸Kafka
Kafka是LinkedIn開源的分布式發(fā)布-訂閱消息系統(tǒng),目前歸屬于Apache定級項目?!盇pache Kafka is publish-subscribe messaging rethought as a distributed commit log.”,官網(wǎng)首頁的一句話高度概括其職責。Kafka并沒有遵守JMS規(guī)范,他只用文件系統(tǒng)來管理消息的生命周期。Kafka的設計目標是:
(1)以時間復雜度為O(1)的方式提供消息持久化能力,即使對TB級以上數(shù)據(jù)也能保證常數(shù)時間復雜度的訪問性能。
(2)高吞吐率。即使在非常廉價的商用機器上也能做到單機支持每秒100K條以上消息的傳輸。
(3)支持Kafka Server間的消息分區(qū),及分布式消費,同時保證每個Partition內(nèi)的消息順序傳輸。
(4)同時支持離線數(shù)據(jù)處理和實時數(shù)據(jù)處理。
(5)Scale out:支持在線水平擴展。
所以,不像AMQ,Kafka從設計開始極為高可用為目的,天然HA。broker支持集群,消息亦支持負載均衡,還有副本機制。同樣,Kafka也是使用Zookeeper管理集群節(jié)點信息,包括consumer的消費信息也是保存在zk中,下面我們分話題來談:
1)消息的安全性
Kafka集群中的Leader負責某一topic的某一partition的消息的讀寫,理論上consumer和producer只與該Leader節(jié)點打交道,一個集群里的某一broker即是Leader的同時也可以擔當某一partition的follower,即Replica。Kafka分配Replica的算法如下:
(1)將所有Broker(假設共n個Broker)和待分配的Partition排序
(2)將第i個Partition分配到第(i mod n)個Broker上
(3)將第i個Partition的第j個Replica分配到第((i + j) mode n)個Broker上
同時,Kafka與Replica既非同步也不是嚴格意義上的異步。一個典型的Kafka發(fā)送-消費消息的過程如下:首先首先Producer消息發(fā)送給某Topic的某Partition的Leader,Leader先是將消息寫入本地Log,同時follower(如果落后過多將會被踢出出Replica列表)從Leader上pull消息,并且在未寫入log的同時即向Leader發(fā)送ACK的反饋,所以對于某一條已經(jīng)算作commit的消息來講,在某一時刻,其存在于Leader的log中,以及Replica的內(nèi)存中。這可以算作一個危險的情況(聽起來嚇人),因為如果此時集群掛了這條消息就算丟失了,但結合producer的屬性(request.required.acks=2 當所有follower都收到消息后返回ack)可以保證在絕大多數(shù)情況下消息的安全性。當消息算作commit的時候才會暴露給consumer,并保證at-least-once的投遞原則。
2)服務的穩(wěn)定容錯性
前面提到過,Kafka天然支持HA,整個leader/follower機制通過zookeeper調(diào)度,它在所有broker中選出一個controller,所有Partition的Leader選舉都由controller決定,同時controller也負責增刪Topic以及Replica的重新分配。如果Leader掛了,集群將在ISR(in-sync replicas)中選出新的Leader,選舉基本原則是:新的Leader必須擁有原來的Leader commit過的所有消息。假如所有的follower都掛了,Kafka會選擇第一個“活”過來的Replica(不一定是ISR中的)作為Leader,因為如果此時等待ISR中的Replica是有風險的,假如所有的ISR都無法“活”,那此partition將會變成不可用。
3) 吞吐量
Leader節(jié)點負責某一topic(可以分成多個partition)的某一partition的消息的讀寫,任何發(fā)布到此partition的消息都會被直接追加到log文件的尾部,因為每條消息都被append到該partition中,是順序?qū)懘疟P,因此效率非常高(經(jīng)驗證,順序?qū)懘疟P效率比隨機寫內(nèi)存還要高,這是Kafka高吞吐率的一個很重要的保證),同時通過合理的partition,消息可以均勻的分布在不同的partition里面。Kafka基于時間或者partition的大小來刪除消息,同時broker是無狀態(tài)的,consumer的消費狀態(tài)(offset)是由consumer自己控制的(每一個consumer實例只會消費某一個或多個特定partition的數(shù)據(jù),而某個partition的數(shù)據(jù)只會被某一個特定的consumer實例所消費),也不需要broker通過鎖機制去控制消息的消費,所以吞吐量驚人,這也是Kafka吸引人的地方。
最后說下由于zookeeper引起的腦裂(Split Brain)問題:每個consumer分別單獨通過Zookeeper判斷哪些partition down了,那么不同consumer從Zookeeper“看”到的view就可能不一樣,這就會造成錯誤的reblance嘗試。而且有可能所有的consumer都認為rebalance已經(jīng)完成了,但實際上可能并非如此。
總結
以上是生活随笔為你收集整理的Kafka 对比 ActiveMQ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kafka设计解析(五): Kafka
- 下一篇: 漫游Kafka入门篇之简单介绍