【八股消消樂】消息隊列優化—消息有序

在這里插入圖片描述

😊你好,我是小航,一個正在變禿、變強的文藝傾年。
🔔本專欄《八股消消樂》旨在記錄個人所背的八股文,包括Java/Go開發、Vue開發、系統架構、大模型開發、具身智能、機器學習、深度學習、力扣算法等相關知識點,期待與你一同探索、學習、進步,一起卷起來叭!

目錄

  • 題目
  • 答案
    • Kafka 消息分區
    • 有序消息
    • 跨topic的有序消息
    • 簡歷優化
      • 單分區
      • 異步消費
      • 多分區
        • 數據不均勻
          • 槽與槽分配
          • 一致性哈希
        • 消息失序

題目

💬技術棧:RocketMQ、Kafka、RabbitMQ

🔍簡歷內容:熟悉Kafka消息分區。為解決Kafka線上消息積壓、broker性能抖動問題,針對業務內有序為topic實現了多分區。參考Redis槽與槽分配機制解決了數據不均勻問題。針對分區擴容采用了停頓方案解決消息失序問題。

🚩面試問:你覺得在多分區方案里面,如果某個分區消息積壓了就啟用異步消費,這種解決思路你覺得怎么樣?


在這里插入圖片描述

💡建議暫停思考10s,你有答案了嘛?如果你有不同題解,歡迎評論區留言、打卡。


答案

Kafka 消息分區

在 Kafka 中,消息是以分區為單位進行存儲的。每個 topic 都可以被劃分為一個或多個分區,每個分區都是一個 有序、不可變 的消息日志。Kafka 使用 WAL (write-ahead-log)日志來存儲消息。每個分區都有一個對應的日志文件,新的消息會被追加到文件的末尾,而已經加入日志里的消息,就不會再被修改了。

在這里插入圖片描述

每個消息在分區日志里都有一個唯一的偏移量(offset),用來標識消息在分區里的位置。 Kafka 保證同一分區內的消息順序,但不保證不同分區之間的順序。而 Kafka 本身暴露了對應的接口,也就是說你可以顯式地指定消息要發送到哪個分區,也可以顯式地指定消費哪個分區的數據。

有序消息

有序消息:消費者消費某個 topic 消息的順序,和生產者生產消息的順序一模一樣。

生產者生產消息的順序,不是指你創建出來消息那個實例的先后順序,而是指broker收到的順序。
在這里插入圖片描述

跨topic的有序消息

問題:保證不同topic之間消息是有序的。比如說 msg1 先發送到了 topic_a 上, msg2 被發送到了 topic_b 上。但是在業務層面上,要求 msg1 一定要先于 msg2 消費

解決方案:引入一個協調者,這個協調者負責把消息重組為有序消息。比如說,如果 msg2 先到了,但是 msg1 還沒出來,那么這個協調者要有辦法讓 msg2 的消費者 B 停下來,暫時不消費 msg2。而在 msg1 來了之后,喚醒消費者 A 消費 msg1,并且在消費完 msg1 之后要再喚醒消費者 B 處理 msg2。

簡歷優化

前置準備:

  • 在什么業務場景下,你需要用到有序消息?
  • 你是如何解決有序消息這個問題的?用的是哪種方案?
  • 如果你用的是單分區解決方案,那么有沒有消息積壓問題?如果有,你是怎么解決的?
  • 如果你用的是多分區解決方案,那么有沒有分區負載不均衡的問題?如果有,你是怎么解決的?

單分區

解決方案:為了保證消息有序,讓特定的 topic 只有一個分區。這樣所有的消息都發到同一個分區上,那么自然就是有序的。

存在的問題: 性能差、消息積壓。

  • 生產端:所有的消息都在一個分區上,也同時意味著所有的消息都發送到了同一個broker上,這個服務器很可能撐不住壓力;
  • 消費端:只有一個分區,那么就只能有一個消費者消費,很容易出現消息積壓的問題。

在這里插入圖片描述

