搞定這8個(gè)Kafka生產(chǎn)級容量評估,每日10億+請求輕松拿捏!
一、kafka容量評估需求場景分析
1、集群如何每天hold住10億+請求
拿電商平臺為例,kafka 集群每天需要承載10億+請求流量數(shù)據(jù),一天24小時(shí),對于平臺來說,晚上12點(diǎn)到凌晨8點(diǎn)這8個(gè)小時(shí)幾乎沒多少數(shù)據(jù)涌入的。這里我們使用「二八法則」來進(jìn)行預(yù)估,也就是80%的數(shù)據(jù)(8億)會在剩余的16個(gè)小時(shí)涌入,且8億中的80%的數(shù)據(jù)(約6.4億)會在這16個(gè)小時(shí)的20%時(shí)間 (約3小時(shí))涌入。
通過上面的場景分析,可以得出如下:
QPS計(jì)算公式 = 640000000 ÷ (3 * 60 * 60) = 6萬,也就是說高峰期集群需要扛住每秒6萬的并發(fā)請求。
假設(shè)每條數(shù)據(jù)平均按20kb(生產(chǎn)端有數(shù)據(jù)匯總)來算, 那就是 1000000000 * 20kb = 18T,一般情況下我們都會設(shè)置3個(gè)副本,即54T,另外 kafka 數(shù)據(jù)是有保留時(shí)間周期的, 一般情況是保留最近3天的數(shù)據(jù),即 54T * 3 = 162T。
2、場景總結(jié)
要搞定10億+請求,高峰期要支撐6萬QPS,需要大約162T的存儲空間。
二、kafka容量評估之物理機(jī)數(shù)量
1、物理機(jī) OR 虛擬機(jī)
一般對于Kafka,Mysql,Hadoop 等集群自建的時(shí)候,都會使用物理機(jī)來進(jìn)行搭建,性能和穩(wěn)定性相對虛擬機(jī)要強(qiáng)很多。
2、物理機(jī)數(shù)量計(jì)算
在第一步中我們分析得出系統(tǒng)高峰期的時(shí)候要支撐6萬QPS,如果公司資金和資源充足的情況下,我們一般會讓高峰期的QPS控制在集群總承載QPS能力的30%左右,這樣的話可以得出集群能承載的總QPS能力約為20萬左右,這樣系統(tǒng)才會是安全的。
3、場景總結(jié)
根據(jù)經(jīng)驗(yàn)可以得出每臺物理機(jī)支撐4萬QPS是沒有問題的,從QPS角度分析,我們要支撐10億+請求,大約需要5臺物理機(jī),考慮到消費(fèi)者請求,需要增加約1.5倍機(jī)器,即7臺物理機(jī)。
三、kafka容量評估之磁盤
1、機(jī)械硬盤 OR 固態(tài)硬盤SSD
兩者主要區(qū)別如下:
- SSD就是固態(tài)硬盤,它的優(yōu)點(diǎn)是速度快,日常的讀寫比機(jī)械硬盤快幾十倍上百倍。缺點(diǎn)是單位成本高,不適合做大容量存儲。
- HDD就是機(jī)械硬盤,它的優(yōu)點(diǎn)是單位成本低,適合做大容量存儲,但速度遠(yuǎn)不如SSD。
首先SSD硬盤性能好,主要是指的隨機(jī)讀寫能力性能好,非常適合Mysql這樣的集群,而SSD的順序讀寫性能跟機(jī)械硬盤的性能是差不多的。
Kafka 寫磁盤是順序追加寫的,所以對于 kafka 集群來說,我們使用普通機(jī)械硬盤就可以了。
2、每臺服務(wù)器需要多少塊硬盤
根據(jù)第一二步驟計(jì)算結(jié)果,我們需要7臺物理機(jī),一共需要存儲162T數(shù)據(jù),大約每臺機(jī)器需要存儲23T數(shù)據(jù),根據(jù)以往經(jīng)驗(yàn)一般服務(wù)器配置11塊硬盤,這樣每塊硬盤大約存儲2T的數(shù)據(jù)就可以了,另外為了服務(wù)器性能和穩(wěn)定性,我們一般要保留一部分空間,保守按每塊硬盤最大能存儲3T數(shù)據(jù)。
3、場景總結(jié)
要搞定10億+請求,需要7臺物理機(jī),使用普通機(jī)械硬盤進(jìn)行存儲,每臺服務(wù)器11塊硬盤,每塊硬盤存儲2T數(shù)據(jù)。
四、kafka容量評估之內(nèi)存
1、Kafka 寫磁盤流程及內(nèi)存分析
從上圖可以得出 Kafka 讀寫數(shù)據(jù)的流程主要都是基于os cache,所以基本上 Kafka 都是基于內(nèi)存來進(jìn)行數(shù)據(jù)流轉(zhuǎn)的,這樣的話要分配盡可能多的內(nèi)存資源給os cache。
kafka的核心源碼基本都是用 scala 和 java (客戶端)寫的,底層都是基于 JVM 來運(yùn)行的,所以要分配一定的內(nèi)存給 JVM 以保證服務(wù)的穩(wěn)定性。對于 Kafka 的設(shè)計(jì),并沒有把很多的數(shù)據(jù)結(jié)構(gòu)存儲到 JVM 中,所以根據(jù)經(jīng)驗(yàn),給 JVM 分配6~10G就足夠了。
從上圖可以看出一個(gè) Topic 會對于多個(gè) partition,一個(gè) partition 會對應(yīng)多個(gè) segment ,一個(gè) segment 會對應(yīng)磁盤上4個(gè)log文件。假設(shè)我們這個(gè)平臺總共100個(gè) Topic ,那么總共有 100 Topic * 5 partition * 3 副本 = 1500 partition 。對于 partition 來說實(shí)際上就是物理機(jī)上一個(gè)文件目錄, .log就是存儲數(shù)據(jù)文件的,默認(rèn)情況下一個(gè).log日志文件大小為1G。
如果要保證這1500個(gè) partition 的最新的 .log 文件的數(shù)據(jù)都在內(nèi)存中,這樣性能當(dāng)然是最好的,需要 1500 * 1G = 1500 G內(nèi)存,但是我們沒有必要所有的數(shù)據(jù)都駐留到內(nèi)存中,我們只保證25%左右的數(shù)據(jù)在內(nèi)存中就可以了,這樣大概需要 1500 * 250M = 1500 * 0.25G = 375G內(nèi)存,通過第二步分析結(jié)果,我們總共需要7臺物理機(jī),這樣的話每臺服務(wù)器只需要約54G內(nèi)存,外加上面分析的JVM的10G,總共需要64G內(nèi)存。還要保留一部分內(nèi)存給操作系統(tǒng)使用,故我們選擇128G內(nèi)存的服務(wù)器是非常夠用了。
2、場景總結(jié)
要搞定10億+請求,需要7臺物理機(jī),每臺物理機(jī)內(nèi)存選擇128G內(nèi)存為主,這樣內(nèi)存會比較充裕。
五、kafka容量評估之CPU壓力
1、CPU Core分析
我們評估需要多少個(gè) CPU Core,主要是看 Kafka 進(jìn)程里會有多少個(gè)線程,線程主要是依托多核CPU來執(zhí)行的,如果線程特別多,但是 CPU核很少,就會導(dǎo)致CPU負(fù)載很高,會導(dǎo)致整體工作線程執(zhí)行的效率不高,性能也不會好。所以我們要保證CPU Core的充足,來保障系統(tǒng)的穩(wěn)定性和性能最優(yōu)。
2、Kafka 網(wǎng)絡(luò)架構(gòu)及線程數(shù)計(jì)算
我們評估下 Kafka 服務(wù)器啟動后會有多少線程在跑,其實(shí)這部分內(nèi)容跟kafka超高并發(fā)網(wǎng)絡(luò)架構(gòu)密切相關(guān),上圖是Kafka 超高并發(fā)網(wǎng)絡(luò)架構(gòu)圖,從圖中我們可以分析得出:
除了上圖所列的還有其他一些線程,所以估算下來,一個(gè) kafka 服務(wù)啟動后,會有100多個(gè)線程在跑。
2、場景總結(jié)
要搞定10億+請求,需要7臺物理機(jī),每臺物理機(jī)內(nèi)存選擇128G內(nèi)存為主,需要16個(gè)cpu core(32個(gè)性能更好)。
六、kafka容量評估之網(wǎng)卡
1、網(wǎng)卡對比分析
通過上圖分析可以得出千兆網(wǎng)卡和萬兆網(wǎng)卡的區(qū)別最大之處在于網(wǎng)口的傳輸速率的不同,千兆網(wǎng)卡的傳輸速率是1000Mbps,萬兆網(wǎng)卡的則是10Gbps萬兆網(wǎng)卡是千兆網(wǎng)卡傳輸速率的10倍。性能上講,萬兆網(wǎng)卡的性能肯定比千兆網(wǎng)卡要好。萬兆網(wǎng)卡現(xiàn)在主流的是10G的,發(fā)展趨勢正逐步面向40G、100G網(wǎng)卡。但還是要根據(jù)使用環(huán)境和預(yù)算來選擇投入,畢竟千兆網(wǎng)卡和萬兆網(wǎng)卡的性價(jià)比區(qū)間還是挺大的。
2、網(wǎng)卡選擇分析
根據(jù)第一二步分析結(jié)果,高峰期的時(shí)候,每秒會有大約6萬請求涌入,即每臺機(jī)器約1萬請求涌入(60000 / 7),每秒要接收的數(shù)據(jù)大小為: 10000 * 20 kb = 184 M/s,外加上數(shù)據(jù)副本的同步網(wǎng)絡(luò)請求,總共需要 184 * 3 = 552 M/s。
一般情況下,網(wǎng)卡帶寬是不會達(dá)到上限的,對于千兆網(wǎng)卡,我們能用的基本在700M左右,通過上面計(jì)算結(jié)果,千兆網(wǎng)卡基本可以滿足,萬兆網(wǎng)卡更好。
3、場景總結(jié)
要搞定10億+請求,需要7臺物理機(jī),每臺物理機(jī)內(nèi)存選擇128G內(nèi)存為主,需要16個(gè)cpu core(32個(gè)性能更好),千兆網(wǎng)卡基本可以滿足,萬兆網(wǎng)卡更好。
4、kafka容量評估之核心參數(shù)
5、kafka容量評估之集群規(guī)劃
(1)集群部署規(guī)劃
這里我采用五臺服務(wù)器來構(gòu)建 Kafka 集群,集群依賴 ZooKeeper,所以在部署 Kafka 之前,需要部署好 ZooKeeper 集群。這里我將 Kafka 和 ZooKeeper 部署在了一起,Kafka 集群節(jié)點(diǎn)操作系統(tǒng)仍然采用 Centos 7.7 版本,各個(gè)主機(jī)角色和軟件版本如下表所示:
這里需要注意:Kafka 和 ZooKeeper 的版本,默認(rèn) Kafka2.11 版本自帶的 ZooKeeper 依賴 jar 包版本為 3.5.7,因此 ZooKeeper 的版本至少在 3.5.7 及以上。
(2)下載與安裝
Kafka 需要安裝 Java 運(yùn)行環(huán)境,你可以點(diǎn)擊Kafka官網(wǎng)
(https://kafka.apache.org/downloads)獲取 Kafka 安裝包,推薦的版本是 kafka_2.11-2.4.1.tgz。將下載下來的安裝包直接解壓到一個(gè)路徑下即可完成 Kafka 的安裝,這里統(tǒng)一將 Kafka 安裝到 /usr/local 目錄下,我以在 kafka-zk1 主機(jī)為例,基本操作過程如下:
[root@kafkazk1~]# tar -zxvf kafka_2.11-2.4.1.tgz -C /usr/local
[root@kafkazk1~]# mv /usr/local/kafka_2.11-2.4.1 /usr/local/kafka
這里我創(chuàng)建了一個(gè) Kafka 用戶,用來管理和維護(hù) Kafka 集群,后面所有對 Kafka 的操作都通過此用戶來完成,執(zhí)行如下操作進(jìn)行創(chuàng)建用戶和授權(quán):
[root@kafkazk1~]# useradd kafka
[root@kafkazk1~]# chown -R kafka:kafka /usr/local/kafka
在 kafka-zk1 節(jié)點(diǎn)安裝完成 Kafka 后,先進(jìn)行配置 Kafka,等 Kafka 配置完成,再統(tǒng)一打包復(fù)制到其他兩個(gè)節(jié)點(diǎn)上。
broker.id=1
listeners=PLAINTEXT://172.16.213.31:9092
log.dirs=/usr/local/kafka/logs
num.partitions=6
log.retention.hours=72
log.segment.bytes=1073741824
zookeeper.connect=172.16.213.31:2181,172.16.213.32:2181,172.16.213.33:2181
auto.create.topics.enable=true
delete.topic.enable=true
num.network.threads=9
num.io.threads=32
message.max.bytes=10485760
log.flush.interval.message=10000
log.flush.interval.ms=1000
replica.lag.time.max.ms=10
Kafka 配置文件修改完成后,接著打包 Kafka 安裝程序,將程序復(fù)制到其他4個(gè)節(jié)點(diǎn),然后進(jìn)行解壓即可。注意,在其他4個(gè)節(jié)點(diǎn)上,broker.id 務(wù)必要修改,Kafka 集群中 broker.id 不能有相同的(唯一的)。
(3)啟動集群
五個(gè)節(jié)點(diǎn)的 Kafka 配置完成后,就可以啟動了,但在啟動 Kafka 集群前,需要確保 ZooKeeper 集群已經(jīng)正常啟動。接著,依次在 Kafka 各個(gè)節(jié)點(diǎn)上執(zhí)行如下命令即可:
[root@kafkazk1~]# cd /usr/local/kafka
[root@kafkazk1 kafka]# nohup bin/kafka-server-start.sh config/server.properties &
[root@kafkazk1 kafka]# jps
21840 Kafka
15593 Jps
15789 QuorumPeerMain
這里將 Kafka 放到后臺(deamon)運(yùn)行,啟動后,會在啟動 Kafka 的當(dāng)前目錄下生成一個(gè) nohup.out 文件,可通過此文件查看 Kafka 的啟動和運(yùn)行狀態(tài)。通過 jps 指令,可以看到有個(gè) Kafka 標(biāo)識,這是 Kafka 進(jìn)程成功啟動的標(biāo)志。
九、總結(jié)
整個(gè)場景總結(jié):
要搞定10億+請求,經(jīng)過上面深度剖析評估后需要以下資源: