【中间件】大数据之分布式消息队列Kafka
目錄
Kafka設(shè)計動機
Kafka特點
Kafka設(shè)計架構(gòu)
基本架構(gòu)
Kafka各組件詳解
Kafka關(guān)鍵技術(shù)點
典型應(yīng)用場景
? ? ? 在大數(shù)據(jù)數(shù)據(jù)收集環(huán)節(jié),需要構(gòu)建數(shù)據(jù)流水線,其中一種方式可以通過消息隊列實現(xiàn)。在實際應(yīng)用中,不同服務(wù)器產(chǎn)生的日志,比如指標監(jiān)控數(shù)據(jù),用戶搜索日志,用戶點擊日志等,需要同時傳送到多個系統(tǒng)中以便進行相應(yīng)的邏輯處理和挖掘。
? ? ? 消息隊列位于生產(chǎn)者和消費者之間的“中間件”,解除了生產(chǎn)者和消費者的直接依賴關(guān)系,使得軟件架構(gòu)更容易擴展和伸縮;能夠緩沖生產(chǎn)者產(chǎn)生的數(shù)據(jù),防止消費者無法及時處理生產(chǎn)者產(chǎn)生的數(shù)據(jù)。
Kafka設(shè)計動機
數(shù)據(jù)流水演化隨著業(yè)務(wù)復(fù)雜度和產(chǎn)生數(shù)據(jù)量不斷增加,逐漸演化成上圖數(shù)據(jù)收集模式,并將收集到數(shù)據(jù)直接寫入后端,則會產(chǎn)生以下幾個潛在問題:
- 數(shù)據(jù)生產(chǎn)者和消費者耦合度過高
- 生產(chǎn)者和消費者間數(shù)據(jù)處理速率不對等
- 大量并發(fā)的網(wǎng)絡(luò)連接對后端消費者不夠友好
為了解決以上問題,引入“中間件”,從這個角度理解Kafka 如下圖所示(Kafka在數(shù)據(jù)流中扮演的角色):
- 消息中間件:避免生產(chǎn)者和消費者直接相互產(chǎn)生的彼此高度依賴,使得兩者中任何一個由變化,都不會影響另一方。
- 消息隊列:緩存生產(chǎn)者產(chǎn)生的數(shù)據(jù),使得消費者可以重復(fù)消費歷史數(shù)據(jù);平滑生產(chǎn)者產(chǎn)生數(shù)據(jù)速度和消費處理數(shù)據(jù)速度的不對等。
- 發(fā)布訂閱系統(tǒng):消費者訂閱某類主題的數(shù)據(jù),當生產(chǎn)者產(chǎn)生對應(yīng)主題的數(shù)據(jù)后,所有訂閱者會快速獲取到數(shù)據(jù)。隨時增加新的消費者而無需進行任何系統(tǒng)層面的修改。
- 消息總線:所有收集到的數(shù)據(jù)會流經(jīng) Kafka,之后由Kafka分流后,進入各個消費者系統(tǒng)。
Kafka特點
Kafka是在大數(shù)據(jù)背景下產(chǎn)生,能應(yīng)對海量數(shù)據(jù)的處理系統(tǒng)。具有以下特點:
- 高性能:相比RabbitMQ等消息隊列,Kafka 具有更高的性能和吞吐率。
- 良好擴展性:采用分布式設(shè)計架構(gòu),數(shù)據(jù)經(jīng)分片后寫入多個節(jié)點,既可以突破單節(jié)點數(shù)據(jù)存儲和處理的瓶頸,也可以實現(xiàn)容錯等功能。
- 數(shù)據(jù)持久化:數(shù)據(jù)消息均會持久化到磁盤上,并通過多副本策略避免數(shù)據(jù)丟失,采用順序?qū)?#xff0c;順序讀,和批量寫等機制,提升磁盤操作的效率。
Kafka設(shè)計架構(gòu)
1. 基本架構(gòu)
Kafka 架構(gòu)由 Producer,Broker 和 Consumer?三類組件構(gòu)成。
- Producer 將數(shù)據(jù)寫入Broker,Consumer 從 Broker上讀取數(shù)據(jù)進行處理,Broker構(gòu)成了連接 Producer?和?Consumer 的“緩沖區(qū)”。
- Broker?和 Cunsumer?通過?Zookeeper?做協(xié)調(diào)和服務(wù)發(fā)現(xiàn)。
- 多個?Broker?構(gòu)成一個可靠的分布式消息存儲系統(tǒng),避免數(shù)據(jù)丟失。
- Broker?中的消息被劃分成若干個 topic ,同屬于一個?topic?的所有數(shù)據(jù)按照某種策略被分成多個?partition?以實現(xiàn)負載分攤和數(shù)據(jù)并行處理。
- 采用 push-pull,即 Producer 將數(shù)據(jù)直接 “push” 給 Broker, 而 Consumer 從Broker?“pull”數(shù)據(jù),這種架構(gòu)優(yōu)勢帶來以下兩點:
- Consumer 可以根據(jù)自己的實際負載和需求獲取數(shù)據(jù)(自己主動去拉取消息進行消費)
-
Consumer 自己維護已讀取消息的?offset 而不是由Broker 端維護,大大緩解 Broker 的壓力,使得它更加輕量級。?
2. Kafka各組件詳解
1.producer
由用戶使用 Kafka 提供的?SDK?開發(fā)的,Producer 將數(shù)據(jù)轉(zhuǎn)化成 “消息”,并通過網(wǎng)絡(luò)發(fā)送給 Broker。每條消息表示為一個三元組: <topic, key, message>
- topic:表示該條消息所屬的 topic,劃分消息的邏輯概念。一個 topic 可以分布到多個不同的 Broker 上。
- key:表示該消息的主鍵。根據(jù)主鍵將同一個 topic 下消息劃分成不同的分區(qū) ( partition ),默認基于哈希取模算法,用戶可以自行設(shè)置分區(qū)算法。如下圖演示 Producer 寫消息的過程,假設(shè) topic A 共分為 4 個 partition (創(chuàng)建 topic 時靜態(tài)制定)。
- message:消息值,其類型為字節(jié)數(shù)組,可以是普通字符串,JSON對象,或者 JSON, Acro,Thrift或Protobuf等序列化框架序列化后的對象。
2. Broker
主要職責(zé)是接受 Producer 和 Consumer 的請求,并把消息持久化到本地磁盤。Broker一般有多個,組成一個分布式高容錯的集群。
Kafka Broker 集群- Broker 以 topic 為單位將消息分成不同的分區(qū) (partition),每個分區(qū)可以有多個副本,通過數(shù)據(jù)冗余的方式實現(xiàn)容錯。當 partition 存在多個副本時,其中一個是 leader,對外提供讀寫請求,其余均是 follower,僅僅同步 leader 中的數(shù)據(jù),并在 leader 出現(xiàn)問題時,通過選舉算法將其中的某一個提升為 leader。
- Broker 能夠保證同一個 topic 在同一個 partition 內(nèi)部的消息是有序的,但無法保證 partition 之間的消息全局有序。在實際應(yīng)用中,合理利用分區(qū)內(nèi)部有序這一特征即可完成時序相關(guān)的需求。
- Broker 中保存數(shù)據(jù)是有有效期,一旦超過了有效期,對應(yīng)的數(shù)據(jù)被移除以釋放磁盤空間。在有效期期內(nèi),消息可以重復(fù)讀取而不受限制。
- Broker 以追加的方式將消息寫到磁盤文件中,且每個分區(qū)中消息被賦予了唯一整數(shù)標識,稱之為 “offset” (偏移量)。
- Broker 僅提供基于 offset 的讀取方式 ,不會維護各個 Consumer 當前已消費的 offset 值,而是由?Consumer 各自維護當前讀取的進度。Consumer 讀取數(shù)據(jù)時告訴 Broker 請求消息的起始 offset 值,Broker將之后的消息流式發(fā)送過去。如下圖所示:
3.Consumer
- 主動從 Broker 拉取(pull)消息進行處理,這個機制大大降低了 Broker 的壓力,使得 Broker 吞吐率很高。
- 每個Consumer 自己維護最后一個已讀取消息的 offset,并在下次請求從這個 offset 開始的消息。
- 多個Consumer 構(gòu)成一個Consumer Group,共同讀取同一個?topic?中的數(shù)據(jù),提高數(shù)據(jù)讀取效率。Kafka 可自動為同一個Group 中的 Consumer 分攤負載,從而實現(xiàn)消息的并發(fā)讀取,在某個Consumer發(fā)生故障時,自動將它處理的 partition 轉(zhuǎn)移給同 Group 中的 Consumer 處理。
4.Zookeeper
在?Kafka 集群中,Zookeeper 擔任分布式服務(wù)協(xié)調(diào)作用,Broker 和 Consumer 直接依賴于 Zookeeper 才能工作。
- Broker 與 Zookeeper:所有 Broker 會向 Zookeeper 注冊,將自己的位置,健康狀況,維護的 topic,partition等信息寫入 Zookeeper ,以便其他 Consumer 可以發(fā)現(xiàn)和獲取這些數(shù)據(jù)。
- Consumer 與 Zookeeper:Consumer Group 通過Zookeeper 保證內(nèi)部各個 Consumer 的負載均衡,在某個 Consumer 或 Broker 出現(xiàn)故障時,重新分攤負載。Consumer (僅限于 height-level API,如果是 low-level API,用戶需要自己保存和恢復(fù)offset)會將最近獲取消息的 offset 寫入 Zookeeper,以便出現(xiàn)故障重啟后,能夠接著故障前的斷點繼續(xù)讀取數(shù)據(jù)。
3. Kafka關(guān)鍵技術(shù)點
1. 可控的可靠性級別
Producer 通過兩種方式向 Broker 發(fā)送數(shù)據(jù):同步 與 異步。異步方式通過批處理的方式,可大大提高數(shù)據(jù)寫入效率。這兩種方式均支持通過控制消息應(yīng)答方式,在寫性能與可靠性之間做一個較好的權(quán)衡。目前支持三種消息應(yīng)答方式,通過request.required.ack 控制:
- 0:無需對消息進行確認,性能最高,但不能確保消息被成功接收并寫入磁盤。
- 1:需要等到 leader partition 寫成功后才會返回,但對應(yīng)的 follower partition 不一定寫成功。在性能與可靠性之間進行折中。
- -1:需要等到所有 partition 均寫成功后才會返回。性能較低,但可靠性最高。
2. 數(shù)據(jù)多副本
Broker 允許為每個 topic 中的數(shù)據(jù)存放多個副本,以達到容錯的目的。Kafka 采用強一致的數(shù)據(jù)復(fù)制策略。
Kafka Broker 多副本放置3. 高效的持久化機制
直接將消息持久化到磁盤而不是內(nèi)存中,這要求必須采用高效的數(shù)據(jù)寫入和存儲方式。Kafka Broker 將收到的數(shù)據(jù)順序寫入磁盤,并結(jié)合基于 offset 的數(shù)據(jù)組織方式,能達到高效的讀速度和寫速度。
4. 數(shù)據(jù)傳輸優(yōu)化:批處理與zero-copy技術(shù)
為了優(yōu)化 Broker 與 Consumer?之間的網(wǎng)絡(luò)數(shù)據(jù)傳輸效率,Kafka引入了大量優(yōu)化技術(shù),典型的兩個代表:
- 批處理:發(fā)送是將多條消息進行組裝,同時對數(shù)據(jù)格式統(tǒng)一設(shè)計,避免數(shù)據(jù)格式轉(zhuǎn)換帶來開銷。
- zero-copy技術(shù):一般情況下,一條存儲在磁盤的數(shù)據(jù)從讀取到發(fā)送出去需要經(jīng)過四次拷貝(內(nèi)核狀態(tài) read buffer? > 用戶態(tài)應(yīng)用程序?buffer? > 內(nèi)核態(tài) socket buffer? > 網(wǎng)卡NIC buffer)和兩次系統(tǒng)調(diào)用。經(jīng)過zero-copy技術(shù)優(yōu)化后,數(shù)據(jù)只需三次拷貝(少了 用戶態(tài)應(yīng)用程序?buffer),且無需使用任何系統(tǒng)調(diào)用,大大提高數(shù)據(jù)發(fā)送效率。如下圖所示:
5. 可控的消息傳遞語義
根據(jù)接受者受到重復(fù)消息的次數(shù),將消息傳遞語義分為三種:
- at most once:不需要等待確認,消息可能被消費者成功接收,也可能丟失。
- at least once:需要等待確認,如未收到確認則會重發(fā);保障消費者收到消息,但可能會收到多次。
- exactly once:消費者會且只會處理一次同一條消息。
實現(xiàn)第三種語義,常用技術(shù)手段有:
- 兩段鎖協(xié)議:分布式中常用的一致性協(xié)議。
- 在支持冪等操作下,使用 at least once 語義。Producer 與 Broker,? Broker 與 Consumer 之間,均存在消息傳遞語義問題。
典型應(yīng)用場景
1. 消息隊列
與 RabbitMQ 和 ZeroMQ 等開源消息隊列相比,Kafka 具有高吞吐率,自動分區(qū),多副本以及良好容錯性等特點,使得它非常適合大數(shù)據(jù)應(yīng)用場景。
2. 流式計算框架的數(shù)據(jù)源
在流式計算框架,為了保證數(shù)據(jù)不丟失,具備“at least once”數(shù)據(jù)發(fā)送語意,通常在數(shù)據(jù)源中使用具有高性能的消息隊列。
3. 分布式日志收集系統(tǒng)中Source或Sink
可與日志收集組件 Flume 或 Logstash 組合使用,擔任 Source 或 Sink 的角色。
4. Lambda Architecture 中的 Source
同時為批處理和流式處理兩條流水線提供數(shù)據(jù)源
?
注:內(nèi)容主要整理自書本《大數(shù)據(jù)技術(shù)體系詳解 原理、架構(gòu)與實踐》 董西成
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的【中间件】大数据之分布式消息队列Kafka的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【项目管理】专用中英文术语词汇 205
- 下一篇: 【科普】一图区分 IAAS + PAAS