本篇是消息隊列中的一節,爲何講到消息隊列見:https://segmentfault.com/a/11...。其中流處理的數據傳播用到消息隊列。另外消息隊列還能夠做用於異步處理,流量削峯,多系統同步等。另外一篇介紹了傳統的JMS(activemq),AMQP(rabbitmq),本篇介紹kafka,robbitmq,ddmq,另外簡單說下bridgemq以及常見mq的綜合對比。同其餘系統同樣,終點關注架構組件,功能(生產消費等),分佈式的高可用,擴展性,一致性等linux
官方:發佈訂閱,流處理管道和存儲
https://kafka.apache.org/docu...redis
https://kafka.apache.org/docu...apache
1) Producer端使用zookeeper用來"發現"broker列表,以及和Topic下每一個partition leader創建socket鏈接併發送消息.
2) Broker端使用zookeeper用來註冊broker信息,以及監測partition leader存活性.全部的Kafka Broker節點一塊兒去Zookeeper上註冊一個臨時節點,成功的爲Broker controller,失效後zk後發現從新註冊節點,controller負責各broker內partition的選主(ISR中,記錄replica進度,隨便選)ISR,在這個集合中的節點都是和leader保持高度一致的,任何一條消息必須被這個集合中的每一個節點讀取並追加到日誌中了,纔回通知外部這個消息已經被提交了。所以這個集合中的任何一個節點隨時均可以被選爲leader.若是ISR的大小超過某個最小值,則分區將僅接受寫入,以防止丟失僅寫入單個副本的消息(只關注ISR,而不是共識多個都寫入,多數(兩個故障須要5個副本,一個要三個)對於主數據的寫代價大)【與ES相似都使用的Microsoft的PacificA】
3) Consumer端使用zookeeper用來註冊consumer信息,其中包括consumer消費的partition列表等,同時也用來發現broker列表,並和partition leader創建socket鏈接,並獲取消息。
broker,partition,customer組內線程可擴展。json
只保證一個partition被一個customer消費有序
producter推,customer拉(拉須要存日誌)
partition中的每一個message只能被組(Consumer group )中的一個consumer(consumer 線程)消費,若多個同時要配多個Consumer group。
kafka中的消息是批量(一般以消息的條數或者chunk的尺寸爲單位)發送給consumer,當消息被consumer接收以後,負責維護消息的消費記錄(JMS等都是broker維護),consumer能夠在本地保存最後消息的offset,並間歇性的向zookeeper註冊offset.也沒有ACK
消息消費的可靠性,消費者控制,最多一次,先保存offset再處理;至少一次,先處理再保存offset;只一次:最少1次+消費者的輸出中額外增長已處理消息最大編號segmentfault
確保有每一個分區數據日誌中每一個key有最後已知值,offset不能變。對同一partition的多個文件一塊兒壓縮合並。
position是文件的bytes偏移吧?壓縮過程當中要重建索引和位置?【我的理解是要重建的】
active不動(不影響寫入),對cleaner point後面的作壓縮,選擇日誌tail和header比例小的,合併壓縮每組log不超過1G,index不超過10M。
對於tail的壓縮過程:【position不變???我的理解這是錯誤的,position是變得】
每一個日誌清理線程會使用一個名爲「SkimpyOffsetMap」的對象來構建key與offset的映射關係的哈希表。日誌清理須要遍歷兩第二天志文件,第一次遍歷把每一個key的哈希值和最後出現的offset都保存在SkimpyOffsetMap中,映射模型以下圖所示。第二次遍歷檢查每一個消息是否符合保留條件,若是符合就保留下來,不然就會被清理掉服務器
activemq 不能分片。kafka性能(上面知道基本上partition和consumer須要配置同樣的,一個consumer group的線程數和partition數量一致,受partition限制,rocketmq多partition的擴展在於都用一個commitlog,而不是一個partition單獨一份順序log,對於磁盤多個文件是隨機寫入的,隨機高性能很差不能linux組提交,cq只存儲位置,在commitlog中找數據,一份徹底順序的寫入提升性能。對於消費順序和kafka都是同樣的保證,cq都是負載均衡,只保證一個cq順序。在消費時,須要先讀取cq上個的offset再讀commitlog。http://rocketmq.apache.org/ro...)架構
每一個commmit log消息發給topic的隨機queue中(生產者的負載均衡,每一個msg只發送到一個q中),每一個queue有不少consumequeue,發給全部。廣播模式,cq會在全部q上,集羣模式cq會負載均衡到某個q上,消息根據這些配置數據落到q的全部cq上。
併發
內存。redis實現。適合小型系統
負載均衡
這裏的kafka去掉了。普通的直接用哪一個rocketmq.延時消息和事務消息異步
分析:少topic時kafka性能好,rockemq須要讀mq後去讀一個大的cl。多topic是rockemq好,處理線程多。