看完就入门系列!吞吐量、消息持久化、负载均衡和持久化、伸缩性…… 你真的了解 Kafka 了吗?...
作者|?liuhehe123
來源|?CSDN博客?責編|?Carol
出品|?CSDN云計算(ID:CSDNcloud)
封圖|?CSDN下載于視覺中國?
無論是已經接觸過 Kafka 還是剛入坑的小伙伴,都應該時不時回頭了解一下 Kafka ,有時候會有不少新收獲。今天這份 Kafka 的介紹,建議再認真閱讀一遍哦~
Kafka在設計之初就考慮的問題:
吞吐量/延時
消息持久化
負載均衡和持久化
伸縮性
吞吐量
kafka是如何做到高吞吐量和低延時的呢?
kafka的寫入操作是很快的,這主要得益于它對磁盤的使用方法不同。雖然kafka會持久化所有數據到磁盤,但本質上每次寫入操作其實都只是把數據寫入到操作系統的頁緩存中,然后由操作系統自行決定什么時候把頁緩存中的數據寫回磁盤。
先說kafka是咋實現的,kafka依靠下列4點達到了高吞吐量、低延時的設計目標:
大量使用操作系統葉緩存,內存操作速度快且命中率高。
kafka不直接參與物理I/O操作,而是交給最擅長此事的操作系統來完成。
采用追加寫入的方式,摒棄了緩慢的磁盤隨機讀寫操作。
使用以sendfile為代表的的零拷貝技術加強網絡間的數據傳輸效率。
前三個都是使用頁緩存的好處,頁緩存是在內存中分配的,所以寫入消息很快。使得kafka不必直接與底層文件系統打交道。另外采用追加的方式寫入,避免了磁盤隨機寫操作。
零拷貝:
簡而言之,就是避免讓CPU做大量的數據拷貝技術,采用不使用CPU時間的技術進行系統內核緩沖區之間的數據拷貝。
從上圖中可以看出,共產生了四次數據拷貝,即使使用了DMA來處理了與硬件的通訊,CPU仍然需要處理兩次數據拷貝,與此同時,在用戶態與內核態也發生了多次上下文切換,無疑也加重了CPU負擔。
1、讓數據傳輸不需要經過user space
我們減少拷貝次數的一種方法是調用mmap()來代替read調用:
buf?=?mmap(diskfd,?len);write(sockfd,?buf,?len);應用程序調用mmap(),磁盤上的數據會通過DMA被拷貝的內核緩沖區,接著操作系統會把這段內核緩沖區與應用程序共享,這樣就不需要把內核緩沖區的內容往用戶空間拷貝。應用程序再調用write(),操作系統直接將內核緩沖區的內容拷貝到socket緩沖區中,這一切都發生在內核態,最后,socket緩沖區再把數據發到網卡去。
2、sendfile
使用sendfile不僅減少了數據拷貝的次數,還減少了上下文切換,數據傳送始終只發生在kernel space。下圖為使用DMA的sendfile零拷貝技術圖。
消息持久化
kafka是要持久化消息的,而且要將消息持久化到磁盤上的。
先說這樣做的好處(為什么要持久化):
解耦消息發送與消息消費:通過將消息持久化使得生產者不再需要直接和消費者方耦合,它只是簡單地把消息生產出來并交由kafka服務器保存起來即可。
實現靈活的消息處理(便于消息重演):很多kafka下游子系統(消費方)都會有這樣的需求——對于已經處理過的消息可能在未來的某個時間點重新處理一次,即所謂的消息重演(message replay)。
那么kafka持久化是咋做的呢?
對比一下:
普通的系統實現持久化時可能先盡量使用內存,當內存資源耗盡時,再一次性地把數據 “刷盤”;kafka則反其道行之,所有數據都會立即被寫入到文件系統的持久化日志中,之后kafka服務器才會返回結果給客戶端,通知客戶端消息寫入成功。這樣做即實時保存了數據,又減少了kafka程序對于內存的消耗,從而將節省出的內存留給頁緩存使用,進一步提升整體性能。
這里解釋下:kafka在吞吐量中說使用頁緩存,持久化又說盡量減少對內存的消耗,這是咋回事?
總的來說,Kafka不會保持盡可能多的內容在內存空間,而是盡可能把內容直接寫入到磁盤。所有的數據都及時的以追加的方式寫入到文件系統的持久化日志中,而不必要把內存中的內容刷新到磁盤中。
負載均衡和故障轉移
kafka作為一個完備的分布式系統,肯定也是要滿足負載均衡和故障轉移處理操作的。
負載均衡:kafka的負載均衡是通過智能化的分區領導者選舉來實現的。可以在集群中的所有機器上以均等的機會分散各個partition的leader,從而整體上實現了負載均衡。【后面進行補充】
故障轉移(使用zookeeper):即當服務器意外中止時,整個集群能夠快速檢測到他失效了,并立即將該服務器上的應用或服務轉移到其他機器上。kafka使用的是會話機制來解決的。每臺kafka服務器啟動后會以會話的形式把自己注冊到zookeeper服務器上,一旦該服務器運轉出現問題,與zookeeper的會話便不能維持從而超時失效,此時kafka會選舉出一臺新的服務器賴萬全代替這臺服務器繼續提供服務。
伸縮性
伸縮性指的是:向分布式系統系統中增加額外的計算資源時提升吞吐量的能力。
如果服務器是無狀態的,狀態的保存和管理交給專門的協調服務來做,比如 zookeeper ,那么整個集群的服務器之間就不需要再進行繁重的狀態共享,這極大地降低了維護復雜度。
Kafka 正式采用了這一思想——每臺kafka的服務器上的狀態統一交由Zookeeper保管。而擴展kafka集群就很容易:啟動一臺新的kafka服務器即可。
需要說明的一點是,kafka服務器并不是所有狀態都不保存,他只是保存了很輕量級的內部狀態,所以整個集群間維護狀態一致性的代價很低。
來看看kafka的基本概念和術語
目前kafka最新的版本是 2.4。
1、broker、topic、partition、offset、replica、leader和follower
下面是Kafka的大致架構圖:
Kafka服務器官方稱呼為:broker。
先來說說Kafka的消息格式是啥樣的?
消息由三部分組成:消息頭部、key 和 value。
消息頭:包括CRC碼、消息版本、屬性、時間戳、鍵長度和消息體長度等信息。
Key: 消息鍵, 對消息做partition時使用,即決定消息被保存在某個topic下的那個partition。
Value:消息體,保存實際的消息數據。
Timestamp: 消息發送時間戳。
2、kafka的Topic和Partition 到底是個什么東西?
Topic(主題): topic代表了一類消息,也可以認為消息被發送到的地方。比如業務A使用一個topic, 業務B使用另外一個topic。相當于 柴雞蛋和茶葉蛋這樣簡單分下。
Partition(分區)???? 一個Topic可以由多個partition組成,而kafka的partition是不可修改的有序消息序列。分區是物理層面的,用戶是看不到的,用戶不用管這些消息怎么取出來的,之所以做分區,主要是為了提高系統的吞吐量。
3、offset
一個(生產的)消息的寫入offset位移值, 一個是消費者端的消費位移offset。他倆是不同的概念。
消費該partition的消費者位移會隨著消費進度不斷前移,不過終究不可能超過該分區的最新一條消息的位移。
kafka的一條消息其實就是一個三元組:<topic, partition, offset> 三元組(tuple),通過該元組值能夠在kafka集群中找到唯一對應的那條消息。
4、replica
kafka的冗余機制,備份多份日志,這些備份日志在kafka中被稱為副本(replica),他們存在就是為了 防止數據丟失的。
5、leader和follower
leader提供對外服務,follower與leader保持同步,follower存在的目的就是用來充當leader的候補。
6、ISR(同步副本集合)
kafka為partition動態維護了一個replica集合,該集合中的所有replica保存的消息日志都與leader replica 保持同步狀態。
記住,只有這個集合(ISR)中的replica才能被選為leader,也只有這個集合中的所有replica都接受到了同一條消息,Kafka才會將消息置于 “已提交” 狀態,即認為這條消息發送成功。
【這里不要與producer端搞混,producer端的參數acks設置 0、all/-1 、1的情況,會在后面的文章補充。】
7、kafka使用場景
消息傳輸
網站行為日志跟蹤
日志收集
流式處理
零拷貝部分參考作者以及鏈接:
作者:卡巴拉的樹 https://www.jianshu.com/p/fad3339e3448
本文來源 CSDN 博客,原文鏈接:
https://blog.csdn.net/liuhehe123/article/details/105429934
同時,歡迎所有開發者掃描下方二維碼填寫《開發者與AI大調查》,只需2分鐘,即可收獲價值299元的“ AI開發者萬人大會”在線直播門票!
推薦閱讀:小網站的容器化(下):網站容器化的各種姿勢,先跟著擼一波代碼再說! 你知道嗎?其實Oracle直方圖自動統計算法存在這些缺陷!(附驗證步驟) 詳解以太坊虛擬機(EVM)的數據存儲機制 比特幣當贖金,WannaRen勒索病毒二度來襲!平臺抗住日訪問量7億次,研發品控流程全公開“手把手撕開LeetCode翻譯,扒各種算法套路的褲子”北京四環堵車引發的智能交通大構想 真香,朕在看了!總結
以上是生活随笔為你收集整理的看完就入门系列!吞吐量、消息持久化、负载均衡和持久化、伸缩性…… 你真的了解 Kafka 了吗?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 涨姿势,一个通信项目从开始到结束,原来还
- 下一篇: 华为:跨过时艰,向未来