30分鐘帶你了解「消息中間件」Kafka比然、RocketMQ

消息中間件的應(yīng)用場(chǎng)景

  • 異步解耦
  • 削峰填谷
  • 順序收發(fā)
  • 分布式事務(wù)一致性

騰訊應(yīng)用案例:

主流 MQ 框架及對(duì)比

說明

  • Kafka:整個(gè)行業(yè)應(yīng)用廣泛
  • RocketMQ:阿里,從 apache 孵化
  • Pulsar:雅虎開源栈妆,符合云原生架構(gòu)的消息隊(duì)列胁编,社區(qū)活躍
  • RabbitMQ 架構(gòu)比較老,AMQP并沒有在主流的 MQ 得到支持
  • NSQ:內(nèi)存型鳞尔,不是最優(yōu)選擇
  • ActiveMQ嬉橙、ZeroMQ 可忽略

Kafka 優(yōu)點(diǎn)

  • 非常成熟,生態(tài)豐富寥假,與 Hadoop 連接緊密
  • 吞吐非常高市框,可用性高
    • sharding
    • 提升 replication 速度
  • 主要功能:pub-sub,壓縮支持良好
  • 可按照 at least once, at most once 進(jìn)行配置使用糕韧,exactly once 需要 Consumer 配合
  • 集群部署簡(jiǎn)單枫振,但 controller 邏輯很復(fù)雜喻圃,實(shí)現(xiàn)partition 的多副本、數(shù)據(jù)一致性
  • controller 依賴 ZooKeeper
  • 異步刷磁盤(除了錢的業(yè)務(wù)粪滤,很少有同步 flush 的需求)

Kafka 缺點(diǎn)

  • 寫入延時(shí)穩(wěn)定性問題斧拍,partition 很多時(shí)
    • Kafka 通常用機(jī)械盤,隨機(jī)寫造成吞吐下降和延時(shí)上升
    • 100ms ~ 500ms
  • 運(yùn)維的復(fù)雜性
    • 單機(jī)故障后補(bǔ)充副本
    • 數(shù)據(jù)遷移
    • 快手的優(yōu)化:遷移 partition 時(shí)舊數(shù)據(jù)不動(dòng)杖小,新數(shù)據(jù)寫入新 partition 一定時(shí)間后直接切換

RocketMQ

  • 阿里根據(jù) Kafka 改造適應(yīng)電商等在線業(yè)務(wù)場(chǎng)景
  • 以犧牲性能為代價(jià)增強(qiáng)功能
    • 按 key 對(duì)消息查詢饮焦,維護(hù) hash 表,影響 io
    • 為了在多 shard 場(chǎng)景下保證寫入延遲穩(wěn)定窍侧,在 broker 級(jí)別將所有 shard 當(dāng)前寫入的數(shù)據(jù)放入一個(gè)文件,形成 commitlog list转绷,放若干個(gè) index 文件維護(hù)邏輯 topic 信息伟件,造成更多的隨機(jī)讀
  • 沒有中心管理節(jié)點(diǎn),現(xiàn)在看起來并沒有什么用议经,元數(shù)據(jù)并不多
  • 高精度的延遲消息(快手已支持秒級(jí)精度的延遲消息)

Pulsar

  • 存儲(chǔ)斧账、計(jì)算分離,方便擴(kuò)容
    • 存儲(chǔ):bookkeeper
    • MQ邏輯:無狀態(tài)的 broker 處理

發(fā)展趨勢(shì)

  • 云原生
  • 批流一體:跑任務(wù)時(shí)煞肾,需要先把 Kafka 數(shù)據(jù)→HDFS咧织,資源消耗大。如果本來就存在 HDFS籍救,能節(jié)省很大資源
  • Serverless

各公司發(fā)展

  • 快手:Kafka
    • 所有場(chǎng)景均在使用
    • 特殊形態(tài)的讀寫分離
      • 數(shù)據(jù)實(shí)時(shí)消費(fèi)到 HDFS
      • 在有明顯 lag 的 consumer 讀取時(shí)习绢,broker 把請(qǐng)求從本地磁盤轉(zhuǎn)發(fā)的 HDFS
      • 不會(huì)因?yàn)橛?lag 的 consumer 對(duì)日常讀寫造成明顯的磁盤隨機(jī)讀寫
    • 由于自己改造,社區(qū)新功能引入困難
  • 阿里巴巴:開源 RocketMQ
  • 字節(jié)跳動(dòng)
    • 在線場(chǎng)景:NSQ→RocketMQ
    • 離線場(chǎng)景:Kafka→自研的存儲(chǔ)計(jì)算分類的 BMQ(協(xié)議層直接兼容Kafka蝙昙,用戶可以不換 client)
  • 百度:自研的 BigPipe闪萄,不怎么樣
  • 美團(tuán):Kafka 架構(gòu)基礎(chǔ)上用 Java 進(jìn)行重構(gòu),內(nèi)部叫 Mafka
  • 騰訊:部分使用了自研的 PhxQueue奇颠,底層是 KV 系統(tǒng)
  • 滴滴:DDMQ
    • 對(duì) RocketMQ 和 Kafka 進(jìn)行封裝
    • 多機(jī)房數(shù)據(jù)一致性可能有問題
  • 小米:自研 Talos
    • 架構(gòu)類似 pulsar败去,存儲(chǔ)是 HDFS,讀場(chǎng)景有優(yōu)化

