標籤:

kafka中的topic為什麼要進行分區?

kafka為什麼要在topic里加入分區的概念?如果沒有分區,topic中的segment消息寫滿後,直接給訂閱者不是也可以嗎?


這裡其實有2個問題,可以逐一回答

1.kafka為什麼要在topic里加入分區的概念?
topic是邏輯的概念,partition是物理的概念,對用戶來說是透明的。producer只需要關心消息發往哪個topic,而consumer只關心自己訂閱哪個topic,並不關心每條消息存於整個集群的哪個broker。

為了性能考慮,如果topic內的消息只存於一個broker,那這個broker會成為瓶頸,無法做到水平擴展。所以把topic內的數據分布到整個集群就是一個自然而然的設計方式。Partition的引入就是解決水平擴展問題的一個方案。

如同我在Kafka設計解析(一)里所講,每個partition可以被認為是一個無限長度的數組,新數據順序追加進這個數組。物理上,每個partition對應於一個文件夾。一個broker上可以存放多個partition。這樣,producer可以將數據發送給多個broker上的多個partition,consumer也可以並行從多個broker上的不同paritition上讀數據,實現了水平擴展

2.如果沒有分區,topic中的segment消息寫滿後,直接給訂閱者不是也可以嗎
「segment消息寫滿後」,consume消費數據並不需要等到segment寫滿,只要有一條數據被commit,就可以立馬被消費

segment對應一個文件(實現上對應2個文件,一個數據文件,一個索引文件),一個partition對應一個文件夾,一個partition里理論上可以包含任意多個segment。所以partition可以認為是在segment上做了一層包裝。

這個問題換個角度問可能更好,「為什麼有了partition還需要segment」。
如果不引入segment,一個partition直接對應一個文件(應該說兩個文件,一個數據文件,一個索引文件),那這個文件會一直增大。同時,在做data purge時,需要把文件的前面部分給刪除,不符合kafka對文件的順序寫優化設計方案。引入segment後,每次做data purge,只需要把舊的segment整個文件刪除即可,保證了每個segment的順序寫,

更多kafka相關分析,可參考
http://www.jasongj.com/2015/01/02/Kafka%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/
Kafka設計解析(一)
http://www.jasongj.com/2015/04/24/KafkaColumn2/
http://www.jasongj.com/2015/06/08/KafkaColumn3/
Kafka設計解析(四)
http://www.jasongj.com/2015/12/31/KafkaColumn5_kafka_benchmark/


Kafka可以將主題劃分為多個分區(Partition),會根據分區規則選擇把消息存儲到哪個分區中,只要如果分區規則設置的合理,那麼所有的消息將會被均勻的分布到不同的分區中,這樣就實現了負載均衡和水平擴展。另外,多個訂閱者可以從一個或者多個分區中同時消費數據,以支撐海量數據處理能力:

Kafka的設計也是源自生活,好比是為公路運輸,不同的起始點和目的地需要修不同高速公路(主題),高速公路上可以提供多條車道(分區),流量大的公路多修幾條車道保證暢通,流量小的公路少修幾條車道避免浪費。收費站好比消費者,車多的時候多開幾個一起收費避免堵在路上,車少的時候開幾個讓汽車並道就好了,嗯……

順便說一句,由於消息是以追加到分區中的,多個分區順序寫磁碟的總效率要比隨機寫內存還要高(引用Apache Kafka – A High Throughput Distributed Messaging System的觀點),是Kafka高吞吐率的重要保證之一。

為了保證數據的可靠性,Kafka會給每個分區找一個節點當帶頭大哥(Leader),以及若干個節點當隨從(Follower)。消息寫入分區時,帶頭大哥除了自己複製一份外還會複製到多個隨從。如果隨從掛了,Kafka會再找一個隨從從帶頭大哥那裡同步歷史消息;如果帶頭大哥掛了,隨從中會選舉出新一任的帶頭大哥,繼續笑傲江湖。

更多內容請參考雲上的卡夫卡 - 數據工會。


若沒有分區,一個topic對應的消息集在分散式集群服務組中,就會分布不均勻,即可能導致某台伺服器A記錄當前topic的消息集很多,若此topic的消息壓力很大的情況下,伺服器A就可能導致壓力很大,吞吐也容易導致瓶頸。
有了分區後,假設一個topic可能分為10個分區,kafka內部會根據一定的演算法把10分區儘可能均勻分布到不同的伺服器上,比如:A伺服器負責topic的分區1,B伺服器負責topic的分區2,在此情況下,Producer發消息時若沒指定發送到哪個分區的時候,kafka就會根據一定演算法上個消息可能分區1,下個消息可能在分區2。當然高級API也能自己實現其分發演算法。


他們說的太複雜了。
水平擴展:磁碟寫入速度就是kafka處理速度的極限,處理不過來就要加機器。每台機器持有不同的partition。生產者愛發哪台發哪台,並行處理。