全局有序:沒什么優化手段,只能是換用更加強大的機器。
業務內有序:比如說在下單的場景下,會產生創建訂單消息和完成支付消息。業務上只會要求同一個訂單的創建訂單消息應該優先于完成支付消息,但是不會要求訂單 A 的創建消息需要先于訂單 B 的支付消息。這種解決方案參考下面的異步消費、多分區方案。

異步消費

問題:單分區方案中,由于只有一個消費者,容易造成消息積壓。

解決方案:保證同一個業務內的順序。當消費者從隊列取出來消息之后,把同一個業務的消息丟到同一個隊列里。

在這里插入圖片描述
消費者線程從 Kafka 里獲取消息,然后轉發到內存隊列里面。在轉發的時候,要把同一個業務的消息轉發到同一個隊列里面。一般來說可以根據業務特征字段計算一個哈希值,比如說直接使用業務 id 作為哈希值。利用這個哈希值除以工作線程數量,然后取余數,得到對應的內存隊列

存在的問題:可能存在消息未消費。消費線程取出來了,轉發到隊列之后,工作線程還沒來得及處理,消費者整體就宕機了,那么這些消息就存在丟失的可能。

多分區

將上面方案的內存隊列換成了多個分區。原本同一個業務的消息發送到同一個分區。

保證同一個業務的消息必然發送到同一個分區:生產者在發送消息的時候,根據業務特征,比如說業務 ID 計算出目標分區,在發送的時候顯式地指定分區就可以了。

在這里插入圖片描述

引發的問題:數據不均勻、增加分區可能導致消息失序。

數據不均勻

問題:數據不均勻一般是業務造成的。在我們的方案里面,分區是根據業務特征來選擇的,那么自然有一些分區有很多數據,有一些分區數據很少。比如說萬一我們不小心把熱點用戶的消息都發到了同一個分區里面,那么這個分區的 QPS 就會很高,消費者也不一定來得及消費,就可能引起消息積壓。

在這里插入圖片描述

解決方案:Redis 中槽和槽分配的機制,又或者說一致性哈希算法。

槽與槽分配

借鑒 Redis 的槽與槽分配方案。不過 Redis 使用了 16384 個槽,一般的業務用不上那么多槽,所以可以考慮用 1024 個槽根據業務的特征來計算一個哈希值,再除以 1024 取余就可以得到所在的槽。再根據不同槽的數據多少,合理地把槽分配到不同的分區。最好把槽和分區的綁定關系做成動態的,也就是說我可以隨時調整槽到分區的映射關系,保證所有的分區負載都是均勻的。

在這里插入圖片描述

動態調整槽與分區的綁定:借助于配置中心來完成。比如說最開始你把槽 1 綁定到分區 2 上,后面在運行的時候你發現分區 2 數據太多,就把槽 1 重新綁定到了分區 3 上

一致性哈希

使用一致性哈希算法來篩選分區。首先要根據數據分布的整體情況,把分區分布在哈希環上,確保每一個分區上的數據分布大體上是均勻的。如果一部分哈希值上數據較多,就多插入幾個分區節點。然后根據業務特征計算一個哈希值,從哈希環上找到對應的分區

在這里插入圖片描述

消息失序

場景:如果中間有增加新的分區,那么就可能引起消息失序。比如說最開始 id 為 3 的訂單消息 msg1 發到分區 0 上,但是這時候很不幸分區 0 上積攢了很多消息,所以 msg1 遲遲得不到消費。緊接著我們擴容,增加了一個新的分區。如果這時候來了一個消息 msg2,那么它會被轉發到分區 3 上。分區 3 上面沒有積攢什么數據,所以消費者 3 直接就消費了這個消息。本來 msg1 應該先于 msg2 被消費。而增加分區之后 msg2 反而被先消費了。

解決方案:對于新加入的分區,可以暫停消費一段時間。如果我們估算 msg1 會在一分鐘內被消費,那么新加入的分區的消費者可以在三分鐘后再開始消費。那么大概率 msg1 就會先于 msg2 消費