Kafka

Kafka 是什么烈拒?

  • 開源的消息引擎系統(tǒng)(消息隊(duì)列/消息中間件)
  • 分布式流處理平臺(tái)
  • 發(fā)布/訂閱模型
  • 削峰填谷

Kafka 術(shù)語

  • Topic:發(fā)布訂閱的主題
  • Producer:向Topic發(fā)布消息的客戶端
  • Consumer:消費(fèi)者
  • Consumer Group:消費(fèi)者組圆裕,多個(gè)消費(fèi)者共同組成一個(gè)組
  • Broker:Kafka的服務(wù)進(jìn)程
  • Replication:備份,相同數(shù)據(jù)拷貝到多臺(tái)機(jī)器
    • Leader Replica
    • Follower Replica荆几,不與外界交互
  • Partition:分區(qū)吓妆,解決伸縮性問題,多個(gè)Partition組成一個(gè)Topic
  • Segment:partition 由多個(gè) segment 組成

Kafka 如何持久化伴郁?

  • 消息日志(Log)保存數(shù)據(jù)耿战,磁盤追加寫(Append-only)
    • 避免緩慢的隨機(jī)I/O操作
    • 高吞吐
  • 定期刪除消息(日志段)

Kafka 文件存儲(chǔ)機(jī)制

https://www.open-open.com/lib/view/open1421150566328.html

  • 每個(gè) partition 相當(dāng)于一個(gè)巨型文件→多個(gè)大小相等 segment 數(shù)據(jù)文件中
  • 每個(gè) partition 只需要順序讀寫就行了,segment 文件生命周期由配置決定
  • segment file 組成:
    • index file:索引文件
    • data file:數(shù)據(jù)文件
  • segment file 文件命名規(guī)則:
    • 全局第一個(gè) segment 是 0
    • 后序每個(gè)加上全局 partition 的最大 offset

一對(duì) segment file

message 物理結(jié)構(gòu)

分區(qū)

為什么分區(qū)焊傅?

  • Kafka的消息組織方式:主題-分區(qū)-消息
  • 一條消息剂陡,僅存在某一個(gè)分區(qū)中
  • 提高伸縮性狈涮,不同分區(qū)可以放到不同機(jī)器,讀寫操作也是以分區(qū)粒度

分區(qū)策略鸭栖?

  • 輪詢
  • 隨機(jī)
  • 按 key 保序歌馍,單分區(qū)有序

Kafka 是否會(huì)消息丟失?

  • 只對(duì)“已提交”的消息做有限度的持久化保證
    • 已提交的消息:消息寫入日志文件
    • 有限度的持久化保證:N個(gè) broker 至少一個(gè)存活
  • 生產(chǎn)者丟失數(shù)據(jù)
    • producer.send(msg) 異步發(fā)送消息晕鹊,不保證數(shù)據(jù)到達(dá)Kafka
    • producer.send(msg, callback) 判斷回調(diào)
  • 消費(fèi)者程序丟失數(shù)據(jù)
    • 應(yīng)該「先消費(fèi)消息松却,后更新位移的順序」
    • 新問題:消息的重復(fù)處理
    • 多線程異步處理消息,Consumer不要開啟自動(dòng)提交位移溅话,應(yīng)用程序手動(dòng)提交位移

控制器

  • 在 ZooKeeper幫助下管理和協(xié)調(diào)整個(gè) Kafka 集群
  • 運(yùn)行過程中晓锻,只能有一個(gè) Broker 成為控制器

控制器如何選舉?

在 ZooKeeper 創(chuàng)建 /controller 節(jié)點(diǎn)飞几,第一個(gè)創(chuàng)建成功的 Broker 被指定為控制器砚哆。

控制器有什么用?

  • 主題管理(創(chuàng)建屑墨、刪除躁锁、增加分區(qū))
  • 分區(qū)重分配
  • 領(lǐng)導(dǎo)者選舉
  • 集群成員管理(新增 Broker、Broker 主動(dòng)關(guān)閉卵史、Broker 宕機(jī))(ZooKeeper 臨時(shí)節(jié)點(diǎn))
  • 數(shù)據(jù)服務(wù):最全的集群元數(shù)據(jù)信息

控制器故障轉(zhuǎn)移

  • 只有一個(gè) Broker 當(dāng)控制器战转,單點(diǎn)失效,立即啟用備用控制器

