關於Kafka
根據Kafka官方的文檔,Kafka可以被認為一個高大上的集群消息中間件,但是讀了下以前一個朋友給的部署文檔和Kafka的官方的文檔。發現Kafka確實不錯,真的可以說是集群消息中間件。
-
用topic來進行消息管理,每個topic包含多個part,每個part對應一個邏輯log,有多個segment組成。
-
segment中的消息id由其邏輯位置決定,可以用消息id直接定位到消息的存儲位置,避免id到位置的額外映射。
-
生產者發到某個topic的消息會被均勻的分布到多個part上,broker收到消息會寫入最后的segment文件中,當某個segment上的消息條數達到配置值或消息發布時間超過閾值時,segment上的消息會被flush到磁盤,只有flush到磁盤上的消息消費者才能收到。並且通過rolling的機制,保證segment的文件不至於過大。
-
消費者可以rewind back到任意位置重新進行消費,當消費者故障時,可以選擇最小的offset進行重新讀取消費消息。
是不是看起來很爽,但是深入往下看,發現了一些深坑
-
Kafka對消息的重復、丟失、錯誤以及順序型沒有嚴格的要求。但是part只會被consumer group內的一個consumer消費,故kafka保證每個parti內的消息會被順序的消費。
-
broker沒有副本機制,一旦broker宕機,該broker的消息將都不可用。同時broker是無狀態的,broker不保存消費者的狀態,由消費者自己保存。無狀態導也致消息的刪除成為難題,所以Kafka選擇消息保存一定時間后會被刪除。
-
大量的依賴Zookeeper,需要Zookeeper來管理broker與consumer的動態加入與離開。以及消費關系及每個partion的消費信息。
看到這里,你如果還明白我說這些深坑是什么意思,那就請帶入運維場景和特定故障場景思考下。我稍后會說一下這些坑會帶來什么問題。
關於RabbitMQ
RabbitMQ是使用Erlang開發的一個消息隊列,可以構建成集群,也可以單獨使用。
根據測試,RabbitMQ在不使用ACK機制的,Msg大小為1K的情況下,QPS可達6W+。再雙方ACK機制,Msg大小為1K的情況下,QPS瞬間降到了1W+。從某種意義上RabbitMQ還真是慢,但是我們需要思考下。
-
我們真的每個消息都能到1K嗎?
-
我們真的需要雙方都對消息ACK的系統嗎?
好了,如果兩個回答都是YES,那么RabbitMQ就是慢的。如果是No,那么RabbitMQ還是一個非常快的隊列。
RabbitMQ慢有幾個原因:
-
RabbitMQ做為一個Broker,不單單做到了簡單的數據轉發功能,還保證了單個隊列上的數據有序,即便是有多個消費者和多個生產者。
-
RabbitMQ的策略是實時轉發,而不像Kafka那樣等待刷盤之后才讓消費者來消費。
-
如果消費者和生產者不對等,會產生大量的磁盤IO操作,進行消息換出。
RabbitMQ為什么不好用:
-
AMQP協議本身比較復雜,參數比較多。
-
Erlang寫的,很多人不熟悉,並且Mnesia出現問題好多人解決不了。
RabbitMQ和Kafka相比沒價值了嗎?
很多親們讀到這里,就會想RabbitMQ好像也不怎么樣呀。和Kafka相比沒什么價值可言了,但是我前面說了一些Kafka的坑,我就在這里面揭示一下。
-
Kafka大量依賴Zookeeper,它的broker並不保存任何狀態,如果Zookeeper集群不幸悲劇了,那么整個Kafka集群的消息就全完蛋了。
-
上面問題有人會說這概率好小,我也同樣認為這個概率很小,那么一個broker當機呢?當一個broker當機了整個消息隊列由於負載均衡的算法,在一瞬間消費者和生產者之間的消息就全亂掉了。很多需要保證消息順序的系統一下子就完蛋了。
這就是RabbitMQ存在的價值和意義,同時RabbitMQ使用了MirrorQueue的機制,也可以做到多個機器進行熱備。
RabbitMQ該怎么用
-
RabbitMQ的消息應當盡可能的小,並且只用來處理實時且要高可靠性的消息。
-
消費者和生產者的能力盡量對等,否則消息堆積會嚴重影響RabbitMQ的性能。
-
集群部署,使用熱備,保證消息的可靠性。
Kafka該怎么用
-
應當有一個非常好的運維監控系統,不單單要監控Kafka本身,還要監控Zookeeper。
-
對消息順序不依賴,且不是那么實時的系統。
-
對消息丟失並不那么敏感的系統。