不過這種等待的解決方式并不能解決根本問題,只能說是很大程度上緩解了問題。但是本身增加分區也是一個很不常見的操作,再疊加消息失序的概率也很低,所以我們也可以通過監控發現這種失序場景,然后再手工修復一下就可以了

簡歷總結:

最開始我進公司的時候就遇到了一個 Kafka 的線上故障。我司有一個業務需要用到有序消息,所以最開始的設計就是對應的 topic 只有一個分區,從而保證了消息有序。

可是隨著業務增長,一個分區很快就遇到了性能瓶頸。只有一個分區,也就意味著只有一個消費者,所以在業務增長之后,就開始出現了消息積壓。另外一方面,這個分區所在的broker的負載也明顯比其他服務器要大,偶爾也會有一些性能抖動的問題。

后來我仔細看了我們的業務,實際上,我們的業務要求的不是全局有序,而是業務內有序。

換句話來說,不一定非得用一個分區,而是可以考慮使用多個分區。所以我就給這個 topic 增加了幾個分區,同時也增加了消費者。優化完之后,到目前為止,還沒有出現過消息積壓的問題。

當然,為了避免在單分區增加到多分區的時候,出現消息失序的問題,我用了一個很簡單的方案,就是對應的消費者在啟動之后,并沒有立刻消費,而是停頓了三分鐘,從而避免了潛在的消息失序問題。


往期精彩專欄內容,歡迎訂閱:

🔗【八股消消樂】20250624:消息隊列優化—延遲消息
🔗【八股消消樂】20250623:消息隊列優化—系統架構設計
🔗【八股消消樂】20250622:Elasticsearch查詢優化
🔗【八股消消樂】20250620:Elasticsearch優化—檢索Labubu
🔗【八股消消樂】20250619:構建微服務架構體系—保證服務高可用
🔗【八股消消樂】20250615:構建微服務架構體系—鏈路超時控制
🔗【八股消消樂】20250614:構建微服務架構體系—實現制作庫與線上庫分離
🔗【八股消消樂】20250612:構建微服務架構體系—限流算法優化
🔗【八股消消樂】20250611:構建微服務架構體系—降級策略全總結
🔗【八股消消樂】20250610:構建微服務架構體系—熔斷恢復抖動優化
🔗【八股消消樂】20250609:構建微服務架構體系—負載均衡算法如何優化
🔗【八股消消樂】20250608:構建微服務架構體系—服務注冊與發現
🔗【八股消消樂】20250607:MySQL存儲引擎InnoDB知識點匯總
🔗【八股消消樂】20250606:MySQL參數優化大匯總
🔗【八股消消樂】20250605:端午節產生的消費數據,如何分表分庫?
🔗【八股消消樂】20250604:如何解決SQL線上死鎖事故
🔗【八股消消樂】20250603:索引失效與優化方法總結
🔗【八股消消樂】20250512:慢SQL優化手段總結
🔗【八股消消樂】20250511:項目中如何排查內存持續上升問題
🔗【八股消消樂】20250510:項目中如何優化JVM內存分配?
🔗【八股消消樂】20250509:你在項目中如何優化垃圾回收機制?
🔗【八股消消樂】20250508:Java編譯優化技術在項目中的應用
🔗【八股消消樂】20250507:你了解JVM內存模型嗎?
🔗【八股消消樂】20250506:你是如何設置線程池大小?
🔗【八股消消樂】20250430:十分鐘帶背Duubo中大廠經典面試題
🔗【八股消消樂】20250429:你是如何在項目場景中選取最優并發容器?
🔗【八股消消樂】20250428:你是項目中如何優化多線程上下文切換?
🔗【八股消消樂】20250427:發送請求有遇到服務不可用嗎?如何解決?

📌 [ 筆者 ]   文藝傾年
📃 [ 更新 ]   2025.6.25
? [ 勘誤 ]   /* 暫無 */
📜 [ 聲明 ]   由于作者水平有限,本文有錯誤和不準確之處在所難免,本人也很想知道這些錯誤,懇望讀者批評指正!

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86858.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86858.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86858.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2D寫實交互數字人如何重塑服務體驗?

