最佳化金字塔
應用程式層面
框架層面(Broker層面)
JVM層面
作業系統層面
應用程式層面:應當最佳化業務程式碼合理使用kafka,合理規劃主題,合理規劃分割槽,合理設計資料結構;
框架層面:在不改動原始碼的情況下,從kafka引數配置入手,結合業務體量和執行資料進行調優
JVM層面:在出現明顯緩慢和可能的記憶體溢位的情況下,結合業務程式碼情況和伺服器能力調優堆記憶體,非堆記憶體,GC方式等引數,非必要不更改過多引數
作業系統層面:在伺服器作業系統層面調優儘量減少kafka程式執行限制,關注檔案描述符限制,Selinux限制,JDK版本等情況
作業系統調優
檔案系統的選擇上,可選擇XFS和EXT4,生產環境推薦XFS,具備高效能和高伸縮性優點,最新的報導顯示具備多級快取的ZFS針對高IO的kafka有不錯的效果,但並未大規模驗證
Swap空間引數設定:儘量設定小一點,修改/etc/sysctl.conf檔案,增加vm.swappiness=,防止Linux OOM Killer執行緒隨意殺執行緒
檔案描述符:ulimit -n不能設定過小,在topic數量稍大時就會出現Too Many File Open報錯情況
控制程序可以擁有的記憶體對映區域的最大數量:vm.max_map_count,設定過小會出現記憶體溢位情況
作業系統頁快取:由於Kafka儲存資料時只要資料到來Page Cache頁快取就會返回Ack給生產者,並不會直接落盤,還需要等待觸發或手動刷盤操作進行持久化刷盤,此時作業系統的Cached大小必須超過一個日誌段大小,Broker上對應引數為log.segment.bytes,越大消費者在消費時有更大機率在快取頁命中,避免頻繁IO從硬碟讀取資料。
JVM層面調優
(1)堆記憶體引數設定:kafka本身並不佔用過多堆記憶體,6-8G相對合適,在kafka-server-start.sh設定KAFKA_HEAP_OPTS引數即可;更精確可以檢視KafkaServer-gc.log,關注Full GC之後堆上存活大小的總量,從而可以將堆記憶體設定為這個值的2-2.5倍,可以使用圖上命令進行手動GC
(2)GC選擇器:博主kafka3.5.1版本的kafka叢集使用openjdk11.0.X,預設G1收集器;在G1中Full GC是單執行緒執行,在生產環境中要儘量避免Full GC
(3)JDK選擇:至少JDK1.8,推薦JDK11,kafka3.0推薦至少使用JDK11
框架調優(Broker層面)
(1)版本適配:儘量保持客戶端版本和Broker端版本一致或儘量適配,以避免版本之間不一致問題導致的效能最佳化損失,如零複製等特性
(2)訊息壓縮方式:Broker端和Producer段的訊息壓縮方式應該保持一致,推薦lz4,第二選擇gzip,如果設定得不一致會導致Broker付出大量額外的CPU效能用於解壓和二次壓縮
(3)num.io.thread:Handler執行緒用於執行業務處理,Acceptor執行緒用於接收網路請求,Processor執行緒用於建立網路連線和分發網路請求,Handler執行緒才是執行業務請求處理的執行緒,由Broker引數num.io.thread決定,數量越大執行執行緒越多,處理速度更快
(4)num.recovery.threads.per.data.dir:Broker重啟後恢復執行緒數量,設定越大,追上資料進入ISR越快
(5)num.network.thread:The number of threads that the server uses for receiving requests from the network and sending responses to the network,增加這個執行緒引數就是提高收發網路請求的速度
(6)log.retention.bytes:日誌儲存時間,針對業務需求合理設定時間
(7)message.max.bytes:針對訊息集合打包的大訊息體業務,需要設定更大的引數
(8)num.replica.fetchers:副本資料同步執行緒,應當不超過cpu核數,通常設定為4-8即可
框架調優(Producer層面)
(1)訊息傳送確認機制:acks=all,通常情況下在生產環境設定為acks=1即Leader副本確認即可
(2)批次傳送訊息大小:batch.size= 傳送到同一個分割槽訊息的批次大小限制
(3)傳送最大時延:linger.ms=,批次大小沒有達到batch.size,最大允許時延
框架調優(Consumer層面)
(1)訊息提交機制:如為保證訊息不重複消費即手動提交訊息
(2)訊息資料批次大小:fetch.min.bytes,如果時延不敏感追求吞吐量,可設定得大一點
應用程式層面調優
(1)保證業務程式碼健壯性,保證容器不會出現過多bug導致反覆重啟誘發Kafka叢集Rebalance
(2)不要頻繁建立Producer和Consumer,建立的連線要Close;
(3)合理建立執行緒池進行連線複用
(4)合理利用多執行緒進行推送,消費訊息