主頁 >  其他 > kafka掃盲-思考與實作

kafka掃盲-思考與實作

2021-10-15 21:47:03 其他

微信搜【假裝懂編程】,與作者零距離交流

由于作業中經常用到kafka,但是對kafka的一些內部機制不是很熟悉,所以最近在看kafka相關的知識,我們知道kafka非常經典的訊息引擎,它以高性能、高可用著稱,那么問題來了,它是怎么做到高性能、高可用的?它的訊息是以什么樣的形式持久化的?既然寫了磁盤,為何速度還那么快?它是如何保證訊息不丟失的...?帶著這一系列的問題,我們來扒開kafka的面紗,

首先我們思考這樣一個問題:為什么需要訊息引擎?為什么不能直接走rpc? 以一個訂單系統為例:當我們下了一個訂單的時候,應該是要先減商品庫存,然后用戶支付扣錢,商家賬戶加錢...,最后可能還要發推送或者短信告訴用戶下單成功,告訴商家來訂單了,

這整個下單程序,如果全部同步阻塞,那么耗時會增加,用戶等待的時間會加長,體驗不太好,同時下單程序依賴的鏈路越長,風險越大,為了加快回應,減少風險,我們可以把一些非必須卡在主鏈路中的業務拆解出去,讓它們和主業務解耦,下單的最關鍵核心就是要保證庫存、用戶支付、商家打款的一致性,訊息的通知完全可以走異步,這樣整個下單程序不會因為通知商家或者通知用戶阻塞而阻塞,也不會因為它們失敗而提示訂單失敗,

接下來就是如何設計一個訊息引擎了,宏觀來看一個訊息引擎支持發送存盤接收就行了,

那么如上圖一個簡易訊息佇列模型出現了,Engine把發送方的訊息存盤起來,這樣當接收方來找Engine要資料的時候,Engine再從存盤中把資料回應給接收放就ok了,既然涉及到持久化的存盤,那么緩慢的磁盤IO是要考慮的問題,還有接收方可能不止一個,以上述訂單為例,下單完成之后,通過訊息把完成事件發出去,這時候負責用戶側推送的開發需要消費這條訊息,負責商戶側推送的開發也需要消費這條訊息,能想到的最簡單的做法就是copy出兩套訊息,但是這樣是不是顯得有點浪費?高可用也是一個需要考慮的點,那么我們的engine是不是得副本,有了副本之后,如果一個engine節點掛掉,我們可以選舉出一個新副本來作業,光有副本也不行,發送方可能也是多個,這時候如果所有的發送方都把資料打到一個Leader(主)節點上似乎也不合理,單個節點的壓力太大,可能你會說:不是有副本嗎?讓接收方直接從副本讀取訊息,這樣的話又帶來另一個問題:副本復制Leader的訊息延遲了咋辦?讀不到訊息再讀一次Leader?如果這樣的話,引擎的設計的貌似更加復雜了,似乎不太合理,那就得想一種既能不通過副本又能分散單節點壓力就行了,答案就是分片技術,既然單個Leader節點壓力太大,那么就分成多個Leader節點,我們只需要一個好的負載均衡演算法,通過負載均衡把訊息平均分配到各個分片節點就好了,于是我們可以設計出一套大概長這樣的生產者-消費者模型,

但是這些只是簡單的想法,具體如何實作還是很復雜的,帶著這一系列問題和想法,我們來看看kafka是如何實作的,

思考與實作

首先我們還是從kafka的幾個名詞入手,主要介紹下訊息、主題、磁區和消費者組,

一條訊息該怎么設計

訊息是服務的源頭,一切的設計都是為了將訊息從一端送到另一端,這里面涉及到訊息的結構,訊息體不能太大,太大容易造成存盤成本上升,網路傳輸開銷變大,所以訊息體只需要包含必要的資訊,最好不要冗余,訊息最好也支持壓縮,通過壓縮可以在訊息體本身就精簡的情況下變的更小,那么存盤和網路開銷可以進一步降低,訊息是要持久化的,被消費掉的訊息不能一直存盤,或者說非常老的訊息被再次消費的可能性不大,需要一套機制來清理老的訊息,釋放磁盤空間,如何找出老的訊息是關鍵,所以每個訊息最好帶個訊息生產時的時間戳,通過時間戳計算出老的訊息,在合適的時候進行洗掉,訊息也是需要編號的,編號一方面代表了訊息的位置,另一方面消費者可以通過編號找到對應的訊息,大量的訊息如何存盤也是個問題,全部存盤在一個檔案中,查詢效率低且不利于清理老資料,所以采用分段,通過分段的方式把大的日志檔案切割成多個相對小的日志檔案來提升維護性,這樣當插入訊息的時候只要追加在段的最后就行,但是在查找訊息的時候如果把整個段加載到記憶體中一條一條找,似乎也需要很大的記憶體開銷,所以需要一套索引機制,通過索引來加速訪問對應的Message,