1,分散式存儲;2,分散式consumer;3,分區內的有序


首先, Partition對上層應用不透明. 用戶可以指定產生的消息publish到那個paritition.
topic之下分partition的原因負載均衡. 不考慮消息的順序, 單個Topic可以用多個Partition, leader均勻分散在全體broker上, 緩解單個broker過熱問題.

還有一個原因是, 每個.log文件(segment)對應的index文件中, offset為32bit, 如果單個Partition的record數目超過4GB, 應該怎麼呢? 使用多Partition.

如果hdd大小是8TB, ssd大小為1TB, 一個topic下產生的消息超過了磁碟大小,怎麼辦呢?

如果一個伺服器配置24/36塊盤, 把topic分成partition, 粒度小一下, 單機磁碟的負載也會根據均衡.

如果一個topic數據, 太大, 必然有partitioning的需要.


你還是得看下原理啊!
kafka入門 - OrcHome


大家的回家都很官方,從我的角度理解kafka作為一個消息中間件,那個其實和普通的消息隊列原理應該是一樣的。加入說我們用一個隊列來實現生產者和消費者模型,其實隊列就相當於topic(或者分區),topic是分區的抽象,是邏輯上的概念,而分區是物理上的概念。如果只有topic這個概念,相當於已有一個隊列,那麼生產者在寫和消費者的讀同時進行的時候必然就需要加鎖,這樣效率自然就高不到哪去了,所以一個topic被劃分到多個分區,相當於建立了多個隊列,本質上同一個分區讀寫應該還會加鎖,但是多個分區提高的並行度。而且分區實際上也是對數據按某種規則的進一步劃分,這個在某些實際的應用中是一種實實在在的需求。當然這點上阿里的RocketMq中有tag的概念,應用性更強。


1、分區類似hadoop分散式文件系統,也類似於spark中RDD以partition方式將數據分塊存儲,一是分塊存儲提高數據概率性安全,比如分散式的文件塊,如果某台機器宕機數據丟失,也是丟失一部分,不會出現整個文件全軍覆沒。另外通過partition級別的冗餘存儲(replication.factor)來保證partition級別的安全性。

2、kafka採用partition存儲方式,也提高訪問吞吐率,有負載均衡的效果。

3、最主要的是通過分區,對分區選Leader,可以增加Topic級別消息並發度。

綜上所述,一個是增大副本高可用,另外增加並發;

希望有幫助,多謝批評指正。


分區數小於broker數的時候,增加分區可以增加吞吐量。也可以增加消費者的並行度。


分區(partition)和索引(offset)一樣,是開放給clients的概念。基於指定的通信協議,Clients可向任一broker(周期性)查詢特定主題(topic)的元信息,包括主題有多少個分區,每個分區的leader分區在哪,並可以自主選擇連接到哪個分區,生產(produce)消息到該分區,或是從該分區的哪個位置(offset)開始消費(consume)。這些都是Clients決定的,broker端並沒有特殊的機制來保證這一點。

broker端保證的只有,不允許同一個消費者組(consumer group)的兩個消費者(consumer )去消費同一個分區的消息。從這一點來說,分區策略需要保證單個消費者至少有能力消費完單個分區的消息,否則消息會持續積壓。

所以分區實質是針對給定消息規模、給定(單)消費者能力的一個實踐性的部署建議。


Partition的話第一個目標,並行讀寫。 Producer產生10個新消息,可以交給10個broker上的partition一起寫;Consumer消費10個新消息,可以從10個broker上面一起讀。

還有就是如果一個topic在一個地方寫不下了咋辦,,所以partition。

另外:Replica和partition不一樣,replicas是為了容錯性。一個topic有很多partition,而每個partition又有很多replication。如果一個broker爆炸了,可以保證其上所有數據都有備份。看起來好像這東西能也能支持並行?不,,,這個只是用來單純的備份。。


為了負載均衡啊,很多分散式組件都有這種設計,比如mongodb的sharding。分區就是邏輯上還是一個topic,但是物理上分開存儲。


因為不同的topic所有的消息數量是不一樣的。對某個topic,可能他的消息數量超過了服務節點的極限,導致任務失敗。將topic分到不同的partition,讓不同的節點平攤任務,能更好的保證任務的完成。


主要是提高性能吧。因為如果沒有分區的概念,所有消息都獨立存放在一個磁碟中,那麼它的IO將是隊列的瓶頸所在。


The partitions in the log serve several purposes. First, they allow the log to scale beyond a size that will fit on a single server. Each individual partition must fit on the servers that host it, but a topic may have many partitions so it can handle an arbitrary amount of data. Second they act as the unit of parallelism—more on that in a bit.

The partitions of the log are distributed over the servers in the Kafka cluster with each server handling data and requests for a share of the partitions. Each partition is replicated across a configurable number of servers for fault tolerance.


多看文檔


推薦閱讀:

TAG:消息 | Kafka |