Kafka 的 ZooKeeper 存儲(chǔ)結(jié)構(gòu)

分布式事務(wù)的應(yīng)用場(chǎng)景

  • 團(tuán)隊(duì)內(nèi)部以躯,某些操作要同時(shí)更新多個(gè)數(shù)據(jù)源
  • 業(yè)務(wù)團(tuán)隊(duì) A 完成某個(gè)操作后槐秧,B 業(yè)務(wù)的某個(gè)操作也必須完成,A 業(yè)務(wù)并不能直接訪問 B 的數(shù)據(jù)庫
  • 公司之間寸潦,用戶付款后色鸳,支付系統(tǒng)(支付寶/微信)必須通知商家的系統(tǒng)更新訂單狀態(tài)

兩階段最終一致

  • 先完成數(shù)據(jù)源 A 的事務(wù)(一階段)
  • 成功后通過某種機(jī)制,保證數(shù)據(jù)源 B 的事務(wù)(二階段)也一定最終完成
    • 不成功见转,會(huì)不斷重試直到成功為止
    • 或達(dá)到一定重試次數(shù)后停止(配合對(duì)賬命雀、人工處理)

如何保證最終一致?

為了保證最終一致斩箫,消息系統(tǒng)和業(yè)務(wù)程序需要保證:

  • 消息發(fā)送的一致性:消息發(fā)送時(shí)吏砂,一階段事務(wù)和消息發(fā)送必須同時(shí)成功或失敗
  • 消息存儲(chǔ)不丟失:消息發(fā)送成功后,到消息被成功消費(fèi)前乘客,消息服務(wù)器(broker)必須存儲(chǔ)好消息狐血,保證發(fā)生故障時(shí),消息不丟失
  • 消費(fèi)者不丟失消息:處理失敗不丟棄易核,重試直到成功為止

消息發(fā)送的一致性如何保證匈织?

目標(biāo):本地事務(wù)、消息發(fā)送必須同時(shí)成功/失敗

問題

  • 先執(zhí)行本地事務(wù),再發(fā)送消息缀匕,消息可能發(fā)送失敗
  • 可把失敗的消息放入內(nèi)存纳决,稍后重試,但成功率也無法達(dá)到 100%

解決方案`* 先發(fā)送半消息(Half Msg乡小,類似 Prepare 操作)阔加,不會(huì)投遞給消費(fèi)者

  • 半消息發(fā)送成功,再執(zhí)行 DB 操作
  • DB 操作執(zhí)行成功后满钟,提交半消息

發(fā)送異常會(huì)如何胜榔?

  • 1 異常,半消息發(fā)送失敗湃番,本地 DB 沒有執(zhí)行夭织,整個(gè)操作失敗,DB/消息的狀態(tài)一致(都沒有提交)
  • 2 異常/超時(shí)
    • 生產(chǎn)者以為失敗了吠撮,不執(zhí)行 DB
    • broker 存儲(chǔ)半消息成功摔癣,等不到后序操作,會(huì)詢問生產(chǎn)者是提交還是回滾(第6步)
  • 3 DB操作失斘诚颉:生產(chǎn)者在第 4 步告知 broker 回滾半消息
  • 4 提交/回滾半消息失敗:broker 等不到這個(gè)操作戴卜,觸發(fā)回查(第 6 步)
  • 5逾条、6、7回查失斖栋:RocketMQ 最多回查 15 次

代碼师脂、思維導(dǎo)圖筆記下載

代碼和思維導(dǎo)圖在 GitHub 項(xiàng)目中,歡迎大家 star江锨!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吃警,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子啄育,更是在濱河造成了極大的恐慌酌心,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑豌,死亡現(xiàn)場(chǎng)離奇詭異安券,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氓英,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門侯勉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人铝阐,你說我怎么就攤上這事址貌。” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵练对,是天一觀的道長遍蟋。 經(jīng)常有香客問我,道長锹淌,這世上最難降的妖魔是什么匿值? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赂摆,結(jié)果婚禮上挟憔,老公的妹妹穿的比我還像新娘。我一直安慰自己烟号,他們只是感情好绊谭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汪拥,像睡著了一般达传。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上迫筑,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天宪赶,我揣著相機(jī)與錄音,去河邊找鬼脯燃。 笑死搂妻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辕棚。 我是一名探鬼主播欲主,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼逝嚎!你這毒婦竟也來了扁瓢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤补君,失蹤者是張志新(化名)和其女友劉穎引几,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽铁,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡她紫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屿储。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贿讹。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖够掠,靈堂內(nèi)的尸體忽然破棺而出民褂,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布赊堪,位于F島的核電站面殖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏哭廉。R本人自食惡果不足惜脊僚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遵绰。 院中可真熱鬧辽幌,春花似錦、人聲如沸椿访。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽成玫。三九已至加酵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哭当,已是汗流浹背猪腕。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钦勘,地道東北人码撰。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像个盆,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朵栖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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