Kafka 探險(xiǎn) - 架構(gòu)簡(jiǎn)介

這個(gè) Kafka 的專(zhuān)題啡直,我會(huì)從系統(tǒng)整體架構(gòu)烁涌,設(shè)計(jì)到代碼落地。和大家一起杠源碼酒觅,學(xué)技巧撮执,漲知識(shí)。希望大家持續(xù)關(guān)注一起見(jiàn)證成長(zhǎng)舷丹!
我相信:技術(shù)的道路抒钱,十年如一日!十年磨一劍!

簡(jiǎn)介

Kafka 是一種分布式的谋币,基于發(fā)布 / 訂閱的消息系統(tǒng)仗扬。最初被 LinkedIn 開(kāi)發(fā),并在 2011 年初開(kāi)源蕾额,2012 年 10 月從 Apache 孵化器破殼而出早芭,成為 Apache 的頂級(jí)項(xiàng)目。

Kafka 最初被設(shè)計(jì)的目的是 LinkedIn 流量和運(yùn)維數(shù)據(jù)分析诅蝶。流量數(shù)據(jù)包含 PV (Page View) , UV (Unique Visitor) ,搜索數(shù)據(jù)退个,詳情頁(yè)數(shù)據(jù)等。在高并發(fā)場(chǎng)景對(duì)于這些數(shù)據(jù)的統(tǒng)計(jì)并非實(shí)時(shí)的秤涩,不是簡(jiǎn)單的對(duì)于數(shù)據(jù)庫(kù)的某個(gè)字段數(shù)據(jù)量 +1 這么簡(jiǎn)單帜乞,超大的流量洪峰下并不能因?yàn)榻y(tǒng)計(jì)數(shù)據(jù)將業(yè)務(wù)主流程阻塞。所以通常會(huì)將這些數(shù)據(jù)記錄在文件或大數(shù)據(jù)存儲(chǔ)引擎中筐眷,然后周期性的進(jìn)行統(tǒng)計(jì)分析黎烈。

Kafka 被越來(lái)越多的公司青睞主要和他的特性?xún)?yōu)勢(shì)有關(guān):

  • 以 O(1) 時(shí)間復(fù)雜度消息持久化,對(duì)于 TB 級(jí)別的數(shù)據(jù)也能夠保證 O(1) 的訪問(wèn)效率
  • 支持批量 寫(xiě) 數(shù)據(jù)匀谣,并且對(duì)于數(shù)據(jù)進(jìn)行壓縮保證高吞吐
  • 支持消息分區(qū)照棋,分布式發(fā)送,分布式消費(fèi)武翎,便于水平擴(kuò)展 (Scale out)烈炭,具有很高的并發(fā)能力

應(yīng)用場(chǎng)景

那為何需要使用消息隊(duì)列,或者說(shuō)在什么場(chǎng)景下 Kafka 更加合適

解耦

在大數(shù)據(jù)宝恶,高并發(fā)的場(chǎng)景下為了突破性能瓶頸會(huì)對(duì)系統(tǒng)進(jìn)行水平擴(kuò)展和垂直拆分符隙,將一個(gè)復(fù)雜的系統(tǒng)拆分多個(gè)獨(dú)立,純凈的子系統(tǒng)垫毙。數(shù)據(jù)在各個(gè)系統(tǒng)之間流轉(zhuǎn)霹疫,但是如果某一個(gè)服務(wù)處理速度過(guò)慢,就會(huì)拖累整個(gè)鏈路的性能综芥,形成瓶頸降低整個(gè)系統(tǒng)的性能丽蝎,造成“旱的旱死澇的澇死”的局面。

舉個(gè)簡(jiǎn)單例子:在淘寶下單時(shí)膀藐,交易系統(tǒng)完成扣款屠阻,后續(xù)會(huì)有很多動(dòng)作:提醒賣(mài)家發(fā)貨,生成賣(mài)家工作流额各,核銷(xiāo)優(yōu)惠券国觉,增加購(gòu)物積分等等,如果這一步全部寫(xiě)到交易系統(tǒng)的扣款代碼之后虾啦,很有可能交易系統(tǒng)就會(huì)被拖死蛉加,下游任何一個(gè)環(huán)節(jié)失敗也會(huì)導(dǎo)致扣款回滾蚜枢,并且如果需要添加一個(gè)新的動(dòng)作需要交易去做大量修改,設(shè)計(jì)肯定是不合理的针饥。實(shí)際上交易系統(tǒng)在處理完扣款后會(huì)發(fā)送一個(gè)扣款完成消息厂抽,下游接這個(gè)消息即可,下游失敗不會(huì)影響核心流程失敗丁眼,并且各個(gè)系統(tǒng)的邊界更加清楚筷凤,分層更更加合理。

數(shù)據(jù)持久化

如今的應(yīng)用程序基本都會(huì)涉及到多個(gè)系統(tǒng)之間的對(duì)接苞七,數(shù)據(jù)在系統(tǒng)之間通過(guò) RPC 進(jìn)行傳遞藐守,處理數(shù)據(jù)的過(guò)程失敗就會(huì)導(dǎo)致數(shù)據(jù)丟失,除非數(shù)據(jù)被持久化到磁盤(pán)上蹂风。而 Kafka 將所有需要流轉(zhuǎn)的數(shù)據(jù)都 持久化到磁盤(pán)上 卢厂,保證數(shù)據(jù)不會(huì)丟失。另外還有一個(gè)很重要的能力就是保留現(xiàn)場(chǎng)便于后續(xù)問(wèn)題排查跟蹤惠啄,經(jīng)歷過(guò)系統(tǒng)失敗但是無(wú)法復(fù)現(xiàn)的人才會(huì)體會(huì)到的痛慎恒!

為了保證磁盤(pán)上的數(shù)據(jù)不會(huì)爆炸式瘋漲,Kafka 提供了數(shù)據(jù)清理撵渡,數(shù)據(jù)壓縮等功能融柬,清除處理完成的歷史數(shù)據(jù)。

擴(kuò)展性

在應(yīng)用的訪問(wèn)量劇增的情況下趋距,代碼優(yōu)化往往沒(méi)有直接進(jìn)行水平擴(kuò)展來(lái)的那么及時(shí)粒氧。診斷,分析节腐,方案外盯,優(yōu)化,驗(yàn)證 一系列復(fù)雜流程讓代碼優(yōu)化看起來(lái)只能是一個(gè)從長(zhǎng)計(jì)議的方案翼雀。這時(shí)止血的方案只能是降級(jí)饱苟,限流,擴(kuò)機(jī)器 三板斧锅纺。Kafka 的擴(kuò)展性主要就體現(xiàn)在能熱擴(kuò)容,不需要修改參數(shù)肋殴,不需要修改代碼囤锉,上機(jī)器 -> 注冊(cè)服務(wù) 就完成了擴(kuò)容。并非所有系統(tǒng)都具備這個(gè)像 調(diào)節(jié)音量旋鈕一樣簡(jiǎn)單的提高系統(tǒng)性能 的能力 护锤,這里會(huì)涉及到擴(kuò)容之前的數(shù)據(jù)是否會(huì)有熱點(diǎn)官地,新節(jié)點(diǎn)對(duì)集群的同步,流量重分配等等一系列復(fù)雜流程烙懦。

容災(zāi)

系統(tǒng)的部分組件失敗不會(huì)影響這個(gè)系統(tǒng)的運(yùn)行驱入,消息隊(duì)列降低了進(jìn)程間的耦合度,上游或者下游服務(wù)掛掉后不會(huì)影響其他系統(tǒng)的運(yùn)行,在服務(wù)重新在線后能夠繼續(xù)處理之前未處理的數(shù)據(jù)亏较,只是會(huì)存在一定的延時(shí)但是能夠保證 最終業(yè)務(wù)正確性 莺褒。

保序

