kafka與rabbitmq

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,只有一個消費者能消費到。

2.多訂閱
當RabbitMQ須要支持多訂閱時,發佈者發送的消息經過路由同時寫到多個Queue,不一樣訂閱組消費不一樣的Queue。因此支持多訂閱時,消息會多個拷貝。

kafka
Kafka只支持消息持久化,消費端爲拉模型,消費狀態和訂閱關係由客戶端端負責維護,消息消費完後不會當即刪除,會保留歷史消息。所以支持多訂閱時,消息只會存儲一份就能夠了。可是可能產生重複消費的狀況。

以下圖,kafka集羣中,leader標識的是brokerid,後面的Isr(已同步的副本)也是brokerid。 從後面的一條記錄能夠看出,當其中一個broker down了之後會從Isr列表中清除掉。可是Replicas仍然保存。

kafka Connect 導入導出數據
kafka Connect是kafka附帶的一個工具,用於將數據導入和導出到kafka。是一個可擴展的工具,運行鏈接器,實現與外部系統的交互的自定義邏輯。
官網的例子分爲如下幾個步驟:(以單個broker爲例)

  1. 啓動zookeeper
    bin/zookeeper-server-start.sh config/zookeeper.properties
  2. 啓動broker server
    bin/kafka-server-start.sh config/server.properties
  3. 在kafka目錄建立文件test.txt 文件名若更改,配置文件須要同步修改
    echo -e "foo\nbar" > test.txt
  4. 啓動connect
    bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties
  5. 查看kafka
    bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
  6. 查看kafka對應的目錄

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參數理解

參數--bootrap-server 與 --zookeeper
在老的版本中僅只能用--zookeeper,在最新的版本中支持bootstrap-server。
bootstrap-server指定了kafka的server地址,就無需再指定zookeeper地址。

zookeeper已是不建議使用的參數。

登陸zookeeper客戶端,查看zookeeper中存儲的信息

linux IO過程

kafka實現高吞吐量的零拷貝機制
傳統的IO機制

Kafka中存在大量的網絡數據持久化到磁盤(Producer到Broker)和磁盤文件經過網絡發送(Broker到Consumer)的過程。這一過程的性能直接影響Kafka的總體吞吐量。
以將磁盤文件經過網絡發送爲例。傳統模式下,通常使用以下僞代碼所示的方法先將文件數據讀入內存,而後經過Socket將內存中的數據發送出去。
buffer = File.read
Socket.send(buffer)
這一過程實際上發生了四次數據拷貝。首先經過系統調用將文件數據讀入到內核態Buffer(DMA拷貝),而後應用程序將內存態Buffer數據讀入到用戶態Buffer(CPU拷貝),接着用戶程序經過Socket發送數據時將用戶態Buffer數據拷貝到內核態Buffer(CPU拷貝),最後經過DMA拷貝將數據拷貝到NIC Buffer。

傳統的以下圖所示

這一過程實際上發生了四次數據拷貝。首先經過系統調用將文件數據讀入到內核態 Buffer(DMA 拷貝),而後應用程序將內存態 Buffer 數據讀入到用戶態 Buffer(CPU 拷貝),接着用戶程序經過 Socket 發送數據時將用戶態 Buffer 數據拷貝到內核態 Buffer(CPU 拷貝),最後經過 DMA 拷貝將數據拷貝到 NIC Buffer。同時,還伴隨着四次上下文切換.

數據經過 DMA 拷貝到內核態 Buffer 後,直接經過 DMA 拷貝到 NIC Buffer,無需 CPU 拷貝。除了減小數據拷貝外,由於整個讀文件 - 網絡發送由一個 sendfile 調用完成,整個過程只有兩次上下文切換,所以大大提升了性能。零拷貝過程如上圖所示。

kafka在zookeeper中存儲結構

