简单分析KafKa工作原理
架構圖
Producer:Producer即生產者,消息的產生者,是消息的入口。
kafka cluster:
Broker:Broker是kafka實例,每個服務器上有一個或多個kafka的實例,我們姑且認為每個broker對應一臺服務器。每個kafka集群內的broker都有一個不重復的編號,如圖中的broker-0、broker-1等……
- Topic:消息的主題,可以理解為消息的分類,kafka的數據就保存在topic。在每個broker上都可以創建多個topic。
- Partition:Topic的分區,每個topic可以有多個分區,分區的作用是做負載,提高kafka的吞吐量。同一個topic在不同的分區的數據是不重復的,partition的表現形式就是一個一個的文件夾!
- Replication:每一個分區都有多個副本,副本的作用是做備胎。當主分區(Leader)故障的時候會選擇一個備胎(Follower)上位,成為Leader。在kafka中默認副本的最大數量是10個,且副本的數量不能大于Broker的數量,follower和leader絕對是在不同的機器,同一機器對同一個分區也只可能存放一個副本(包括自
Message:每一條發送的消息主體。
Consumer:消費者,即消息的消費方,是消息的出口。
Consumer Group:我們可以將多個消費組組成一個消費者組,在kafka的設計中同一個分區的數據只能被消費者組中的某一個消費者消費。同一個消費者組的消費者可以消費同一個topic的不同分區的數據,這也是為了提高kafka的吞吐量!
Zookeeper:kafka集群依賴zookeeper來保存集群的的元信息,來保證系統的可用性。
Partition的組成
Partition在服務器上的表現形式就是一個一個的文件夾,每個partition的文件夾下面會有多組segment文件,每組segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中沒有)三個文件, log文件就實際是存儲message的地方,而index和timeindex文件為索引文件,用于檢索消息。
如上圖,這個partition有三組segment文件,每個log文件的大小是一樣的,但是存儲的message數量是不一定相等的(每條的message大小不一致)。文件的命名是以該segment最小offset來命名的,如000.index存儲offset為0~368795的消息,kafka就是利用分段+索引的方式來解決查找效率的問題。
存儲策略
無論消息是否被消費,kafka都會保存所有的消息。那對于舊數據有什么刪除策略呢?
需要注意的是,kafka讀取特定消息的時間復雜度是O(1),所以這里刪除過期的文件并不會提高kafka的性能!
日志復制
Kafka 允許 topic 的 partition 擁有若干副本,你可以在server端配置partition 的副本數量。當集群中的節點出現故障時,能自動進行故障轉移,保證數據的可用性。
創建副本的單位是 topic 的 partition ,正常情況下, 每個分區都有一個 leader 和零或多個 followers 。
所有的讀寫操作都由 leader 處理,一般 partition 的數量都比 broker 的數量多的多,各分區的 leader 均 勻的分布在brokers 中。所有的 followers 節點都同步 leader 節點的日志,日志中的消息和偏移量都和 leader 中的一致。(當然, 在任何給定時間, leader 節點的日志末尾時可能有幾個消息尚未被備份完成)。
Followers 節點就像普通的 consumer 那樣從 leader 節點那里拉取消息并保存在自己的日志文件中。Followers 節點可以從 leader 節點那里批量拉取消息日志到自己的日志文件中。
與大多數分布式系統一樣,自動處理故障需要精確定義節點 “alive” 的概念。Kafka 判斷節點是否存活有兩種方式。
Kafka認為滿足這兩個條件的節點處于 “in sync” 狀態,區別于 “alive” 和 “failed” 。 Leader會追蹤所有 “in sync” 的節點。如果有節點掛掉了, 或是寫超時, 或是心跳超時, leader 就會把它從同步副本列表中移除。 同步超時和寫超時的時間由 replica.lag.time.max.ms 配置確定。
現在, 我們可以更精確地定義, 只有當消息被所有的副本節點加入到日志中時, 才算是提交, 只有提交的消息才會被 consumer 消費, 這樣就不用擔心一旦 leader 掛掉了消息會丟失。另一方面, producer 也 可以選擇是否等待消息被提交,這取決他們的設置在延遲時間和持久性之間的權衡,這個選項是由 producer 使用的 acks 設置控制。 請注意,Topic 可以設置同步備份的最小數量, producer 請求確認消息是否被寫入到所有的備份時, 可以用最小同步數量判斷。如果 producer 對同步的備份數沒有嚴格的要求,即使同步的備份數量低于 最小同步數量(例如,僅僅只有 leader 同步了數據),消息也會被提交,然后被消費。
ISR機制(一致性)
Kafka 動態維護了一個同步狀態的備份的集合 (a set of in-sync replicas), 簡稱 ISR ,在這個集合中的節點都是和 leader 保持高度一致的,只有這個集合的成員才 有資格被選舉為 leader,一條消息必須被這個集合 所有 節點讀取并追加到日志中了,這條消息才能視為提交。這個 ISR 集合發生變化會在 ZooKeeper 持久化,正因為如此,這個集合中的任何一個節點都有資格被選為 leader 。這對于 Kafka 使用模型中, 有很多分區和并確保主從關系是很重要的。因為 ISR 模型和 f+1 副本,一個 Kafka topic 冗余 f 個節點故障而不會丟失任何已經提交的消息。
向 Kafka 寫數據時,producers 設置 ack 是否提交完成, 0:不等待broker返回確認消息,1: leader保存成功返回或, -1(all): 所有備份都保存成功返回.請注意. 設置 “ack = all” 并不能保證所有的副本都寫入了消息。默認情況下,當 acks = all 時,只要 ISR 副本同步完成,就會返回消息已經寫入。
性能優化
順序寫磁盤
將寫磁盤的過程變為順序寫,可極大提高對磁盤的利用率。Consumer通過offset順序消費這些數據,且不刪除已經消費的數據,從而避免隨機寫磁盤的過程。
Kafka刪除舊數據的方式是刪除整個Segment對應的log文件和整個index文件,而不是刪除部分內容。
充分利用Page Cache(內核緩存)
相比于維護盡可能多的 in-memory cache,并且在空間不足的時候匆忙將數據 flush 到文件系統,我們把這個過程倒過來。所有數據一開始就被寫入到文件系統的持久化日志中,而不用在 cache 空間不足的時候 flush 到磁盤。實際上,這表明數據被轉移到了內核的 pagecache 中。
Page Cache的優點:
零拷貝
Kafka中存在大量網絡數據持久化到磁盤(Producer到Broker)和磁盤文件通過網絡發送(Broker到Consumer)的過程,這個過程中傳統模式下要進行數據的四次拷貝,Kafka通過零拷貝技術(sendfile)提交效率
減少網絡開銷
在某些情況下,數據傳輸的瓶頸不是 CPU ,也不是磁盤,而是網絡帶寬。對于需要通過廣域網在數據中心之間發送消息的數據管道尤其如此。當然,用戶可以在不需要 Kakfa 支持下一次一個的壓縮消息。但是這樣會造成非常差的壓縮比和消息重復類型的冗余,比如 JSON 中的字段名稱或者是或 Web 日志中的用戶代理或公共字符串值。高性能的壓縮是一次壓縮多個消息,而不是壓縮單個消息。
Kafka 以高效的批處理格式支持一批消息可以壓縮在一起發送到服務器。這批消息將以壓縮格式寫入,并且在日志中保持壓縮,只會在 consumer 消費時解壓縮。
Kafka 支持 GZIP,Snappy 和 LZ4 壓縮協議
參考
- kafka中文文檔
- kafka-CAP理論
- Kafka工作原理
總結
以上是生活随笔為你收集整理的简单分析KafKa工作原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 香港域名注册怎么绑定ip(如何注册香港域
- 下一篇: MySQL日志:binlog、事务日志(