強(qiáng)哥:你這瓜保熟嗎?哦不雪情,你這隊(duì)列保序嗎遵岩?
在大多數(shù)場(chǎng)景下,數(shù)據(jù)處理順序是至關(guān)重要的巡通,順序錯(cuò)亂很可能導(dǎo)致數(shù)據(jù)結(jié)果錯(cuò)誤尘执。除非這個(gè)處理過(guò)程是無(wú)狀態(tài)的,此時(shí)消息只是起到事件觸發(fā)的作用宴凉,觸發(fā)下游進(jìn)行計(jì)算誊锭。Kafka 可以保證分區(qū)內(nèi)部有序而不能保證全局有序。

核心概念

架構(gòu)圖

image.png
image.png

上圖是一個(gè)典型的 Kafka 架構(gòu)圖弥锄,左邊為消息生產(chǎn)者(Producer) 丧靡,發(fā)送消息到一個(gè)特定的主題(Topic),由于 Kafka 的分布式設(shè)計(jì)每個(gè) Topic 被分成多個(gè)分區(qū)叉讥,因此發(fā)送到每個(gè) Topic 的消息會(huì)被存儲(chǔ)到對(duì)應(yīng)的分區(qū)窘行。另外如果 Topic 設(shè)置了副本,則每個(gè)分區(qū)都會(huì)有對(duì)應(yīng)的副本图仓。這些 Topic 被不同的消費(fèi)者(Consumer)訂閱罐盔,如果兩個(gè)消費(fèi)者在同一個(gè)消費(fèi)者組,那么里面的消費(fèi)者只能訂閱一個(gè)固定的分區(qū)救崔。

用上圖的 Topic A 舉例惶看, Producer 1 發(fā)送消息到 Topic-A ,消息會(huì)在存放在 Broker-2 和 Broker-3 的兩個(gè)分區(qū)上六孵,并且由于 Topic-A 開(kāi)啟了分區(qū)備份纬黎,所以每個(gè)分區(qū)都會(huì)由另外一個(gè)節(jié)點(diǎn) Topic-A' 備份分區(qū)數(shù)據(jù) 。發(fā)送到 Broker 的數(shù)據(jù)會(huì)被消費(fèi)者訂閱劫窒,由于 Consumer-1 和 Consumer-2 在同一個(gè)消費(fèi)者組中本今,他們只能消費(fèi)一個(gè)固定分區(qū)的消息, Consumer-1 只會(huì)接收到 Topic-A Partition-1 的消息,Consumer-2 只會(huì)接收到 Topic-A Partition-0 的消息主巍。

Broker

在 Kafka 集群中的一個(gè) Kafka Server 就是一個(gè) Broker 冠息,生產(chǎn)者將消息投遞到 Broker ,Broker 保證消息的 持久化孕索,容災(zāi)逛艰,準(zhǔn)確性等。同時(shí)接受消費(fèi)者的消息訂閱搞旭,向消費(fèi)者分發(fā)消息散怖。一般來(lái)說(shuō)在生產(chǎn)環(huán)境一臺(tái) Kafka 服務(wù)器就是一個(gè) Broker菇绵。

Topic & Partition & Log

Topic 可以認(rèn)為是用來(lái)存儲(chǔ)消息的邏輯概念,可簡(jiǎn)單認(rèn)為他是一個(gè) 信箱 镇眷。每條消息發(fā)送的時(shí)候都需要指定需要發(fā)送到哪個(gè) Topic 咬最,消息被消費(fèi)的時(shí)候也需要指定消費(fèi)哪個(gè) Topic 中的消息。