ActiveMQ
基於java開發,是Apache出品的、採用Java語言編寫的徹底基於JMS1.1規範的面向消息的中間嗎件。其最新架構被命名爲Apollo,京東的消息中間件就是基於activeMQ開發的。
優勢:

  1. 誇平臺
  2. 能夠用JDBC:能夠將數據持久化到數據庫
  3. 支持JMS :支持JMS的統一接口
  4. 支持自動重連
  5. 有安全機制:支持基於shiro,jaas等多種安全配置機制,能夠對Queue/Topic進行認證和受權
  6. 監控完善:擁有完善的監控,包括Web Console,JMX,Shell命令行,Jolokia的REST API
  7. 界面友善:提供的Web Console能夠知足大部分狀況,還有不少第三方的組件可使用,如hawtio

缺點:

  1. 社區活躍度不及RabbitMQ高
  2. 會出莫名其妙的問題,會丟失消息
  3. 不適合用於上千個隊列的應用場景

zeroMQ
基於C開發,號稱史上最快的隊列。雖然大多數時候咱們習慣將其納入消息隊列家族之中,可是其和前面的幾款有着本質的區別,ZeroMQ自己就不是一個消息隊列服務器,更像是一組底層網絡通信庫,對原有的Socket API上加上一層封裝而已。

優勢:

  1. 號稱最快的消息隊列系統,尤爲針對大吞吐量的需求場景
  2. 單獨部署或集成到應用中使用,不須要安裝和運行一個消息服務器或中間件,由於你的應用程序將扮演了這個服務角色
  3. 可以實現高級/複雜的隊列,可是開發人員須要本身組合多種技術框架
  4. 跨平臺,多語言支持
  5. 可做爲Socket通訊庫使用

缺點:

  1. 僅提供非持久性的隊列,也就是說若是down機,數據將會丟失

RocketMQ
基於java開發的,阿里消息中間。件目前已經捐獻個Apache基金會,它是由Java語言開發的,具有高吞吐量、高可用性、適合大規模分佈式系統應用等特色,經歷過雙11的洗禮。
優勢 :

  1. 單機支持 1 萬以上持久化隊列
  2. RocketMQ 的全部消息都是持久化的,先寫入系統pagecache(頁高速緩衝存儲器),而後刷盤,能夠保證內存與磁盤都有一份數據 ,訪問時,直接從內存讀取
  3. 模型簡單,接口易用
  4. 性能很是好,能夠大量堆積消息在broker(集羣中包含一個或多個服務器,這些服務器被稱爲broker)中
  5. 支持多種消費,包括集羣消費、廣播消費等
  6. 各個環節分佈式擴展設計,主從HA(高可用性集羣)
  7. 開發度較活躍,版本更新很快

選取理由:

  1. 強調集羣無單點,任意一點高可用,可水平擴展
  2. 海量消息堆積能力,消息堆積後, 寫入低延遲
  3. 支持上萬個隊列
  4. 消息失敗自動重試機制 特色: 設計不遵循任何規範,不遵循JMS規範,可是參考了各類規範,與同類產品的設計思想。
    在1.0版本與2.0版本也是採用zookeeper作集羣。在3.0的時候拋棄了zookeeper本身內部實現了一個組件nameserver,比zookeeper更加輕量級,更加的穩定。也支持cousumer group。只有一種模式,發佈->訂閱,不存在點對點的機制。支持持久化,開源的只支持持久到mysql,阿里估計能支持持久到OceanBase 。 存儲沒有邊界的,當存儲滿的時候會剔除掉最先的記錄。

缺點:

  1. 支持的客戶端語言很少,目前是java及c++,其中c++不成熟
  2. RocketMQ社區關注度及成熟度也不高
  3. 沒有web管理界面,提供了一個CLI(命令行界面)管理工具帶來查詢、管理和診斷各類問題
  4. 沒有在MQ核心中去實現JMS等接口

Jafka 是在 Kafka 之上孵化而來的,即 Kafka 的一個升級版。具備如下特性:快速持久化,能夠在 O(1) 的系統開銷下進行消息持久化;高吞吐,在一臺普通的服務器上既能夠達到 10W/s 的吞吐速率;徹底的分佈式系統,Broker、Producer、Consumer 都原生自動支持分佈式,自動實現負載均衡;支持 Hadoop 數據並行加載,對於像 Hadoop 的同樣的日誌數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。

相關文章
相關標籤/搜索