消息保存或緩存在磁盤上,一般認(rèn)為磁盤讀寫數(shù)據(jù)是會(huì)降低性能,因?yàn)?b>尋址會(huì)消耗時(shí)間,實(shí)際Kafka特性之一是高吞吐率。
Kafka輕松支持普通服務(wù)器每秒百萬(wàn)級(jí)寫入請(qǐng)求,超過(guò)了大部分的消息中間件,在日志處理等海量數(shù)據(jù)場(chǎng)景廣泛應(yīng)用。
基準(zhǔn)測(cè)試參考:Apache Kafka基準(zhǔn)測(cè)試:每秒寫入2百萬(wàn)(在三臺(tái)廉價(jià)機(jī)器上)
一、寫入數(shù)據(jù)
優(yōu)化寫入速度用兩個(gè)技術(shù):順序?qū)懭?和 MMFile 。
1.1 順序?qū)懭?/h4>
Linux對(duì)磁盤讀寫優(yōu)化:read-ahead和write-behind,磁盤緩存等。內(nèi)存做這些操作,JAVA對(duì)象內(nèi)存開銷大,堆內(nèi)存數(shù)據(jù)增多,GC時(shí)間長(zhǎng),磁盤好處:
(1)順序讀寫速度超過(guò)內(nèi)存隨機(jī)讀寫:每次讀寫都尋址(“機(jī)械動(dòng)作”最耗時(shí))
(2)JVM的GC效率低,內(nèi)存占用大。磁盤可避免
(3)系統(tǒng)冷啟動(dòng)后,磁盤緩存依然可用
每個(gè)Partition都是一個(gè)文件 ,收到消息后Kafka會(huì)把數(shù)據(jù)插入到文件末尾(虛框部分)。
缺陷:不能刪除數(shù)據(jù) ,每個(gè)消費(fèi)者(Consumer)對(duì)每個(gè)Topic都有一個(gè)offset表示 讀到第幾條數(shù)據(jù)

Consumer1有兩個(gè)offset分別對(duì)應(yīng)Partition0、Partition1(假設(shè)每一個(gè)Topic一個(gè)Partition);Consumer2有一個(gè)offset對(duì)應(yīng)Partition2。offset是由客戶端SDK負(fù)責(zé)保存,Kafka的Broker完全無(wú)視這個(gè)東西的存在;一般情況下SDK會(huì)把它保存到zookeeper里面。(所以需要給Consumer提供zookeeper的地址)。
解決:Kakfa刪除數(shù)據(jù)策略:(1)基于時(shí)間,(2)基于partition文件大小(配置文檔看具體配置)。
1.2 Memory Mapped Files(mmap內(nèi)存映射文件)
出現(xiàn)原因:順序寫入硬盤,硬盤訪問(wèn)速度還是不可能追上內(nèi)存。Kafka不是實(shí)時(shí)寫入硬盤 ,利用了操作系統(tǒng) 分頁(yè)存儲(chǔ)(用內(nèi)存提高I/O效率) 。
工作原理:操作系統(tǒng)Page實(shí)現(xiàn)文件到物理內(nèi)存的直接映射。對(duì)物理內(nèi)存的操作會(huì)同步到硬盤(操作系統(tǒng)適當(dāng)時(shí))。64位操作系統(tǒng)中可表示20G數(shù)據(jù)文件
用途:進(jìn)程像讀寫硬盤一樣讀寫內(nèi)存(當(dāng)然是虛擬機(jī)內(nèi)存),不必關(guān)心內(nèi)存大小,虛擬內(nèi)存兜底。
好處:I/O提升, 省去用戶空間到內(nèi)核空間 復(fù)制開銷(調(diào)用文件的read會(huì)把數(shù)據(jù)先放到內(nèi)核空間的內(nèi)存中,然后再?gòu)?fù)制到用戶空間的內(nèi)存中。)
缺點(diǎn):不可靠, 寫到mmap中的數(shù)據(jù),沒(méi)被真正寫到硬盤,操作系統(tǒng)會(huì)在程序主動(dòng)調(diào)用flush的時(shí)候才把數(shù)據(jù)真正寫到硬盤。
Kafka提供了參數(shù)producer.type來(lái)控制是不是主動(dòng)flush,如果Kafka寫入到mmap之后就立即flush然后再返回Producer叫 同步 (sync);寫入mmap之后立即返回Producer不調(diào)用flush叫 異步 (async)。
二、讀取數(shù)據(jù)
基于sendfile實(shí)現(xiàn)Zero Copy,sendfile系統(tǒng)調(diào)用減少多次copy,提升文件傳輸性能
2.1 傳統(tǒng)模式文件傳輸流程(read/write方式):
1.文件數(shù)據(jù)被copy到內(nèi)核緩沖區(qū)(調(diào)read函數(shù)),2.然后到用戶緩沖區(qū)(read函數(shù)返回),3.再到內(nèi)核與socket相關(guān)緩沖區(qū)(write函數(shù)調(diào)用)
4.相關(guān)協(xié)議引擎
四次copy操作:硬盤—>內(nèi)核buf—>用戶buf—>socket相關(guān)緩沖區(qū)—>協(xié)議引擎