在數字化浪潮席卷全球的當下,人機交互模式正經歷著前所未有的變革。從早期的文本命令行界面,到圖形用戶界面(GUI)的普及,再到如今語音交互、手勢識別等多模態交互技術的興起,我們與機器之間的溝通方式愈發自…

CI/CD GitHub Actions配置流程

騰訊云服務器寶塔FinalShellgithup 1.在云服務器上創建SSH秘鑰對,下載秘鑰到本地 2.在服務器中綁定秘鑰對(綁定后,服務器不能將不允許密碼登錄)綁定前先關機服務器,綁定后再開啟服務器 3.FinalShell改為公鑰登錄&am…

液態交互效果網頁開發--源自鴻蒙5以及iOS26的靈感

首先先來看看最終展示效果 當鼠標靠近“開始探索”的按鈕的時候,按鈕放大并有微弱光效 鼠標靠近之前會給視窗添加一層接近背景的朦朧感,當鼠標放在視窗上朦朧感消失 技術不復雜,這個網頁主要是使用了以下關鍵技術: HTML5 語義化標…

PYTHON從入門到實踐9-類和實例

# 【1】面向對象編程 class Student(object):# 可以幫屬性值綁定到對象上,self相當于JAVA的thisdef __init__(self, name, age):self.name nameself.age agedef speak(self):print(self.name, 說:老師好)if __name__ __main__:new_student1 Student(…

matplotlib 繪制極坐標圖

1、功能介紹: 使用了 matplotlib 庫來創建一個極坐標圖 2、代碼部分: import matplotlib.pyplot as plt import numpy as np# 設置中文字體 plt.rcParams[font.sans-serif] [SimHei] # 選擇黑體字體,支持中文 plt.rcParams[axes.unicode…

Dask心得與筆記【2】

文章目錄 計算參考文獻 計算 數組切片如下 import numpy as np import dask.array as dadata np.arange(1000).reshape(10, 100) a da.from_array(data, chunks(5, 20)) print(a[:,0:3])切片結果是前3列 dask.array<getitem, shape(10, 3), dtypeint64, chunksize(5, 3…

數據采集合規安全是品牌控價基石

在品牌控價與數據分析工作中&#xff0c;數據采集是不可或缺的前置環節。當前主流的數據采集方式為爬蟲采集&#xff0c;這種依托機器自動化操作的模式&#xff0c;取代了傳統人工逐一瀏覽、復制數據的繁瑣流程&#xff0c;大幅提升了效率。采集后的原始數據&#xff0c;會由系…

llm推理賦能action policy的探索

兄弟&#xff0c;你這個問題非常到位&#xff0c;咱分兩個問題詳細講透&#xff1a; &#x1f680; (1) HybridVLA怎么引入更好的推理能力賦能Diffusion Action&#xff1f; HybridVLA 目前設計的亮點&#xff1a; Diffusion Token 與 LLM 自回歸結合 但推理能力沒有被顯式結…

spring04-管理bean(創建、注入):基于注解

一、什么是注解&#xff1f; &#xff08;1&#xff09;注解的定義 注解&#xff08;Annotation&#xff09;是 Java 代碼中的一種特殊標記&#xff0c;用于在程序運行或編譯時提供元信息。 格式&#xff1a; 注解名(屬性名屬性值, 屬性名屬性值...)&#xff08;2&#xff…

docker安裝elasticsearch和kibana

elasticsearch版本和kibana版本需保持一致。這里我使用的都是8.18.2 安裝elasticsearch docker-compose.yml networks:es-net: external: true services:elasticsearch:container_name: es01deploy:resources:limits:cpus: 0memory: 0environment:- discovery.typesingle-no…

Python爬蟲實戰:研究sanitize庫相關技術

1. 引言 1.1 研究背景與意義 在當今數字化時代,互聯網已成為人們獲取信息、交流互動的重要平臺。隨著 Web 2.0 技術的發展,用戶生成內容 (UGC)、社交媒體嵌入、第三方插件等功能極大豐富了網頁的內容和交互性,但也帶來了嚴峻的安全挑戰。根據 Web 應用安全聯盟 (WAS) 的統…

c++ 學習(二、結構體)

目錄 一、結構體與const 二、結構體與class的區別 參考鏈接&#xff1a;69 結構體-結構體中const使用場景_嗶哩嗶哩_bilibili 一、結構體與const 調用函數的時候&#xff0c;希望這個結構體是可讀而不可寫的時候&#xff0c;傳指針&#xff0c;使用const修飾&#xff0c;方式…

機器學習開篇:算法分類與開發流程

種一棵樹最好的時間是十年前&#xff0c;其次是現在。 一、機器學習算法分類 機器學習&#xff08;ML&#xff0c;Meachine Learning&#xff09;是人工智能的核心領域&#xff0c;讓計算機從數據中學習規律并做出預測&#xff0c;本文簡單介紹機器學習的算法分類和開發流程。…

使用pyflink編寫demo并將任務提交到yarn集群

目錄 背景 一、pyflink安裝 二、編寫demo程序 三、提交yarn前準備 四、提交任務 五、踩坑記錄 1、提交任務時客戶端出現語法錯誤 2、提交任務時客戶端出現lzma包找不到 3、提交任務時客戶端出現“org.apache.flink.streaming.api.utils.PythonTypeUtils.getCollectionIn…

Vue 3 最基礎核心知識詳解

Vue3作為現代前端主流框架&#xff0c;是前后端開發者都應當掌握的核心技能。本篇文章將帶你了解vue3的基礎核心知識&#xff0c;適合學習與復習 一、Vue 3 應用創建 1.1 創建Vue應用的基本步驟 // main.js import { createApp } from vue // 1. 導入createApp函數 import …

Bootstrap 5學習教程,從入門到精通,Bootstrap 5 Flex 布局語法知識點及案例(27)

Bootstrap 5 Flex 布局語法知識點及案例 Bootstrap 5 提供了強大的 Flexbox 工具集&#xff0c;讓布局變得更加簡單靈活。以下是 Bootstrap 5 Flex 布局的完整知識點和詳細案例代碼。 一、Flex 布局基礎語法 1. 啟用 Flex 布局 <div class"d-flex">我是一個…

HarmonyOS 5智能單詞應用開發:記憶卡(附:源碼

一、應用概述與核心價值 在語言學習過程中&#xff0c;單詞記憶是基礎也是難點。本文介紹的智能單詞記憶卡應用通過創新的交互設計和科學的學習模式&#xff0c;幫助用戶高效記憶單詞。應用采用ArkUI框架開發&#xff0c;主要特點包括&#xff1a; 雙模式學習系統&#xff1a…

LeetCode--38.外觀數列

前言&#xff1a;之前我不是說&#xff0c;我后續可能會講一下遞歸嗎&#xff0c;現在它來了&#xff0c;這道題會用到回溯的方法&#xff0c;并且比較純粹哦 解題思路&#xff1a; 1.獲取信息&#xff1a;&#xff08;下面這些信息差不多是力扣上面的題目信息了&#xff0c;所…

服務器的安裝與安全設置

1&#xff1a;安裝操作系統 1、創建虛擬機Win49&#xff08;49為序號&#xff09;&#xff0c;并安裝Windows Server 2019操作系統 參考配置&#xff1a;安裝系統的分區大小為20GB&#xff0c;其余分區暫不劃分&#xff0c; 文件系統格式為NTFS&#…

Sensodrive SensoJoint機器人力控關節模組抗振動+Sensodrive力反饋系統精準對接

Sensodrive成立于2003年&#xff0c;起源于德國航空航天中心&#xff08;DLR&#xff09;的LBR項目。公司由一批傳感器技術專家創立&#xff0c;專注于高精度工業扭矩傳感器的研發。憑借二十余年的技術積累&#xff0c;Sensodrive將DLR輕型機器人扭矩技術引入工業領域&#xff…