Kafka玩出植物大戰殭屍即視感

​從這篇文章你將瞭解到什麼?
  • Kafka的topic爲何要分區。面試

  • 消費者組的做用。
    markdown

  • Kafka分區分配。架構





「Kafka是一個分佈式、支持分區的(partition)、多副本的(replica),基於zookeeper協調的分佈式消息系統。」

看着這一句句對Kafka的介紹,以及這張架構圖, 忽然感受眼前一陣恍惚......



再睜眼的瞬間, 畫風竟然變成了植物大戰殭屍的樣子!!!分佈式


下面咱們來講道說道這有趣的場景:spa


咱們熟悉的消息生產者——天然就是植物大戰殭屍中能夠生成糧食的植物了。3d


好比生產者豌豆射手:code

他能夠發送出普通豌豆(消息)。orm


好比生產者寒冰射手:
遊戲

他能夠發送出寒冰豌豆(消息)。kafka



再來看看咱們可愛的消費者殭屍,他們能夠消耗(消費)生產者發出來的豌豆(消息)。


而Kafka broker服務就是一個個炮臺!
炮臺能夠儲存豌豆射手發送過來的豌豆, 而後再把這些豌豆投送給殭屍。

ZooKeeper就是殭屍最喜歡的大腦了!

固然這只是一句玩笑,咱們消費者殭屍是不會移動的,也不會去攻擊Zookeeper。

這裏要說明一下,全部消費者殭屍的夢想都是不放過每一顆屬於他的豌豆。他們甚至會主動從炮臺拉取(pull)豌豆過來消耗(消費)。

玩過植物大戰殭屍的小夥伴們都知道,遊戲中是沒有Kafka炮臺這種東西的。那爲何咱們須要Kafka呢?

下面咱們來看看,沒有Kafka時,生產者直接面對消費者殭屍的狀況。

1 生產者大戰殭屍

在沒有Kafka的狀況下, 豌豆射手(生產者)VS殭屍(消費者)。
豌豆射手要一邊留意殭屍的位置, 一邊費盡全力將豌豆(消息)發送到殭屍身上!

若是這時候出現一大波新的殭屍!

豌豆射手除了要及時辨認出全部殭屍的位置外, 還要把同一顆豌豆(同一個消息)同時投送給每個殭屍。

豌豆射手還要留意投送出去的的豌豆有沒有發送成功,若是一顆豌豆石沉大海,那究竟是這個殭屍已經掛了,仍是方向射偏了?同時還要從萬千消費者中找到這個投送失敗的殭屍,從新投送。

這也太累了吧!

而從殭屍的角度上看呢, 他除了要消耗每個豌豆, 還要費勁辨認出每個豌豆射手的位置, 不然的話, 就接不到豌豆射手投出來的豌豆了!


隨着生產者和消費者的增多,他們之間的關係也就愈來愈混亂。這樣一來, 不只豌豆射手累, 殭屍也累!



2 Kafka大戰殭屍

若是在豌豆射手和殭屍之間加上一個Kafka炮臺(kafka broker)會怎麼樣呢?
如今豌豆射手只須要關心Kafka炮臺的位置, 而後把豌豆發送給Kafka炮臺存儲起來。豌豆射手不用再關心有多少個消費者殭屍, 只要一心一意地生產豌豆就好, 多舒心!


而消費者殭屍呢, 一樣也不須要關心有多少生產者,只須要記住Kafka炮臺的位置,專心消耗豌豆就行。


Kafka的使用場景之一就是解耦生產者和消費者,生產者和消費者再也不直接接觸。


消費者組


Kafka炮臺支持兩種豌豆投遞方式。

把消費者殭屍劃分紅不一樣的消費者組,那麼就能夠實現點對點模式和廣播模式。


若是每一個消費者殭屍屬於不一樣的消費組,那麼同一顆豌豆會被「廣播」給每一個消費組內的殭屍。


若是每一個消費者殭屍都在同一個消費組,那麼同一顆豌豆,每個消費組內只能有一個殭屍能消耗這顆豌豆。

主題與訂閱


生產者有不少類型,有普通豌豆射手,有寒冰射手,有火焰射手等等,這些生產者發出來的豌豆就分別對應3個Topic:普通主題,寒冰主題, 火焰主題。


