kafka權(quán)威指南(閱讀摘錄)


Kafka 使用零復(fù)制技術(shù)向客戶端發(fā)送消息——也就是說,Kafka 直接把消息從文件(或者更確切地說是 Linux 文件系統(tǒng)緩存)里發(fā)送到網(wǎng)絡(luò)通道,而不需要經(jīng)過任何中間緩沖區(qū)。這是 Kafka 與其他大部分?jǐn)?shù)據(jù)庫系統(tǒng)不一樣的地方,其他數(shù)據(jù)庫在將數(shù)據(jù)發(fā)送給客戶端之前會(huì)先把它們保存在本地緩存里。這項(xiàng)技術(shù)避免了字節(jié)復(fù)制,也不需要管理內(nèi)存緩沖區(qū),從而獲得更好的性能。
如何選定分區(qū)數(shù)量
為主題選定分區(qū)數(shù)量并不是一件可有可無的事情,在進(jìn)行數(shù)量選擇時(shí),需要考慮如下幾個(gè)因素。
主題需要達(dá)到多大的吞吐量?例如,是希望每秒鐘寫入 100KB 還是 1GB ?
從單個(gè)分區(qū)讀取數(shù)據(jù)的最大吞吐量是多少?每個(gè)分區(qū)一般都會(huì)有一個(gè)消費(fèi)者,如果你知道消費(fèi)者將數(shù)據(jù)寫入數(shù)據(jù)庫的速度不會(huì)超過每秒 50MB,那么你也該知道,從一個(gè)分區(qū)讀取數(shù)據(jù)的吞吐量不需要超過每秒 50MB。
可以通過類似的方法估算生產(chǎn)者向單個(gè)分區(qū)寫入數(shù)據(jù)的吞吐量,不過生產(chǎn)者的速度一般比消費(fèi)者快得多,所以最好為生產(chǎn)者多估算一些吞吐量。
每個(gè) broker 包含的分區(qū)個(gè)數(shù)、可用的磁盤空間和網(wǎng)絡(luò)帶寬。
如果消息是按照不同的鍵來寫入分區(qū)的,那么為已有的主題新增分區(qū)就會(huì)很困難。
單個(gè) broker 對(duì)分區(qū)個(gè)數(shù)是有限制的,因?yàn)榉謪^(qū)越多,占用的內(nèi)存越多,完成首領(lǐng)選舉需要的時(shí)間也越長(zhǎng)。
消費(fèi)者數(shù)量
我們有必要為主題創(chuàng)建大量的分區(qū),在負(fù)載增長(zhǎng)時(shí)可以加入更多的消費(fèi)者。不過要注意,不要讓消費(fèi)者的數(shù)量超過主題分區(qū)的數(shù)量,多余的消費(fèi)者只會(huì)被閑置。
跟隨者副本
首領(lǐng)以外的副本都是跟隨者副本。跟隨者副本不處理來自客戶端的請(qǐng)求,它們唯一的任務(wù)就是從首領(lǐng)那里復(fù)制消息,保持與首領(lǐng)一致的狀態(tài)。如果首領(lǐng)發(fā)生崩潰,其中的一個(gè)跟隨者會(huì)被提升為新首領(lǐng)。
Kafka 可以在哪些方面作出保證呢?
Kafka 可以保證分區(qū)消息的順序。如果使用同一個(gè)生產(chǎn)者往同一個(gè)分區(qū)寫入消息,而且消息 B 在消息 A 之后寫入,那么 Kafka 可以保證消息 B 的偏移量比消息 A 的偏移量大,而且消費(fèi)者會(huì)先讀取消息 A 再讀取消息 B。
只有當(dāng)消息被寫入分區(qū)的所有同步副本時(shí)(但不一定要寫入磁盤),它才被認(rèn)為是“已提交”的。生產(chǎn)者可以選擇接收不同類型的確認(rèn),比如在消息被完全提交時(shí)的確認(rèn),或者在消息被寫入首領(lǐng)副本時(shí)的確認(rèn),或者在消息被發(fā)送到網(wǎng)絡(luò)時(shí)的確認(rèn)。
只要還有一個(gè)副本是活躍的,那么已經(jīng)提交的消息就不會(huì)丟失。
消費(fèi)者只能讀取已經(jīng)提交的消息。
復(fù)制機(jī)制和分區(qū)的多副本架構(gòu)
Kafka 的復(fù)制機(jī)制和分區(qū)的多副本架構(gòu)是 Kafka 可靠性保證的核心。把消息寫入多個(gè)副本可以使 Kafka 在發(fā)生崩潰時(shí)仍能保證消息的持久性。
使用 Kafka 構(gòu)建數(shù)據(jù)管道
在使用 Kafka 構(gòu)建數(shù)據(jù)管道時(shí),通常有兩種使用場(chǎng)景:第一種,把 Kafka 作為數(shù)據(jù)管道的兩個(gè)端點(diǎn)之一,例如,把 Kafka 里的數(shù)據(jù)移動(dòng)到 S3 上,或者把 MongoDB 里的數(shù)據(jù)移動(dòng)到 Kafka 里;第二種,把 Kafka 作為數(shù)據(jù)管道兩個(gè)端點(diǎn)的中間媒介,例如,為了把 Twitter 的數(shù)據(jù)移動(dòng)到 ElasticSearch 上,需要先把它們移動(dòng)到 Kafka 里,再將它們從 Kafka 移動(dòng)到 ElasticSearch 上。
Kafka 為數(shù)據(jù)管道帶來的主要價(jià)值
Kafka 為數(shù)據(jù)管道帶來的主要價(jià)值在于,它可以作為數(shù)據(jù)管道各個(gè)數(shù)據(jù)段之間的大型緩沖區(qū),有效地解耦管道數(shù)據(jù)的生產(chǎn)者和消費(fèi)者。Kafka 的解耦能力以及在安全和效率方面的可靠性,使它成為構(gòu)建數(shù)據(jù)管道的最佳選擇。
ETL 和 ELT
數(shù)據(jù)管道的構(gòu)建可以分為兩大陣營,即 ETL 和 ELT。 ETL 表示提取—轉(zhuǎn)換—加載(Extract-Transform-Load),也就是說,當(dāng)數(shù)據(jù)流經(jīng)數(shù)據(jù)管道時(shí),數(shù)據(jù)管道會(huì)負(fù)責(zé)處理它們。這種方式為我們節(jié)省了時(shí)間和存儲(chǔ)空間,因?yàn)椴恍枰?jīng)過保存數(shù)據(jù)、修改數(shù)據(jù)、再保存數(shù)據(jù)這樣的過程。不過,這種好處也要視情況而定。有時(shí)候,這種方式會(huì)給我們帶來實(shí)實(shí)在在的好處,但也有可能給數(shù)據(jù)管道造成不適當(dāng)?shù)挠?jì)算和存儲(chǔ)負(fù)擔(dān)。這種方式“有一個(gè)明顯不足,就是數(shù)據(jù)的轉(zhuǎn)換會(huì)給數(shù)據(jù)管道下游的應(yīng)用造成一些限制,特別是當(dāng)下游的應(yīng)用希望對(duì)數(shù)據(jù)進(jìn)行進(jìn)一步處理的時(shí)候。假設(shè)有人在 MongoDB 和 MySQL 之間建立了數(shù)據(jù)管道,并且過濾掉了一些事件記錄,或者移除了一些字段,那么下游應(yīng)用從 MySQL 中訪問到的數(shù)據(jù)是不完整的。如果它們想要訪問被移除的字段,只能重新構(gòu)建管道,并重新處理歷史數(shù)據(jù)(如果可能的話)。
ELT 表示提取—加載—轉(zhuǎn)換(Extract-Load-Transform)。在這種模式下,數(shù)據(jù)管道只做少量的轉(zhuǎn)換(主要是數(shù)據(jù)類型轉(zhuǎn)換),確保到達(dá)數(shù)據(jù)池的數(shù)據(jù)盡可能地與數(shù)據(jù)源保持一致。這種情況也被稱為高保真(high fidelity)數(shù)據(jù)管道或數(shù)據(jù)湖(data lake)架構(gòu)。目標(biāo)系統(tǒng)收集“原始數(shù)據(jù)”,并負(fù)責(zé)處理它們。這種方式為目標(biāo)系統(tǒng)的用戶提供了最大的靈活性,因?yàn)樗鼈兛梢栽L問到完整的數(shù)據(jù)。在這些系統(tǒng)里診斷問題也變得更加容易,“因?yàn)閿?shù)據(jù)被集中在同一個(gè)系統(tǒng)里進(jìn)行處理,而不是分散在數(shù)據(jù)管道和其他應(yīng)用里。這種方式的不足在于,數(shù)據(jù)的轉(zhuǎn)換占用了目標(biāo)系統(tǒng)太多的 CPU 和存儲(chǔ)資源。有時(shí)候,目標(biāo)系統(tǒng)造價(jià)高昂,如果有可能,人們希望能夠?qū)⒂?jì)算任務(wù)移出這些系統(tǒng)。
數(shù)據(jù)管道
數(shù)據(jù)管道最重要的作用之一是解耦數(shù)據(jù)源和數(shù)據(jù)池。
留待實(shí)戰(zhàn)內(nèi)容
連接器示例——從MySQL到ElasticSearch
broker最重要的度量指標(biāo)
如果說 broker 只有一個(gè)可監(jiān)控的度量指標(biāo),那么它一定是指非同步分區(qū)的數(shù)量。該度量指明了作為首領(lǐng)的 broker 有多少個(gè)分區(qū)處于非同步狀態(tài)。這個(gè)度量可以反映 Kafka 的很多內(nèi)部問題,從 broker 的崩潰到資源的過度消耗。
集群?jiǎn)栴}
集群?jiǎn)栴}一般分為以下兩類:
不均衡的負(fù)載。
資源過度消耗。
流入和流出速率
流出速率也包括副本流量,也就是說,如果所有主題都設(shè)置了復(fù)制系數(shù) 2,那么在沒有消費(fèi)者客戶端的情況下,流出速率與流入速率是一樣的。
流式處理
流式處理是指實(shí)時(shí)地處理一個(gè)或多個(gè)事件流。流式處理是一種編程范式,就像請(qǐng)求與響應(yīng)范式和批處理范式那樣。
只要持續(xù)地從一個(gè)無邊界的數(shù)據(jù)集讀取數(shù)據(jù),然后對(duì)它們進(jìn)行處理并生成結(jié)果,那就是在進(jìn)行流式處理。重點(diǎn)是,整個(gè)處理過程必須是持續(xù)的。
表與流
在將表與流進(jìn)行對(duì)比時(shí),可以這么想:流包含了變更——流是一系列事件,每個(gè)事件就是一個(gè)變更。表包含了當(dāng)前的狀態(tài),是多個(gè)變更所產(chǎn)生的結(jié)果。所以說,表和流是同一個(gè)硬幣的兩面——世界總是在發(fā)生變化,用戶有時(shí)候關(guān)注變更事件,有時(shí)候則關(guān)注世界的當(dāng)前狀態(tài)。如果一個(gè)系統(tǒng)允許使用這兩種方式來查看數(shù)據(jù),那么它就比只支持一種方式的系統(tǒng)強(qiáng)大。
時(shí)間窗口
如果“移動(dòng)間隔”與窗口大小相等,這種情況被稱為“滾動(dòng)窗口(tumbling window)”。如果窗口隨著每一條記錄移動(dòng),這種情況被稱為“滑動(dòng)窗口(sliding window)”。
變更數(shù)據(jù)捕捉(Change Data Capture)
如果能夠捕捉數(shù)據(jù)庫的變更事件,并形成事件流,流式處理作業(yè)就可以監(jiān)聽事件流,并及時(shí)更新緩存。捕捉數(shù)據(jù)庫的變更事件并形成事件流,這個(gè)過程被稱為 CDC——變更數(shù)據(jù)捕捉(Change Data Capture)。
基于時(shí)間窗口的連接(windowed-join)
如果要連接兩個(gè)流,那么就是在連接所有的歷史事件——將兩個(gè)流里具有相同鍵和發(fā)生在相同時(shí)間窗口內(nèi)的事件匹配起來。這就是為什么流和流的連接也叫作基于時(shí)間窗口的連接(windowed-join)。