2.2 簡(jiǎn)化網(wǎng)絡(luò)上和兩個(gè)本地文件之間的數(shù)據(jù)傳輸
引入sendfile系統(tǒng)調(diào)用,減少數(shù)據(jù)復(fù)制、上下文切換。
(1)sendfile(socket, file, len)運(yùn)行流程:? ? 減少到user緩沖區(qū)
1.文件數(shù)據(jù)被copy至內(nèi)核緩沖區(qū)(sendfile系統(tǒng)調(diào)用),2.至內(nèi)核中socket相關(guān)緩沖區(qū),3.協(xié)議引擎? ? ?
(2)優(yōu)點(diǎn):1)2.1linux內(nèi)核引進(jìn)sendfile:減少內(nèi)核緩沖區(qū)到user緩沖區(qū),再到socket相關(guān)緩沖區(qū)文件copy? 2)2.4后,文件描述符結(jié)果被改變:僅將記錄數(shù)據(jù)位置和長(zhǎng)度數(shù)據(jù)存 socket緩存。實(shí)際數(shù)據(jù)由DMA模塊直接發(fā)送到協(xié)議引擎,減少一次copy。(4次,變2次,變1次)
(3)在apache,nginx,lighttpd等web服務(wù)器當(dāng)中,都有一項(xiàng)sendfile相關(guān)的配置,提升文件傳輸性能。
Kafka把所有的消息都存放在一個(gè)個(gè)文件中,當(dāng)消費(fèi)者需要數(shù)據(jù)的時(shí)候Kafka直接把文件發(fā)送給消費(fèi)者,配合mmap作為文件讀寫方式,直接把它傳給sendfile。
三、批量壓縮
系統(tǒng)瓶頸是網(wǎng)絡(luò)IO,不是CPU或磁盤,數(shù)據(jù)壓縮消耗CPU資源少,
批量壓縮,多個(gè)消息一起壓,如每個(gè)消息都?jí)嚎s,壓縮率低,
Kafka用遞歸消息集合,傳輸并保持壓縮格式(在日志中),直到被消費(fèi)者解壓縮
Kafka支持多種壓縮協(xié)議(Gzip和Snappy壓縮協(xié)議)
總結(jié)
Kafka速度秘訣:
(1)讀取數(shù)據(jù)時(shí)配合sendfile直接暴力輸出
(2)寫入數(shù)據(jù):順序?qū)懭?/b>,單個(gè)Partion是末尾添加所以速度最優(yōu)。
(3)批量壓縮把所有消息變成一個(gè)批量文件,合理減少網(wǎng)絡(luò)IO損耗,通過(guò)mmap提高I/O速度。
https://www.cnblogs.com/binyue/p/10308754.html