Kafka 為了提高可擴(kuò)展性以及吞吐量偏灿,Topic 被分成多個(gè)分區(qū) (Partition) 丹诀,每個(gè) Partition 對(duì)應(yīng)一個(gè) Log,Log 是一個(gè)邏輯概念翁垂, 它會(huì)對(duì)應(yīng)服務(wù)器上一個(gè)文件夾铆遭,這個(gè)文件夾下存放的是這個(gè) Partition 下所有的消息數(shù)據(jù)和消息索引 。在面對(duì)海量數(shù)據(jù)的時(shí)候沿猜,為了避免出現(xiàn)巨大文件出現(xiàn) I/O 瓶頸枚荣,Kafka 又將 Log 分為多個(gè) Segment 。每個(gè) Segment 包含 log 文件index 文件 文件命名是以該 Segment 第一條消息的 offset 命名啼肩。這樣說(shuō)下來(lái)其實(shí)還是很繞的直接看下面的架構(gòu)圖橄妆,可以仔細(xì)留意一下各個(gè)部分的標(biāo)識(shí)和數(shù)字再結(jié)合這段文字,理解起來(lái)應(yīng)該就很輕松了祈坠。

另外因?yàn)?Kafka 采用順序 I/O害碾,順序 I/O 效率非常高,甚至比隨機(jī)寫(xiě)內(nèi)存效率更高赦拘,這也是 Kafka 高性能的原因之一慌随。
image.png
image.png

Replication

在生產(chǎn)環(huán)境中,我們一般會(huì)開(kāi)啟 Kafka 消息冗余特性躺同,每個(gè) Partition 都有 1 個(gè)或多個(gè)副本阁猜,我們稱(chēng)之為 Replication。當(dāng)分區(qū)只有一個(gè)副本的時(shí)候蹋艺,該分區(qū)數(shù)據(jù)只保留了一份剃袍。每個(gè)分區(qū)副本都會(huì)選出一個(gè) Leader , Leader 是所有讀寫(xiě)請(qǐng)求的 “接口人” 捎谨,其余副本均為 Follower 民效。Follower 作用有兩個(gè):拉取 Leader 的 Log 數(shù)據(jù)做 備份 ,在 Leader 失敗后作為候選人 參與 Leader 選舉 涛救。

Producer

消息產(chǎn)出的源頭畏邢,通過(guò)一定的策略推送到 Topic 的各個(gè)分區(qū) 。這里所說(shuō)的推送策略就是消息路由機(jī)制州叠,Kafka 內(nèi)置多種策略可選例如:按照消息 Key 棵红,輪訓(xùn)等等凶赁,甚至用戶(hù)可以寫(xiě)擴(kuò)展代碼來(lái)自定義路由策略咧栗。

Consumer & Consumer Group

消費(fèi)者(Consumer) 主要工作是從 Broker 拉取消息逆甜,進(jìn)行消費(fèi)處理。每個(gè)消費(fèi)者維護(hù)自己的消費(fèi)進(jìn)度致板,這樣的設(shè)計(jì)有諸多好處交煞,比如:每個(gè)消費(fèi)者進(jìn)度能夠輕松的進(jìn)行區(qū)分,并且可以修改單個(gè)消費(fèi)者的消費(fèi)位點(diǎn)跳過(guò)或者重新消費(fèi)某些消息斟或,避免了位點(diǎn)信息的集中化管理的單點(diǎn)故障問(wèn)題素征。

現(xiàn)在的應(yīng)用程序大部分為分布式的系統(tǒng),一個(gè)應(yīng)用有幾十臺(tái)上百臺(tái)服務(wù)器萝挤,這些服務(wù)器上運(yùn)行著相同的代碼御毅,那么一個(gè)消息過(guò)來(lái),每臺(tái)服務(wù)器都執(zhí)行一次消費(fèi)邏輯怜珍,豈不是會(huì)造成巨大的問(wèn)題端蛆。

所以 Kafka 引入了一個(gè)新的概念: 消費(fèi)者組(Consumer Group) 。我們可以將這些應(yīng)用的服務(wù)器都放到同一個(gè)消費(fèi)者組中酥泛,而 Kafka 規(guī)定一條消息只能被同一個(gè)消費(fèi)者組中的一個(gè)消費(fèi)者消費(fèi)今豆,這樣就能完美避免分布式情況下的重復(fù)消費(fèi)問(wèn)題了。上面所說(shuō)的情況簡(jiǎn)單來(lái)說(shuō)是希望實(shí)現(xiàn)消息被某臺(tái)服務(wù)器獨(dú)占柔袁,也就是 單播 問(wèn)題呆躲。假如我們希望這條消息被廣播出去,每臺(tái)收到這個(gè)消息的服務(wù)器都做處理捶索,例如發(fā)消息做日志清理插掂,這種情況稱(chēng)為 廣播 , 那我們只需要將每個(gè)消費(fèi)者放到不同的消費(fèi)者組即可。