總結:一條kafka的訊息包含創造時間訊息的序號支持訊息壓縮,存盤訊息的日志是分段存盤,并且是有索引的,

為什么需要Topic

宏觀來看訊息引擎就是一發一收,有個問題:生產者A要給消費者B發送訊息,同時也要給消費者C發送訊息,那么消費者B和消費者C如何只消費到自己需要的資料?能想到的簡單的做法就是在訊息中加Tag,消費者根據Tag來獲取自己的訊息,不是自己的訊息直接跳過,但是這樣似乎不太優雅,而且存在cpu資源浪費在訊息的過濾上,所以最有效的辦法就是對于給B訊息不會給C,給C的訊息不會給B,這就是Topic,通過Topic來區分不同的業務,每個消費者只需要訂閱自己關注的Topic即可,生產者把消費者需要的訊息通過約定好的Topic發過去,那么簡單的理解就是訊息按照Topic分類了,

總結:Topic是個邏輯的概念,Topic可以很好的做業務劃分,每個消費者只需要關注自己的Topic即可,

磁區如何保證順序

通過上文我們知道磁區的目的就是分散單節點的壓力,再結合Topic和Message,那么訊息的大概分層就是Topic(主題)->Partition(磁區)->Message(訊息),也許你會問,既然磁區是為了降低單節點的壓力,那么干嘛不用多個topic代替多個磁區,在多個機器節點的情況下,我們可以把多個topic部署在多個節點上,似乎也能實作分布式,簡單一想似乎可行,仔細一想,還是不對,我們最侄訓要服務業務的,這樣的話,本來一個topic的業務,要拆解成多個topic,反而把業務的定義打散了,

好吧,既然有多個磁區了,那么訊息的分配是個問題,如果topic下面的資料過于集中在某個磁區上,又會造成分布不均勻,解決這個問題,一套好的分配演算法是很有必要的,

kafka支持輪詢法,即在多磁區的情況下,通過輪詢可以均勻地把訊息分給每個磁區,這里需要注意的是,每個磁區里的資料是有序的,但是整體的資料是無法保證順序的,如果你的業務強依賴訊息的順序,那么就要慎重考慮這種方案,比如生產者依次發了A、B、C三個訊息,它們分別分布在3個磁區中,那么有可能出現的消費順序是B、A、C,

那么如何保證訊息的順序性?從整體的角度來看,只要磁區數大于1,就永遠無法保證訊息的順序性,除非你把磁區數設定成1,但是這樣的話吞吐就是問題,從實際的業務場景來說,一般我們可能需要某個用戶的訊息、或者某個商品的訊息有序就可以了,用戶A和用戶B的訊息誰先誰后沒關系,因為它們之間沒什么關聯,但是用戶A的訊息我們可能要保持有序,比如訊息描述的是用戶的行為,行為的先后順序是不能亂的,這時候我們可以考慮用key hash的方式,同一個用戶id,通過hash始終能保持分到一個磁區上,我們知道磁區內部是有序的,所以這樣的話,同一個用戶的訊息一定是有序的,同時不同的用戶可以分配到不同的磁區上,這樣也利用到了多磁區的特性,

總結:kafka整體訊息是無法保證有序的,但是單個磁區的訊息是可以保證有序的,

如何設計一個合理的消費者模型

既然是設計訊息模型,那么消費者必不可少,實作消費者最簡單的方式就是起一個行程或者執行緒直接去broker里面拉取訊息即可,這很合理,但是如果生產的速度大于當前的消費速度怎么辦?第一時間想到的就是再起一個消費者,通過多個消費者來提升消費速度,這里似乎又有個問題,兩個消費者都消費到了同一條訊息怎么辦?加鎖是個解決方案,但是效率會降低,也許你會說消費的本質就是讀,讀是可以共享的,只要保證業務冪等,重復消費訊息也沒關系,這樣的話,如果10個消費者都爭搶到了同樣的訊息,結果有9個消費者都是白白浪費資源的,因此在需要多個消費者提升消費能力的同時,還要保證每個消費者都消費到沒被處理的訊息,這就是消費者組,消費者組下面可以有多個消費者,我們知道topic是磁區的,因此只要消費者組內的每個消費者訂閱不同的磁區就可以了,理想的情況下是每個消費者都分配到相同資料量磁區,如果某個消費者獲得的磁區數不平均(較多或者較少),出現資料傾斜狀態,那么就會導致某些消費者非常繁忙或者輕松,這樣就不合理,這就需要一套均衡的分配策略,

