新疆所有的網(wǎng)站百度知道客服
1、Kafka是何如做到高性能的?
a、消息批處理減少網(wǎng)絡(luò)通信開銷,提升系統(tǒng)吞吐能力(先攢一波,消息以“批”為單位進(jìn)行處理)
生產(chǎn)端:無論是同步發(fā)送還是異步發(fā)送,Kafka都不會立即就把這條消息發(fā)送出去。而是先把這條消息存放在內(nèi)存中緩存起來,然后選擇合適的時機(jī)把緩存中的所有消息成批的一次性發(fā)給Broker
Broker:整個處理流程中,無論是寫入磁盤、從磁盤讀出來、還是復(fù)制到其他副本,批消息都不會被解開,一直是作為一條“批消息”來進(jìn)行處理
消費端:消息同樣以批為單位進(jìn)行傳遞,Consumer 從 Broker拉到一批消息后,在客戶端進(jìn)行批消息解開,再一條一條交給用戶代碼處理
構(gòu)建批消息和解開批消息分別在發(fā)送端和消費端的客戶端完成,不僅減輕了 Broker 的壓力,最重要的是減少了 Broker 處理請求的次數(shù),提升了總體的處理能力。
b、順序讀寫減少尋址次數(shù),提升磁盤 IO 性能?
????????基于磁盤文件高性能順序讀寫的特性來設(shè)計的存儲結(jié)構(gòu) ,順序讀寫相比于隨機(jī)讀寫省去了很多尋址時間,它只要尋址一次,就可以連續(xù)地進(jìn)行讀寫,所以性能要比隨機(jī)讀寫要好很多(固態(tài)硬盤順序讀寫的性能比隨機(jī)讀寫快幾倍、機(jī)械硬盤差距會達(dá)到幾十倍)
c、利用PageCache 加速消息讀寫,減少 IO開銷
????????程序在調(diào)用系統(tǒng)的API進(jìn)行讀寫文件時,實際操作的都是 PageCache(文件在內(nèi)存中緩存的副本)并不會直接去讀寫磁盤上的文件,大部分情況下,消費讀消息都會命中 PageCache,一個是讀取的速度會非???#xff0c;另外一個是,給寫入消息讓出磁盤的 IO 資源,間接也提升了寫入的性能。
????????根據(jù)局部性原理,通常剛被訪問的數(shù)據(jù)在短時間內(nèi)再次被訪問的概率很高,PageCache用來緩存最近被訪問的數(shù)據(jù),當(dāng)空間不足時淘汰最久未被訪問的緩存,所以讀磁盤數(shù)據(jù)的時,優(yōu)先在 PageCache查找,如果數(shù)據(jù)存在則可以直接返回;如果沒有再從磁盤中讀取,然后緩存PageCache中(消息隊列的場景一般都是發(fā)送即接收,PageCache利用率很高)
????????缺點:在傳輸大文件(GB 級別的文件)時,PageCache會不起作用,浪費一次數(shù)據(jù)拷貝,造成性能下降,即使使用了 PageCache 的零拷貝也會損失性能?
????????PageCache(磁盤高速緩存):操作系統(tǒng)在內(nèi)存中給磁盤上文件建立的緩存
d、使用零拷貝(ZeroCopy)減少數(shù)據(jù)拷貝開銷
borker中消息的消費流程:從文件中找到消息數(shù)據(jù)讀到內(nèi)存中;然后把消息通過網(wǎng)絡(luò)發(fā)給客戶端
- 從文件復(fù)制數(shù)據(jù)到 PageCache 中,如果命中 PageCache,可以省掉;
- 從 PageCache 復(fù)制到應(yīng)用程序的內(nèi)存空間中,也就是我們可以操作的對象所在的內(nèi)存;
- 從應(yīng)用程序的內(nèi)存空間復(fù)制到 Socket 的緩沖區(qū),這個過程就是我們調(diào)用網(wǎng)絡(luò)應(yīng)用框架的 API 發(fā)送數(shù)據(jù)的過程。
????????Kafka 使用零拷貝技術(shù)可以把這個復(fù)制次數(shù)減少一次,上面的 2、3 步驟兩次復(fù)制合并成一次復(fù)制。直接從 PageCache 中把數(shù)據(jù)復(fù)制到 Socket 緩沖區(qū)中,這樣不僅減少一次數(shù)據(jù)復(fù)制,更重要的是,由于不用把數(shù)據(jù)復(fù)制到用戶內(nèi)存空間,DMA 控制器可以直接完成數(shù)據(jù)復(fù)制,不需要 CPU 參與,速度更快
擴(kuò)展:在Unix-like操作系統(tǒng)中 mmap/sendfile 用于實現(xiàn)零拷貝
mmap:允許將一個文件映射到進(jìn)程的地址空間中,使得文件的內(nèi)容可以直接通過內(nèi)存訪問,而無需通過讀取和寫入系統(tǒng)調(diào)用。這樣可以實現(xiàn)零拷貝,因為數(shù)據(jù)可以直接從文件映射的內(nèi)存區(qū)域傳輸?shù)骄W(wǎng)絡(luò)或其他設(shè)備,而無需在用戶空間和內(nèi)核空間之間復(fù)制數(shù)據(jù)。在Java中,可以使用FileChannel的map()方法來實現(xiàn)內(nèi)存映射。 sendfile:是一個系統(tǒng)調(diào)用,允許將一個文件的內(nèi)容直接從內(nèi)核空間傳輸?shù)搅硪粋€文件描述符(通常是網(wǎng)絡(luò)套接字)中,無需在用戶空間和內(nèi)核空間之間復(fù)制數(shù)據(jù)。這可以在發(fā)送文件時實現(xiàn)零拷貝,在Java中,可以使用FileChannel的transferTo()方法或transferFrom()方法來使用sendfile進(jìn)行文件傳輸
e、其他
全異步化的線程模型、高性能的異步網(wǎng)絡(luò)傳輸、自定義的私有傳輸協(xié)議的序列化、反序列化
2、kafka是如何實現(xiàn)復(fù)制的?
Kafka的復(fù)制基本單位是分區(qū),每個分區(qū)的幾個副本之間采用一主多從,構(gòu)成一個小的復(fù)制集群,Broker 只是這些分區(qū)副本的容器。
Kafka 寫入消息時采用的是異步復(fù)制方式,消息寫入主節(jié)點之后,并不馬上返回寫入成功,而是等待用戶指定個數(shù)的副本節(jié)點都復(fù)制成功后再返回。
配置副本節(jié)點數(shù):ISR(In Sync Replicas) 即:保持?jǐn)?shù)據(jù)同步的副本 ;PS:ISR中是包含主節(jié)點的
如果所有的 ISR 節(jié)點都宕機(jī)了,分區(qū)就無法提供服務(wù)了。也可以選擇配置成讓分區(qū)繼續(xù)提供服務(wù),這樣只要有一個節(jié)點還活著,就可以提供服務(wù),代價是無法保證數(shù)據(jù)一致性,會丟消息。
高可用:Kafka 采用 ZooKeeper 監(jiān)控每個分區(qū)的多個節(jié)點,如果發(fā)現(xiàn)某個分區(qū)的主節(jié)點宕機(jī)了,會通過 ZooKeeper 選舉方式選出一個新的主節(jié)點,選舉時會從所有 ISR 節(jié)點中來選新的主節(jié)點,這樣可以保證數(shù)據(jù)一致性。