零復(fù)制
Kafka 使用零復(fù)制技術(shù)向客戶端發(fā)送消息——也就是說泣棋,Kafka 直接把消息從文件(或者更確切地說是 Linux 文件系統(tǒng)緩存)里發(fā)送到網(wǎng)絡(luò)通道,而不需要經(jīng)過任何中間緩沖區(qū)。這是 Kafka 與其他大部分?jǐn)?shù)據(jù)庫(kù)系統(tǒng)不一樣的地方耗跛,其他數(shù)據(jù)庫(kù)在將數(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ù)庫(kù)的速度不會(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)建可以分為兩大陣營(yíng)蜒秤,即 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ù)庫(kù)的變更事件侄柔,并形成事件流共啃,流式處理作業(yè)就可以監(jiān)聽事件流,并及時(shí)更新緩存暂题。捕捉數(shù)據(jù)庫(kù)的變更事件并形成事件流移剪,這個(gè)過程被稱為 CDC——變更數(shù)據(jù)捕捉(Change Data Capture)。
基于時(shí)間窗口的連接(windowed-join)
如果要連接兩個(gè)流薪者,那么就是在連接所有的歷史事件——將兩個(gè)流里具有相同鍵和發(fā)生在相同時(shí)間窗口內(nèi)的事件匹配起來纵苛。這就是為什么流和流的連接也叫作基于時(shí)間窗口的連接(windowed-join)。