前一篇文章《RabbitMQ和Kafka到底怎麼選?》,咱們在吞吐量方面比較了Kafka和RabbitMQ,知道了Kafka的吞吐量要高於RabbitMQ。本文從可靠性方面繼續探討兩個隊列的差別。html
咱們經過前文知道,RabbitMQ的隊列分爲master queue和mirror queue,mirror queue 在master queue宕機以後,會被提高爲master queue,以下圖所示。 隊列A的consumer在消費的時候,機器宕機,此時客戶端和服務端分別作以下動做:安全
當master queue 所在節點宕機後,其正在被消費的消息的相關信息所有丟失,即服務端不知道消費者對那一瞬間消費的消息是否進行了ACK,因此在mirror queue被提高爲master queue時,會把宕機前正在進行消費的的消息所有從新發送一遍,即客戶端重連後,消息可能被重複消費,這個時候就必須依靠應用層邏輯來判斷來避免重複消費。分佈式
在持久化方面,RabbitMQ的master queue每次收到新消息後,都會馬上寫入磁盤,並把消息同步給mirror queue。假設在master queue 收到消息後,消息未同步到mirror queue 以前master queue 宕機,則此時mirror queue中就沒有剛剛master queue收到的那條消息,當這個mirror queue被提高爲master queue時,消費者鏈接到新的master queue上進行消費時就丟了一條消息。因此,RabbitMQ也會丟消息,只不過這個丟消息的機率很是低。性能
咱們知道Kafka中的每一個隊列叫作Topic,一個Topic有多個主分片和副分片,當主分片所在機器宕機後,服務端會把一個副分片提高爲主分片,以下圖所示。 spa
服務端和客戶端會有以下動做:操作系統
Kafka一樣有主從同步,因此也一定存在與RabbitMQ一樣丟消息的問題。可是Kafka的每一個客戶端保存了讀取消息的偏移信息,故當一個主分片宕機後,Kafka客戶端能夠從副分片相應位移後繼續消費,不會有重複消費的狀況。日誌
持久化方面,Kafka默認把消息直接寫文件,可是因爲操做系統的cache緣由,消息可能不會立馬寫到磁盤上,這個時候就須要刷新文件到磁盤。因爲刷新文件到磁盤是一個比較耗時的操做,故Kafka提供了兩種不一樣的刷新配置:code
#每接收多少條消息刷一下磁盤 log.flush.interval.messages=10000 #每隔多少ms刷一下磁盤 log.flush.interval.ms=1000
咱們徹底能夠把log.flush.interval.messages設置爲1,這樣Kafka就能在持久化方面達到和RabbitMQ一樣的安全級別。htm
可是Kafka集羣依賴ZK,如上圖所示,因此對於Kafka穩定性的評估必須考慮ZK集羣的穩定性,而通常咱們認爲任何分佈式集羣的穩定性都小於1,故兩個集羣的串聯穩定性會降低一些,維護更復雜一些,這點沒有RabbitMQ有優點。blog
其實好多開源組件隨着時間推移,每每都進行了各類改進。就好比Kafka雖然是爲了日誌而生,給人第一印象是容易丟消息,可是通過這麼多年的改進,其可靠性可能並不遜色RabbitMQ了,只須要你根據不一樣的業務場景配置不一樣的配置參數,便可達到適合本身的安全級別。
好了,以上就是個人我的分析,多有不足,但願能和小夥伴進行探討。