Kafka 引入消費(fèi)者組的概念巧妙解決了單播和廣播問(wèn)題情组,而沒(méi)有區(qū)分訂閱類(lèi)型燥筷,通過(guò)一種邏輯概念來(lái)屏蔽掉多種訂閱實(shí)現(xiàn)。

另外在同一個(gè)消費(fèi)者組中的消費(fèi)者訂閱的分區(qū)是確定的院崇,只有在消費(fèi)者組中的消費(fèi)者有變化的時(shí)候才會(huì)進(jìn)行重分配肆氓。例如我們有四個(gè)分區(qū),三個(gè)消費(fèi)者底瓣,就會(huì)出現(xiàn)一個(gè)消費(fèi)者訂閱兩個(gè)分區(qū)的情況谢揪。而三個(gè)分區(qū)四個(gè)消費(fèi)者就會(huì)出現(xiàn)有消費(fèi)者處于空閑狀態(tài),造成浪費(fèi)捐凭,所以一般消費(fèi)者的數(shù)量盡量不要大于 Topic 的分區(qū)數(shù)拨扶。
image.png
image.png

尾聲(嘮叨)

這是我 2021 年的第一篇博客,年底做回顧的時(shí)候才知道去年我過(guò)的究竟有多么糟糕茁肠。既沒(méi)有輸入也沒(méi)有輸出患民,雖然工作進(jìn)入一個(gè)新的階段,會(huì)越來(lái)越忙垦梆,但忙不是拒絕成長(zhǎng)的借口匹颤,必須保證每月一到兩本書(shū)的輸入仅孩,一到兩周輸出一篇優(yōu)質(zhì)文章。 最長(zhǎng)的路屬于一顆孤獨(dú)的心印蓖,與君共勉

下期我會(huì)從整體梳理 Kafka 生產(chǎn)者辽慕,包括消息發(fā)送客戶(hù)端,發(fā)送端數(shù)據(jù)緩存從源碼角度看看其中的設(shè)計(jì)模式赦肃,代碼組織技巧溅蛉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市他宛,隨后出現(xiàn)的幾起案子船侧,更是在濱河造成了極大的恐慌,老刑警劉巖厅各,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勺爱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡讯检,警方通過(guò)查閱死者的電腦和手機(jī)琐鲁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)人灼,“玉大人围段,你說(shuō)我怎么就攤上這事⊥斗牛” “怎么了奈泪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)灸芳。 經(jīng)常有香客問(wèn)我涝桅,道長(zhǎng),這世上最難降的妖魔是什么烙样? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任冯遂,我火速辦了婚禮,結(jié)果婚禮上谒获,老公的妹妹穿的比我還像新娘蛤肌。我一直安慰自己,他們只是感情好批狱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布裸准。 她就那樣靜靜地躺著,像睡著了一般赔硫。 火紅的嫁衣襯著肌膚如雪炒俱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音权悟,去河邊找鬼恼蓬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛僵芹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播小槐,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼拇派,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了凿跳?” 一聲冷哼從身側(cè)響起件豌,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎控嗜,沒(méi)想到半個(gè)月后茧彤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疆栏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年曾掂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壁顶。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡珠洗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出若专,到底是詐尸還是另有隱情许蓖,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布调衰,位于F島的核電站膊爪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嚎莉。R本人自食惡果不足惜米酬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望趋箩。 院中可真熱鬧淮逻,春花似錦、人聲如沸阁簸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)启妹。三九已至筛严,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饶米,已是汗流浹背桨啃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工车胡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人照瘾。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓匈棘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親析命。 傳聞我的和親對(duì)象是個(gè)殘疾皇子主卫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容