kafka是一種高吞吐量的分佈式發佈訂閱消息系統。和rabbitMq各佔半臂江山
java
消息隊列中間件(簡稱消息中間件)是指利用高效可靠的消息傳遞機制進行與平臺無關的數據交流,並基於數據通訊來進行分佈式系統的集成。經過提供消息傳遞和消息排隊模型,它能夠在分佈式環境下提供應用解耦、彈性伸縮、冗餘存儲、流量削峯、異步通訊、數據同步等等功能
mysql
RabbitMQ 是採用 Erlang 語言實現的 AMQP 協議的消息中間件,最初起源於金融系統,用於在分佈式系統中存儲轉發消息。RabbitMQ 發展到今天,被愈來愈多的人承認,這和它在可靠性、可用性、擴展性、功能豐富等方面的卓越表現是分不開的。
linux
Kafka 起初是由 LinkedIn 公司採用 Scala 語言開發的一個分佈式、多分區、多副本且基於 zookeeper 協調的分佈式消息系統,現已捐獻給 Apache 基金會。它是一種高吞吐量的分佈式發佈訂閱消息系統,以可水平擴展和高吞吐率而被普遍使用。目前愈來愈多的開源分佈式處理系統如 Cloudera、Apache Storm、Spark、Flink 等都支持與 Kafka 集成。
c++
1.Rabbitmq在與routing 而kafka在於streaming
2.kafka不支持延遲隊列,死信隊列 rabbitmq支持死信隊列
3.都支持持久化
4.kafka不支持多租戶,rabbitmq支持
5.廣播消費 kafka支持較好,更加正統
6.rabbitmq支持優先級隊列,優先級設置在0-10之間
7.消息堆積,kafka比rabbitmq要好不少
8.消息跟蹤 kafka不支持 rabbitmq支持 但大幅度影響性能
9.kafka消息直接寫入磁盤,而不是內存當中,kafka的log文件目錄就是kafka數據文件。
不寫入內存,消息不容易丟失。
web
rabbitMQ安裝請參考
juejin.im/post/5cce82…sql
kafka特色:
1.以時間複雜度爲 O(1) 的方式提供消息持久化能力,即便對 TB 級以上數據也能保證常數時間複雜度的訪問性能。 2.高吞吐率。即便在很是廉價的商用機器上也能作到單機支持每秒 100K 條以上消息的傳輸
數據庫
kafka設計思想
1.Consumergroup:各個consumer能夠組成一個組,每一個消息只能被組中的一個consumer消費,若是一個消息能夠被多個consumer消費的話,那麼這些consumer必須在不一樣的組。
bootstrap
2.消息狀態:在Kafka中,消息的狀態被保存在consumer中,broker不會關心哪一個消息被消費了被誰消費了,只記錄一個offset值(指向partition中下一個要被消費的消息位置),這就意味着若是consumer處理很差的話,broker上的一個消息可能會被消費屢次。
緩存
3.消息持久化:Kafka中會把消息持久化到本地文件系統中,而且保持極高的效率。
安全
4.消息有效期:Kafka會長久保留其中的消息,以便consumer能夠屢次消費,其中不少細節是可配置的。
5.批量發送:Kafka支持以消息集合爲單位進行批量發送,以提升push效率。
6.push-and-pull : Kafka中的Producer和consumer採用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管從broker pull消息,二者對消息的生產和消費是異步的。
7.Kafka集羣中broker之間的關係:不是主從關係,各個broker在集羣中地位同樣,咱們能夠隨意的增長或刪除任何一個broker節點。
8.負載均衡方面: Kafka提供了一個 metadata API來管理broker之間的負載(對Kafka0.8.x而言,對於0.7.x主要靠zookeeper來實現負載均衡)。
9.同步異步:Producer採用異步push方式,極大提升Kafka系統的吞吐率(能夠經過參數控制是採用同步仍是異步方式)。
10.分區機制partition:Kafka的broker端支持消息分區,Producer能夠決定把消息發到哪一個分區,在一個分區中消息的順序就是Producer發送消息的順序,一個主題中能夠有多個分區,具體分區的數量是可配置的。分區的意義很重大,後面的內容會逐漸體現。
11.離線數據裝載:Kafka因爲對可拓展的數據持久化的支持,它也很是適合向Hadoop或者數據倉庫中進行數據裝載。
12.插件支持:如今很多活躍的社區已經開發出很多插件來拓展Kafka的功能,如用來配合Storm、Hadoop、flume相關的插件。
kafka 應用場景
1.日誌收集:一個公司能夠用Kafka能夠收集各類服務的log,經過kafka以統一接口服務的方式開放給各類consumer,例如hadoop、Hbase、Solr等。
2.消息系統:解耦和生產者和消費者、緩存消息等。
3.用戶活動跟蹤:Kafka常常被用來記錄web用戶或者app用戶的各類活動,如瀏覽網頁、搜索、點擊等活動,這些活動信息被各個服務器發佈到kafka的topic中,而後訂閱者經過訂閱這些topic來作實時的監控分析,或者裝載到hadoop、數據倉庫中作離線分析和挖掘。
4.運營指標:Kafka也常常用來記錄運營監控數據。包括收集各類分佈式應用的數據,生產各類操做的集中反饋,好比報警和報告。
5.流式處理:好比spark streaming和storm
6.事件源
官網kafka實例版本的問題。
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
當kafka的版本是 kafka_2.12-2.1.1,不支持bootstrap-server
報錯"bootstrap-server is not a recognized option"
option,換成版本kafka_2.12-2.2.0就ok了。應該是2.2.0的新特性。<br
kafka isr機制
isr的全稱是In-Sync Replicas isr(已同步的副本) 是一個副本的列表,裏面存儲的都是能跟leader 數據一致的副本,肯定一個副本在isr列表中,有2個判斷條件
條件1:根據副本和leader 的交互時間差,若是大於某個時間差 就認定這個副本不行了,就把此副本從isr 中剔除,此時間差根據
配置參數rerplica.lag.time.max.ms=10000 決定 單位ms
條件2:根據leader 和副本的信息條數差值決定是否從isr
中剔除此副本,此信息條數差值根據配置參數rerplica.lag.max.messages=4000 決定單位條
isr 中的副本刪除或者增長 都是經過一個週期調度來管理的
request.required.acks 的參數說明:
0:生產者只管發送,無論服務器,消費者是否收到信息
1:只有當leader 確認了收到消息,才確認此消息發送成功
-1:只有isr 中的n-1個副本(leader 除外因此n-1)都同步了消息 此消息才確認發送成功
生產者發送的消息只有在確認發送成功後 才能被消費者消費
kafka設計
一個Topic能夠認爲是一類消息,每一個topic將被分紅多個partition(區),每一個partition在存儲層面是append log文件。任何發佈到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱爲offset(偏移量),offset爲一個long型數字,它是惟一標記一條消息。它惟一的標記一條消息。kafka並無提供其餘額外的索引機制來存儲offset,由於在kafka中幾乎不容許對消息進行「隨機讀寫」 offset 是保存在zookeeper之中的。
kafka消費
對於consumer而言,它須要保存消費消息的offset,對於offset的保存和使用,有consumer來控制;當consumer正常消費消息時,offset將會"線性"的向前驅動,即消息將依次順序被消費.事實上consumer可使用任意順序消費消息,它只須要將offset重置爲任意值。
kafka狀態
kafka集羣幾乎不須要維護任何consumer和producer狀態信息,這些信息有zookeeper保存;所以producer和consumer的實現很是輕量級,它們能夠隨意離開,而不會對集羣形成額外的影響。
kafka的leader選舉規則
當leader失效時,需在followers中選取出新的leader,可能此時follower落後於leader,所以須要選擇一個"up-to-date"的follower.選擇follower時須要兼顧一個問題,就是新leader上所已經承載的partition leader的個數,若是一個server上有過多的partition leader,意味着此server將承受着更多的IO壓力.在選舉新leader,須要考慮到"負載均衡"。
kafka日誌刪除
日誌文件的刪除策略很是簡單:啓動一個後臺線程按期掃描log file列表,把保存時間超過閥值的文件直接刪除(根據文件的建立時間).爲了不刪除文件時仍然有read操做(consumer消費),採起copy-on-write方式。
CopyOnWrite機制
當咱們往容器中添加一個元素的時候,不是直接添加,而是對當前容器copy,複製一個容器,在這個複製的容器中添加元素,添加完以後,再將引用指向這個新容器。
優勢:CopyOnWrite容器能夠併發的進行讀操做,而不須要加鎖,由於 當前容器不會添加任何元素,因此這也是一種讀寫分離的思想,讀和寫的操做分開了。
缺點:
1.內存佔用問題,產生了兩個容器
2.只能保持數據的最終一致性,沒法保持 實時性,因此若是但願讀到新數據,不要用copyOnWrite
RabbitMQ與kafka的消息隊列模式
1.生產端發送一條消息經過路由投遞到Queue,只有一個消費者能消費到。
kafka
Kafka只支持消息持久化,消費端爲拉模型,消費狀態和訂閱關係由客戶端端負責維護,消息消費完後不會當即刪除,會保留歷史消息。所以支持多訂閱時,消息只會存儲一份就能夠了。可是可能產生重複消費的狀況。
以下圖,kafka集羣中,leader標識的是brokerid,後面的Isr(已同步的副本)也是brokerid。 從後面的一條記錄能夠看出,當其中一個broker down了之後會從Isr列表中清除掉。可是Replicas仍然保存。
kafka Connect 導入導出數據
kafka Connect是kafka附帶的一個工具,用於將數據導入和導出到kafka。是一個可擴展的工具,運行鏈接器,實現與外部系統的交互的自定義邏輯。
官網的例子分爲如下幾個步驟:(以單個broker爲例)
kafka Streams
kafka Streams是kafka的0.10提供的新能力,用於實時處理kafka中的數據流。和現有的流處理技術如SparkStreaming,Storm,Flink仍是有些區別的。
Kafka Streams是一套處理分析Kafka中存儲數據的客戶端類庫,處理完的數據或者寫回Kafka,或者發送給外部系統。它構建在一些重要的流處理概念之上:區分事件時間和處理時間、開窗的支持、簡單有效的狀態管理等。
Kafka Streams入門的門檻很低:很容易編寫單機的示例程序,而後經過在多臺機器上運行多個實例便可水平擴展從而達到高吞吐量。Kafka Streams利用Kafka的併發模型以實現透明的負載均衡。
Kafka Streams的價值體如今如下幾點,首先它提供了兩套輕量且易用的API有效下降了Kafka數據流處理的開發成本,在這以前可使用SparkStreaming(不支持單條消費)、Storm(必須使用Trident才支持時間窗),或者本身寫consumer(之前高層API還好,低層API是初學者的噩夢,最歡樂的是官方將低層API稱爲「Simple API」),如今至少又多了一種選擇。其次用它開發的應用支持跑在Yarn、Mesos、Docker或者純Java應用內,比較靈活。再次是數據流的兩種抽象比較有意思,目前我尚未深刻研究,但以爲用來處理不去重/去重的場景簡直太方便了。固然缺點也有,首先目前不支持異步操做,這就須要開發者當心在處理方法中不能有高開銷動做,不然整個處理線程阻塞。另外若是須要SQL接口或者ML能力,那仍是去找SparkStreaming吧。
下圖展現了Kafka Streams應用程序的解剖圖,讓咱們來看一些細節。
kafka的流實例參考
juejin.im/post/5cd50a…
kafka 消費的時候爲何每一個consumer只能消費一個partition? 爲何每一個partition只能有一個consumer。
kafka參數理解
登陸zookeeper客戶端,查看zookeeper中存儲的信息
linux IO過程
kafka實現高吞吐量的零拷貝機制
傳統的IO機制
傳統的以下圖所示
這一過程實際上發生了四次數據拷貝。首先經過系統調用將文件數據讀入到內核態 Buffer(DMA 拷貝),而後應用程序將內存態 Buffer 數據讀入到用戶態 Buffer(CPU 拷貝),接着用戶程序經過 Socket 發送數據時將用戶態 Buffer 數據拷貝到內核態 Buffer(CPU 拷貝),最後經過 DMA 拷貝將數據拷貝到 NIC Buffer。同時,還伴隨着四次上下文切換.
kafka在zookeeper中存儲結構
ActiveMQ
基於java開發,是Apache出品的、採用Java語言編寫的徹底基於JMS1.1規範的面向消息的中間嗎件。其最新架構被命名爲Apollo,京東的消息中間件就是基於activeMQ開發的。
優勢:
缺點:
zeroMQ
基於C開發,號稱史上最快的隊列。雖然大多數時候咱們習慣將其納入消息隊列家族之中,可是其和前面的幾款有着本質的區別,ZeroMQ自己就不是一個消息隊列服務器,更像是一組底層網絡通信庫,對原有的Socket API上加上一層封裝而已。
優勢:
缺點:
RocketMQ
基於java開發的,阿里消息中間。件目前已經捐獻個Apache基金會,它是由Java語言開發的,具有高吞吐量、高可用性、適合大規模分佈式系統應用等特色,經歷過雙11的洗禮。
優勢 :
選取理由:
缺點:
Jafka 是在 Kafka 之上孵化而來的,即 Kafka 的一個升級版。具備如下特性:快速持久化,能夠在 O(1) 的系統開銷下進行消息持久化;高吞吐,在一臺普通的服務器上既能夠達到 10W/s 的吞吐速率;徹底的分佈式系統,Broker、Producer、Consumer 都原生自動支持分佈式,自動實現負載均衡;支持 Hadoop 數據並行加載,對於像 Hadoop 的同樣的日誌數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。