kafka分区与分组原理_kafka 基本原理和概念
Kafka系統的角色Broker :一臺kafka服務器就是一個broker。一個集群由多個broker組成。一個broker可以容納多個topic
topic: 可以理解為一個MQ消息隊列的名字
Partition:為了實現擴展性,一個非常大的topic可以分布到多個 broker(即服務器)上,一個topic可以分為多個partition,每個partition是一個有序的隊列。partition中的每條消息 都會被分配一個有序的id(offset)。kafka只保證按一個partition中的順序將消息發給consumer,不保證一個topic的整體 (多個partition間)的順序。也就是說,一個topic在集群中可以有多個partition,那么分區的策略是什么?(消息發送到哪個分區上,有兩種基本的策略,一是采用Key Hash算法,一是采用Round Robin算法)
ookeeper在Kakfa中扮演的角色Kafka將元數據信息保存在Zookeeper中,但是發送給Topic本身的數據是不會發到Zk上的,否則Zk就瘋了。kafka使用zookeeper來實現動態的集群擴展,不需要更改客戶端(producer和consumer)的配置。broker會在zookeeper注冊并保持相關的元數據(topic,partition信息等)更新。
而客戶端會在zookeeper上注冊相關的watcher。一旦zookeeper發生變化,客戶端能及時感知并作出相應調整。這樣就保證了添加或去除broker時,各broker間仍能自動實現負載均衡。這里的客戶端指的是Kafka的消息生產端(Producer)和消息消費端(Consumer)Broker端使用zookeeper來注冊broker信息,以及監測partition leader存活性.
Consumer端使用zookeeper用來注冊consumer信息,其中包括consumer消費的partition列表等,同時也用來發現broker列表,并和partition leader建立socket連接,并獲取消息.
Zookeer和Producer沒有建立關系,只和Brokers、Consumers建立關系以實現負載均衡,即同一個Consumer Group中的Consumers可以實現負載均衡
入門
1、簡介
Kafka is a distributed,partitioned,replicated commit logservice。它提供了類似于JMS的特性,但是在設計實現上完全不同,此外它并不是JMS規范的實現。kafka對消息保存時根據Topic進行歸類,發送消息者成為Producer,消息接受者成為Consumer,此外kafka集群有多個kafka實例組成,每個實例(server)成為broker。無論是kafka集群,還是producer和consumer都依賴于zookeeper來保證系統可用性集群保存一些meta信息。
2、Topics/logs
一個Topic可以認為是一類消息,每個topic將被分成多個partition(區),每個partition在存儲層面是append log文件。任何發布到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱為offset(偏移量),offset為一個long型數字,它是唯一標記一條消息。它唯一的標記一條消息。kafka并沒有提供其他額外的索引機制來存儲offset,因為在kafka中幾乎不允許對消息進行“隨機讀寫”。
kafka和JMS(Java Message Service)實現(activeMQ)不同的是:即使消息被消費,消息仍然不會被立即刪除.日志文件將會根據broker中的配置要求,保留一定的時間之后刪除;比如log文件保留2天,那么兩天后,文件會被清除,無論其中的消息是否被消費.kafka通過這種簡單的手段,來釋放磁盤空間,以及減少消息消費之后對文件內容改動的磁盤IO開支.
對于consumer而言,它需要保存消費消息的offset,對于offset的保存和使用,有consumer來控制;當consumer正常消費消息時,offset將會"線性"的向前驅動,即消息將依次順序被消費.事實上consumer可以使用任意順序消費消息,它只需要將offset重置為任意值..(offset將會保存在zookeeper中,參見下文)
kafka集群幾乎不需要維護任何consumer和producer狀態信息,這些信息有zookeeper保存;因此producer和consumer的客戶端實現非常輕量級,它們可以隨意離開,而不會對集群造成額外的影響.
partitions的設計目的有多個.最根本原因是kafka基于文件存儲.通過分區,可以將日志內容分散到多個server上,來避免文件尺寸達到單機磁盤的上限,每個partiton都會被當前server(kafka實例)保存;可以將一個topic切分多任意多個partitions,來消息保存/消費的效率.此外越多的partitions意味著可以容納更多的consumer,有效提升并發消費的能力.(具體原理參見下文).
3、Distribution
一個Topic的多個partitions,被分布在kafka集群中的多個server上;每個server(kafka實例)負責partitions中消息的讀寫操作;此外kafka還可以配置partitions需要備份的個數(replicas),每個partition將會被備份到多臺機器上,以提高可用性.
基于replicated方案,那么就意味著需要對多個備份進行調度;每個partition都有一個server為"leader";leader負責所有的讀寫操作,如果leader失效,那么將會有其他follower來接管(成為新的leader);follower只是單調的和leader跟進,同步消息即可..由此可見作為leader的server承載了全部的請求壓力,因此從集群的整體考慮,有多少個partitions就意味著有多少個"leader",kafka會將"leader"均衡的分散在每個實例上,來確保整體的性能穩定.
Producers
Producer將消息發布到指定的Topic中,同時Producer也能決定將此消息歸屬于哪個partition;比如基于"round-robin"方式或者通過其他的一些算法等.
Consumers
本質上kafka只支持Topic.每個consumer屬于一個consumer group;反過來說,每個group中可以有多個consumer.發送到Topic的消息,只會被訂閱此Topic的每個group中的一個consumer消費.
如果所有的consumer都具有相同的group,這種情況和queue模式很像;消息將會在consumers之間負載均衡.
如果所有的consumer都具有不同的group,那這就是"發布-訂閱";消息將會廣播給所有的消費者.
在kafka中,一個partition中的消息只會被group中的一個consumer消費;每個group中consumer消息消費互相獨立;我們可以認為一個group是一個"訂閱"者,一個Topic中的每個partions,只會被一個"訂閱者"中的一個consumer消費,不過一個consumer可以消費多個partitions中的消息.kafka只能保證一個partition中的消息被某個consumer消費時,消息是順序的.事實上,從Topic角度來說,消息仍不是有序的.
kafka的設計原理決定,對于一個topic,同一個group中不能有多于partitions個數的consumer同時消費,否則將意味著某些consumer將無法得到消息.
Guarantees
1) 發送到partitions中的消息將會按照它接收的順序追加到日志中
2) 對于消費者而言,它們消費消息的順序和日志中消息順序一致.
3) 如果Topic的"replicationfactor"為N,那么允許N-1個kafka實例失效.
二、使用場景
1、Messaging
對于一些常規的消息系統,kafka是個不錯的選擇;partitons/replication和容錯,可以使kafka具有良好的擴展性和性能優勢.不過到目前為止,我們應該很清楚認識到,kafka并沒有提供JMS中的"事務性""消息傳輸擔保(消息確認機制)""消息分組"等企業級特性;kafka只能使用作為"常規"的消息系統,在一定程度上,尚未確保消息的發送與接收絕對可靠(比如,消息重發,消息發送丟失等)
2、Websit activity tracking
kafka可以作為"網站活性跟蹤"的最佳工具;可以將網頁/用戶操作等信息發送到kafka中.并實時監控,或者離線統計分析等
3、Log Aggregation
kafka的特性決定它非常適合作為"日志收集中心";application可以將操作日志"批量""異步"的發送到kafka集群中,而不是保存在本地或者DB中;kafka可以批量提交消息/壓縮消息等,這對producer端而言,幾乎感覺不到性能的開支.此時consumer端可以使hadoop等其他系統化的存儲和分析系統.
它的架構包括以下組件:
話題(Topic):是特定類型的消息流。消息是字節的有效負載(Payload),話題是消息的分類名或種子(Feed)名。
生產者(Producer):是能夠發布消息到話題的任何對象。
服務代理(Broker):已發布的消息保存在一組服務器中,它們被稱為代理(Broker)或Kafka集群。
消費者(Consumer):可以訂閱一個或多個話題,并從Broker拉數據,從而消費這些已發布的消息。
Kafka存儲策略
1)kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應一個邏輯log,有多個segment組成。
2)每個segment中存儲多條消息(見下圖),消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲位置,避免id到位置的額外映射。
3)每個part在內存中對應一個index,記錄每個segment中的第一條消息偏移。
4)發布者發到某個topic的消息會被均勻的分布到多個partition上(或根據用戶指定的路由規則進行分布),broker收到發布消息往對應partition的最后一個segment上添加該消息,當某個segment上的消息條數達到配置值或消息發布時間超過閾值時,segment上的消息會被flush到磁盤,只有flush到磁盤上的消息訂閱者才能訂閱到,segment達到一定的大小后將不會再往該segment寫數據,broker會創建新的segment。
Kafka刪除策略
1)N天前的刪除。
2)保留最近的MGB數據。
Kafka broker
與其它消息系統不同,Kafka broker是無狀態的。這意味著消費者必須維護已消費的狀態信息。這些信息由消費者自己維護,broker完全不管(有offset managerbroker管理)。從代理刪除消息變得很棘手,因為代理并不知道消費者是否已經使用了該消息。Kafka創新性地解決了這個問題,它將一個簡單的基于時間的SLA應用于保留策略。當消息在代理中超過一定時間后,將會被自動刪除。
這種創新設計有很大的好處,消費者可以故意倒回到老的偏移量再次消費數據。這違反了隊列的常見約定,但被證明是許多消費者的基本特征。
以下摘抄自kafka官方文檔:
Kafka Design
目標
1) 高吞吐量來支持高容量的事件流處理
2) 支持從離線系統加載數據
3) 低延遲的消息系統
持久化
1) 依賴文件系統,持久化到本地
2) 數據持久化到log
效率
1) 解決”small IO problem“:
使用”message set“組合消息。
server使用”chunks of messages“寫到log。
consumer一次獲取大的消息塊。
2)解決”byte copying“:
在producer、broker和consumer之間使用統一的binary message format。
使用系統的pagecache。
使用sendfile傳輸log,避免拷貝。
Kafka支持GZIP和Snappy壓縮協議。
The Producer
負載均衡
1)producer可以自定義發送到哪個partition的路由規則。默認路由規則:hash(key)%numPartitions,如果key為null則隨機選擇一個partition。
2)自定義路由:如果key是一個user id,可以把同一個user的消息發送到同一個partition,這時consumer就可以從同一個partition讀取同一個user的消息。
異步批量發送
批量發送:配置不多于固定消息數目一起發送并且等待時間小于一個固定延遲的數據。
The Consumer
consumer控制消息的讀取。
Push vs Pull
1)producer push data to broker,consumer pull data from broker
2)consumer pull的優點:consumer自己控制消息的讀取速度和數量。
3)consumer pull的缺點:如果broker沒有數據,則可能要pull多次忙等待,Kafka可以配置consumer long pull一直等到有數據。
Consumer Position
1)大部分消息系統由broker記錄哪些消息被消費了,但Kafka不是。
2)Kafka由consumer控制消息的消費,consumer甚至可以回到一個old offset的位置再次消費消息。
Message Delivery Semantics
三種:
At most once—Messages may be lost but are never redelivered.
At least once—Messages are never lost but may be redelivered.
Exactly once—this is what people actually want, each message is delivered once and only once.
Producer:有個”acks“配置可以控制接收的leader的在什么情況下就回應producer消息寫入成功。
Consumer:
* 讀取消息,寫log,處理消息。如果處理消息失敗,log已經寫入,則無法再次處理失敗的消息,對應”At most once“。
* 讀取消息,處理消息,寫log。如果消息處理成功,寫log失敗,則消息會被處理兩次,對應”At least once“。
* 讀取消息,同時處理消息并把result和log同時寫入。這樣保證result和log同時更新或同時失敗,對應”Exactly once“。
Kafka默認保證at-least-once delivery,容許用戶實現at-most-once語義,exactly-once的實現取決于目的存儲系統,kafka提供了讀取offset,實現也沒有問題。
復制(Replication)
1)一個partition的復制個數(replication factor)包括這個partition的leader本身。
2)所有對partition的讀和寫都通過leader。
3)Followers通過pull獲取leader上log(message和offset)
4)如果一個follower掛掉、卡住或者同步太慢,leader會把這個follower從”in sync replicas“(ISR)列表中刪除。
5)當所有的”in sync replicas“的follower把一個消息寫入到自己的log中時,這個消息才被認為是”committed“的。
6)如果針對某個partition的所有復制節點都掛了,Kafka選擇最先復活的那個節點作為leader(這個節點不一定在ISR里)。
日志壓縮(Log Compaction)
1)針對一個topic的partition,壓縮使得Kafka至少知道每個key對應的最后一個值。
2)壓縮不會重排序消息。
3)消息的offset是不會變的。
4)消息的offset是順序的。
Distribution
Consumer Offset Tracking
1)High-level consumer記錄每個partition所消費的maximum offset,并定期commit到offset manager(broker)。
2)Simple consumer需要手動管理offset。現在的Simple consumer Java API只支持commit offset到zookeeper。
Consumers and Consumer Groups
1)consumer注冊到zookeeper
2)屬于同一個group的consumer(group id一樣)平均分配partition,每個partition只會被一個consumer消費。
3)當broker或同一個group的其他consumer的狀態發生變化的時候,consumer rebalance就會發生。
Zookeeper協調控制
1)管理broker與consumer的動態加入與離開。
2)觸發負載均衡,當broker或consumer加入或離開時會觸發負載均衡算法,使得一個consumer group內的多個consumer的訂閱負載平衡。
3)維護消費關系及每個partition的消費信息。
生產者代碼示例:
總結
以上是生活随笔為你收集整理的kafka分区与分组原理_kafka 基本原理和概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最近这里了这几年做过的计算机专业毕业设计
- 下一篇: 致初入职场的兄弟姐妹