分散式訊息佇列
kafka介紹
基本架構
Kafka是開源的分散式訊息佇列,能夠輕鬆實現高吞吐、可擴充套件、高可用,並且部署簡單快速、開發介面豐富。
kafka分散式訊息佇列的作用:
- 解耦:將訊息生產階段和處理階段拆分開,兩個階段互相獨立各自實現自己的處理邏輯,通過kafka提供的訊息寫入和消費介面實現對訊息的連線處理。降低開發複雜度,提高系統穩定性。
- 高吞吐量:kafka通過順序讀寫磁碟提供可以和記憶體隨機讀寫相匹敵的讀寫速度,靈活的客戶端API設計,利用Linux作業系統提供的“零拷貝”特性減少訊息網路傳輸時間,提供端到端的訊息壓縮傳輸,對同一主題下的訊息採用分割槽儲存,kafka通過諸多良好的特性利用廉價的機器就可以輕鬆實現高吞吐率。
- 高容錯、高可用:kafka允許使用者對分割槽配置多副本,kafka將副本均勻分配到各個broker儲存,保證同一個分割槽的副本不會再同一臺機器上儲存(叢集模式下),多副本之間採用Leader-Follower機制同步訊息,只有Leader對外提供讀寫服務,當Leader以外失敗、Broker程式關閉、服務當機等情況導致資料不可用時,kafka會從Follwer中選擇一個Leader繼續提供讀寫服務。
- 可擴充套件:理論上kafka的效能隨著Broker的增多而增加,增加一個Broker只需要為新增加的Broker設定一個唯一編號,編寫好配置檔案後,kafka通過zookeeper就能發現新的Broker。
- 峰值處理:例如秒殺系統、雙十一等促銷活動的爆發幾種支付系統、推薦系統等都需要訊息佇列的介入,這類系統在某個時間點資料會爆發式增長,後臺處理系統不能夠及時處理峰值請求,如果沒有訊息佇列的接入就會造成後臺系統處理不及時,請求資料嚴重擠壓,如此惡性迴圈最終導致系統崩潰。kafka的接入能夠使資料進行冗餘儲存,並保證訊息順序讀寫,相當於給系統接入一個大的緩衝區,既能夠接收持續暴增的的請求,又能根據後臺系統的處理能力提供資料服務,進而提高各業務系統的峰值處理能力。
kafka相關名詞解析
- Broker:啟動kafka的一個例項就是一個Broker,預設埠9092。一個kafka叢集可以啟動多個Broker同時對外提供服務,Broker不儲存任何producer和consumer相關的資訊。
- Topic:主題,kafka中同一種型別資料集的名稱,相當於資料庫中的表,producer將同一型別的資料寫入同一個topic下,consumer從同一個topic消費同一型別的資料。邏輯上同一資料集只有一個topic,如果設定一個topic有多個partition和多個replication,在物理機上同一個topic下的資料集會被分成多份儲存到不同的物理機上。
- Partition:分割槽,一個topic可以設定多個分割槽,相當於把一個資料集分成多份分別放到不同的分割槽中儲存。一個topic可以有一個或者多個分割槽,在建立topic的時候可以設定topic的Partition數,如果不設定預設為1。理論上Partition數越多,系統的整體吞吐率就越高,但是在實際應用中並不是Partition越多越好,反而過多的Partition在broker當機需要重新對Partition選主,在這個過程中耗時太久會導致Partition暫時無法提供服務,造成寫入訊息失敗。分割槽命名規則是topicname-index。
- Segment:段檔案,kafka中最小資料儲存單位,kafka可以儲存多個topic,各個topic之間隔離沒有影響,一個topic包含一個或者多個Partition,每個Partition在物理結構上是一個資料夾,資料夾名稱以topic名稱加Partition索引的方式命名,一個Partition包含多個segment,每個segment以message在Partition中的其實偏移量命名以log結尾的檔案,productor想topic中釋出訊息會被順序寫入對應的segment檔案中。kafka為了提高寫入和查詢速度,在Partition資料夾下每個segment log檔案都有一個同名的索引檔案,索引檔案以index結尾。
- Offset:訊息在分割槽中的偏移量,用來在分割槽中唯一地表示這個訊息。
- Replication:副本,一個Partition可以設定一個或者多個副本,副本主要保證系統能夠持續不丟失地對外提供服務。在建立topic的時候可以設定Partition的replication數。
- Producer:訊息生產者,負責向kafka中釋出訊息。
- Consumer Group:消費者所屬組,一個Consumer Group可以包含一個或者多個consumer,當一個topic被一個Consumer Group消費的時候,Consumer Group內只能有一個consumer消費同一條訊息,不會出現Consumer Group中多個consumer同時消費一條訊息造成一個訊息被Consumer Group消費多次的情況。
- Consumer:訊息消費者,consumer從kafka指定的主題中拉取訊息,如果一個topic有多個分割槽,kafka只能保證一個分割槽內訊息的有序性,在不同的分割槽之間無法保證。
zookeeper:zookeeper在kafka叢集中主要用於協調管理,kafka將後設資料資訊儲存在zookeeper中,通過zookeeper協調管理來實現整個kafka叢集的動態擴充套件、各個Broker負載均衡、Productor通過zookeeper感知Partition的Leader、Consumer消費的負載均衡並可以儲存Consumer消費的狀態資訊,kafka0.9版本之前Consumer消費資訊的偏移量記錄在zookeeper中,0.9版本之後則由kafka自己維護Consumer消費訊息的偏移量。
高吞吐的實現
kafka通過順序讀寫磁碟提供可以和記憶體隨機讀寫相匹敵的讀寫速度,使用“sendfile”技術實現“零拷貝”減少訊息網路傳輸時間,通過對客戶端的優化設計提高訊息釋出和訂閱的效能,對同一主題下的訊息採用多分割槽儲存,kafka通過諸多良好的特性利用廉價的機器就可以輕鬆實現高吞吐率。
kafka配置引數詳解
Broker配置引數
- broker.id:broker的唯一標識,不同broker的值必須不同。
- host.name:繫結的主機名稱或IP。
- port:監聽埠。
- auto.create.topics.enable:是否自動建立topic,預設值為true。
- auto.leader.reblalance.enable:是否啟動Leader自動平衡,如果設定為true,將會有一個後臺執行緒定期檢查是否需要觸發leader平衡操作,預設值為true。
- leader.imbalance.check.interval.seconds:檢查分割槽是否平衡的時間間隔,預設值300秒。
- leader.imbalance.per.broker.percentage:每個broker允許的不平衡Leader的百分比,超過該值則會觸發Leader重新平衡,預設值為10。
- compression.type:設定topic壓縮格式,目前支援gzip、snappy、lz4壓縮格式。
- background.threads:後臺處理任務執行緒數,預設值為8。
- delete.topic.enable:是否啟動刪除主題功能,如果設定為true開啟功能,則使用kafka管理工具就可以刪除主題。預設值為false。
- log.dir:日誌資料儲存目錄。
- log.retention.bytes:每個分割槽最大檔案大小。
- log.retention.hours:資料儲存時長,超時檔案會被刪除。
- socket.send.buffer.bytes:socket傳送緩衝區大小。
- socket.receive.buffer.bytes:socket最大請求大小。
- zookeeper.connection.timeout.ms:客戶端與zookeeper連線的超時時間。
- zookeeper.session.timeout.ms:zookeeper最大超時時間。
- log.segment.bytes:Segment檔案大小。
- replica.fetch.wait.max.ms:副本Follower與leader之間通訊同步訊息的超時時間。
replica.lag.time.max.ms:如果Follower沒有向Leader傳送同步訊息請求的時間或者Follower一直沒有同步到Leader最後一條訊息的時間超過了該項配置的時間,則改Follower將會被移除出ISR。
更多kafka相關資訊請看新書Kafka技術內幕