主題若是沒有分區,那麼就意味着每一個炮臺只能接收一種主題的豌豆。
若是一個炮臺接收了寒冰豌豆,那麼他就不能再接收普通豌豆。



消費者殭屍也有不少種類型,寒冰殭屍擅長消耗寒冰豌豆,火焰抗性高的殭屍擅長消耗火焰豌豆。

不一樣的消費者殭屍會主動從Kafka炮臺「訂閱」本身感興趣的主題。好比寒冰殭屍會專門去消耗寒冰豌豆,普通殭屍會專門去消耗普通豌豆。


主題沒有分區的弊端


不少不一樣類型生產者其實均可以生產普通豌豆,好比二連豌豆,三連豌豆,加特林豌豆(四連發),甚至還有能夠五連發的豌豆莢。



若是如今戰場上投入一批五連發的豌豆莢!

能夠預見的是,將會有巨量的普通豌豆發送到普通主題炮臺中,很快這個炮臺就會積壓不少豌豆發送不出去,而且還有可能由於負載過大而宕機,而與此造成鮮明對比的是,其餘主題的炮臺倒是處於空閒狀態,連一顆寒冰/火焰豌豆都接收不到。


而站在消費組殭屍的角度上看,即便如今新增再多的消費者,也沒法加速豌豆的消耗,由於Kafka炮臺已經成爲吞吐量的瓶頸。


3 主題分區


若是咱們讓每一個炮臺均可以接收多種主題的豌豆, 這樣就能夠充分利用場上的每個炮臺了。這就是主題的分區。


假如如今咱們給普通豌豆主題2個分區, 這2個分區分別分佈在兩個炮臺中。


這樣場上全部炮臺能夠接收普通豌豆子彈,理想狀態下,是能夠減緩了單一炮臺的壓力,這就是主題分區的特色之一,分佈式存儲


而對於消費者殭屍而言,如今同一時間能夠有兩個消費者殭屍消耗普通豌豆, 加快了豌豆的消耗速度,這主題分區的另外一個特色,分佈式消費



4 分區分配


如今主題有了分區,在得到了不少好處的同時,又必然會引伸出一系列複雜的問題。


生產者的分區分配


如圖,若是豌豆莢每次給主題分區1和分區2按4:1的比例發放豌豆,那麼最後仍是會致使分區1所在的Kafka炮臺負擔太重。

全部如今生產者要考慮怎麼才能把豌豆均勻地分發給各個Kafka炮臺。


在Kafka中,若是生產者有指定分區號,那麼消息會直接發往指定的分區。不然會提供默認的分區器DefaultPartitioner,對消息的key進行哈希運算獲得分區號。若是消息沒有key,那麼就會採用輪詢的方式給主題下的各個分區發送消息。


消費者的分區分配


如圖,若是兩個分區的豌豆都由同一個消費者殭屍負責消耗,另外一個消費者將無所事事,這就是消費者分區分配不均的狀況。


因此,消費者殭屍也要討論由哪些殭屍負責消耗哪些分區的豌豆,讓每一個殭屍均可以均勻地承受打擊。


Kafka提供的消費者分區分配策略有三種,分別是RangeAssignor、RoundRobinAssignor和StickyAssignor。每種策略的具體細節屬於殭屍大軍中的「高度機密」(面試高頻),咱們將在下一篇文章中進行講解。


broker端的分區分配


思考一下,若是一個生產者把全部豌豆發送給炮臺存儲後,炮臺宕機了,那這批豌豆就丟失了,那怎麼才能避免這問題呢?這就是數據的容災能力問題了。


咱們給每一個主題的分區引入副本的概念。


若是每個分區都有2個副本,副本之間的關係是一個Leader對多個follower。

只有Leader副本才能存儲豌豆,其餘副本只是同步Leader的數據。


若是Leader宕機了,那麼就會在剩下的副本中選出新的Leader。這就實現了故障的自動轉移。


Kafka集羣在建立主題時,就要考慮分區副本應該分配在哪一個broker上。


而引入副本機制後,與此相關的優先副本選舉,副本之間的同步機制等問題又是一次長篇大論了。



5 後續


因爲篇幅有限,不少沒有說起的問題,就留到下一篇再講解了。
  • ZooKeeper的做用。

  • 分區的有序性。

  • 分區數。

  • 重平衡。




相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息