上篇博文已經講解了如何安裝Kafka的集群環(huán)境凭豪,今天我們就來一本帶大家了解下Kafka,了解kafka的特點以及基本概念
kafka的特點
Kafka設計的初衷是為了解決互聯(lián)網公司超大量級數據的實時傳輸娄蔼,為了實現這個目標,需要考慮以下四個方面的問題
- 吞吐量/延時
- 消息持久化
- 負載均衡和故障轉移
- 伸縮性
- 吞吐量是Kafka每秒能夠處理的消息數,那么很顯然撒遣,我們都希望系統(tǒng)的吞吐量越大越好喳逛,與此同時瞧捌,還有個客戶端發(fā)送指令,kafka服務端接受指令然后反饋給客戶端的時間润文,這個時間就是延時姐呐,那么對于一個系統(tǒng)而言,延時時間間隔越短越好典蝌。而kafka是一個高吞吐量和低延時的系統(tǒng)曙砂,那么他是如何實現的呢?
- 大量使用操作系統(tǒng)頁緩存骏掀,內存的操作速度快且命中率高
由于大量使用也緩存鸠澈,故讀取消息時大部分消息很有可能依然保存在頁緩存中,因此可以直接命中緩存截驮,不用“穿透”到底層的物理磁盤上獲取消息笑陈,從而極大的提升了讀取的吞吐量
- kafka不直接參與物理I/O操作,而是交由最擅長此事的操作系統(tǒng)來完成
- 采用追加寫入方式葵袭,摒棄了緩慢的磁盤隨機I/O操作
kafka在設計時采用了追加寫入消息的方式涵妥,即只能在日志文件末尾追加寫入新的消息,且不允許修改已經寫入的消息坡锡,因此他屬于典型的磁盤順序訪問型操作蓬网,這種類型的操作訪問速度堪比內存的讀寫速度,性能是非常高的
- 使用sendfile為代表的零拷貝技術加強網絡間的數據傳輸效率
kafka在讀取消息時鹉勒,會首先從OS的頁緩存中讀取拳缠,如果命中便把消息經頁緩存直接發(fā)送到網絡的Socket上,這個過程就是零拷貝技術
- 消息引擎都必須要具有持久化的機制贸弥,持久化的機制有如下的好處:
- 讓消息的生產和消費解耦
消息生產者只需要將消息發(fā)送給kafka即可窟坐,不必關系消息是被誰消費的,何時消費的
- 靈活的消息處理
消息保存在kafka中绵疲,方便實現消息重演這樣的需求哲鸳,可以很方便的處理消息
- 減少內存的使用
將消息持久化到kafka中,給內存釋放出更多的空間盔憨,方便kafka使用頁面緩存技術來提升系統(tǒng)的性能
- kafka是一個分布式流處理平臺徙菠,所以kafka具有分布式系統(tǒng)的兩個重要的特性——負載均衡和故障轉移
- 負載均衡就是讓系統(tǒng)的負載根據一定的規(guī)則均衡的分配到所有參與工作的機器上似芝,從而最大限度的提升整體系統(tǒng)的運行效率酪耳,kafka的負載均衡實際上是通過partition以及l(fā)eader來實現的姐军,后面再詳細介紹
- 當分布式系統(tǒng)的一個節(jié)點出現了問題器净,無法發(fā)送心跳或者會話,則master服務器認為備份服務器已經無法工作 萍摊,將會根據一系列的算法來計算新的節(jié)點挤茄,實現了系統(tǒng)的高可用性
- 伸縮性,所謂的伸縮性表示向分布方式中額外的增加計算資源時吞吐量提升的能力冰木,通俗點來講穷劈,就是如何通過增加節(jié)點來擴展kafka集群環(huán)境的系統(tǒng),這點kafka是通過將服務器的狀態(tài)的相關的參數交給zookeeper來管理
kafka的基本概念
- 消息
消息是每一個消息引擎的重中之重踊沸,好的消息的結構設計能極大的優(yōu)化系統(tǒng)的性能歇终,這里kafka處理的非常好,我們也有必要理解下kafka的消息的組成以及為什么
首先消息是由:消息頭部逼龟、Key和Value組成评凝,其中消息頭部還包括:CRC、版本號腺律、屬性奕短、時間戳和鍵長度。
這里主要說明4個字段的含義:
- 消息鍵:對消息做partition時使用疾渣,即決定消息被保存在某個topic下的哪個partition
- 消息體:保存實際的消息數據
- 時間戳:消息發(fā)送的時間戳篡诽,主要用于流式處理以及其他依賴時間的處理語義,默認是當前時間
- 屬性:kafka使用一個字節(jié)來保存消息的壓縮屬性榴捡,當前只支持4中壓縮屬性:0——無壓縮 1——GZIP壓縮 2——Snappy壓縮 3——LZ4壓縮
Kafka使用二進制字節(jié)數組來保存消息杈女,這個和RabbitMQ是一樣的,為什么要這樣設計呢吊圾? 試想一下达椰,如果我們使用Java的類來實現,如果存儲成String字符串格式 项乒,那么對于Java內存模型啰劲,對象保存的開銷是很大的,隨著堆里面的數據量越來越大檀何,GC的也就越頻繁蝇裤,那么系統(tǒng)的性能也就越差,其他Java的操作系統(tǒng)通常默認是開啟頁緩存機制的频鉴,也就是說堆上保存的對象可能在頁緩存中還保留一份栓辜,這也造成了極大的資源浪費
因此,kafka在消息設計時垛孔,直接使用緊湊二進制字節(jié)數據藕甩,這樣我們就能有更多的內存使用
- topic和partition
準確來說,topic
是一個邏輯上的概念周荐,一般我們用來作為業(yè)務上的一個區(qū)分的尺度狭莱,代表一類消息僵娃,比如說A發(fā)送消息到topicA中,B發(fā)送消息到topicB中腋妙,一個topic
可能被多個消費者來消費默怨,為了提供系統(tǒng)的吞吐量,kafka提出了partition
的概念辉阶,我們可以認為一個topic
是由多個partition
組成的
kafka中的partition
是不可修改的有序消息隊列先壕,每個partition
有自己專屬的partition
號瘩扼,通常是從0開始的谆甜,用戶對partition
唯一能做的就是在消息隊列的尾部追加寫入消息,每個消息隊列中都有一個序號集绰,這個序號就是接下里要說的 offset
- offset
partition
中的每個消息隊列都是固定的规辱,并且從0開始遞增
綜合之前所說的topic
和partition
以及offset
我們可以確定一條消息
- replica
我們知道partition
是有序的消息隊列,那么一定不是保存在一個地方的栽燕,否則一旦kafka掛了罕袋,其上保存的消息也就丟失了,分布式要實現高可用性碍岔,這里kafka采用了冗余機制——備份多個日志浴讯,這些日志在kafka中就被稱為replica
副本,他存在的唯一目的就是防止數據丟失
replica
分為: leader replica
和follower replica
,follower replica
唯一的用途就是leader replica
所在的broker
宕機了蔼啦,不能對外提供服務了榆纽,則kafka就會從剩余的replica
中選舉新的leader來提供服務
- leader和follower
上面我們說過什么是leader
和follower
,在kafka中,leader
對外提供服務捏肢,follower
只能被動的追隨leader
的狀態(tài)奈籽,保持與leader
同步,follower
唯一存在的目的就是當leader
宕機了鸵赫,被選舉稱為新的leader
來繼續(xù)提供服務
kafka保證統(tǒng)一個partition
的多個replica
一定不會分配在同一臺broker
上衣屏,畢竟如果同一個broker
上有同一個partition
的多個replica
,那么將無法實現備份冗余的效果
- ISR
ISR(in-sync replica)在kafka中是一個重要的概念, 翻譯過來就是與 leader replica保持同步的replica集合辩棒, kafka為partition
動態(tài)維護一個replica
集合狼忱,該集合中的所有的replica保存的消息日志都與leader replica
保持同步狀態(tài),只有這個集合中的replica
才能被選為leader
,也只有該集合中的replica
都同時接收到同一條消息一睁,kafka才會將該消息置為“已提交”狀態(tài)钻弄,即認為該條消息發(fā)送成功
這里需要注意兩點:
- ISR中至少需要一個“活著”的
replica
- “已提交”消息