kafka消費者磁區分配策略主要有3種:

  1. Range:這種策略是針對topic的,會把topic的磁區數和消費者數進行一個相除,如果有余數,那就說明多余的磁區不夠平均分了,此時排在前面的消費者會多分得1個磁區,乍看其實挺合理,畢竟本來數量就不均衡,但是如果消費者訂閱了多個topic,并且每個topic平均算下來都多幾個個磁區,那么對于排在前面的消費者就會多消費很多磁區,

由于是按照topic維度來劃分的,所以最終:

  • c1消費 Topic0-p0、Topic0-p1、Topic1-p0、Topic1-p1
  • c2消費 Topic0-p2、Topic1-p2

最終可以發現消費者c1比消費者c2整整多兩個磁區,完全可以把c1的磁區分一個給c2,這樣就可以均衡了,

  1. RoundRobin:這種策略的原理是將消費組內所有消費者以及消費者所訂閱的所有topic的partition按照字典序排序,然后通過輪詢演算法逐個將磁區以此分配給每個消費者,假設現在有兩個topic,每個topic3個磁區,并且有3個消費者,那么大致消費狀況是這樣的:

  • c0消費 Topic0-p0、Topic1-p0
  • c1消費 Topic0-p1、Topic1-p1
  • c2消費 Topic0-p2、Topic1-p2

看似很完美,但是如果現在有3個topic,并且每個topic磁區數是不一致的,比如topic0只有一個磁區,topic1有兩個磁區,topic2有三個磁區,而且消費者c0訂閱了topic0,消費者c1訂閱了topic0和topic1,消費者c2訂閱了topic0、topic1、topic2,那么大致消費狀況是這樣的:

  • c0消費 Topic0-p0
  • c1消費 Topic1-p0
  • c2消費 Topic1-p1、Topic2-p0、Topic2-p1、Topic2-p2

這么看來RoundRobin并不是最完美的,在不考慮每個topic磁區吞吐能力的差異,可以看到c2的消費負擔明顯很大,完全可以將Topic1-p1磁區分給消費者c1,

  1. Sticky:Range和RoundRobin都有各自的缺點,某些情況下可以更加均衡,但是沒有做到,

Sticky引入目的之一就是:磁區的分配要盡可能均勻,以上面RoundRobin 3個topic分別對應1、2、3個磁區的case來說,因為c1完全可以消費Topic1-p1,但是它沒有,針對這種情況,在Sticky模式下,就可以做到把Topic1-p1分給c1,

Sticky引入目的之二就是:磁區的分配盡可能與上次分配的保持相同,這里主要解決就是rebalance后磁區重新分配的問題,假設現在有3個消費者c0、c1、c2,他們都訂閱了topic0、topic1、topic2、topic3,并且每個topic都有兩個磁區,此時消費的狀況大概是這樣:

這種分配方式目前看RoundRobin沒什么區別,但是如果此時消費者c1退出,消費者組內只剩c0、c2,那么就需要把c1的磁區重新分給c0和c2,我們先來看看RoundRobin是如何rebalance的:

可以發現原來c0的topic1-p1分給了c2,原來c2的topic1-p0分給了c0,這種情況可能會造成重復消費問題,在消費者還沒來得及提交的時候,發現磁區已經被分給了一個新的消費者,那么新的消費者就會產生重復消費,但是從理論的角度來說,在c1退出之后,可以沒必要去動c0和c2的磁區,只需要把原本c1的磁區瓜分給c0和c2即可,這就是sticky的做法:

需要注意的是Sticky策略中,如果磁區的分配要盡可能均勻磁區的分配盡可能與上次分配的保持相同發生沖突,那么會優先實作第一個,

總結:kafka默認支持以上3種磁區分配策略,也支持自定義磁區分配,自定義的方式需要自己去實作,從效果來看RoundRobin要好于Range的,Sticky是要好于RoundRobin的,推薦大家使用版本支持的最好的策略,

微信搜【假裝懂編程】,與作者零距離交流

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/316452.html

標籤:其他

上一篇:寫給初學者,一文搞懂大資料學習、崗位、面試及簡歷

下一篇:在除錯中,是否可以知道兩個變數是否是同一個物件?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more