經典乾貨分享:Kafka調優有哪些過程?

2019-11-03     IT技術分享
  1. 主要目標: 高吞吐量低延時
  2. 吞吐量
  • TPS ,指的是Broker端進程或Client端應用程式每秒能處理的 位元組數消息數
  1. 延時 ,可以有兩種理解
  • Producer發送消息Broker持久化 完成之間的時間間隔
  • 端到端的延時 ,即從 Producer發送消息Consumer成功消費該消息 的總時長

優化漏斗

優化漏斗是調優過程中的分層漏斗,層級越靠上,調優的效果越明顯

作業系統層

  1. mount -o noatime
  • 掛載 文件系統時禁用 atime (Access Time)更新,記錄的是 文件最後被訪問的時間
  • 記錄 atime 需要作業系統訪問 inode 資源,禁用atime可以 避免inode訪問時間的寫入操作
  1. 文件系統選擇 ext4XFSZFS
  2. swappiness 設置成一個 很小的值 (1~10,默認是60),防止Linux的 OOM Killer 開啟 隨機殺掉 進程
  • swappiness=0 ,並不會禁止對swap的使用,只是 最大限度 地降低使用swap的可能性
  • 因為一旦設置為0,當物理內存耗盡時,作業系統會觸發 OOM Killer
  • OOM Killer會 隨機 挑選一個進程然後kill掉, 不會給出任何預警
  • swappiness=N,表示內存使用 (100-N)% 時,開始使用Swap
  1. ulimit -n 設置大一點,否則可能會出現 Too Many File Open 錯誤
  2. vm.max_map_count 也設置大一點(如655360,默認值65530)
  • 在一個主題數超多的機器上,可能會碰到 OutOfMemoryError:Map failed 錯誤
  1. 頁緩存大小
  • 給Kafka預留的頁緩存至少也要容納一個 日誌段 的大小( log.segment.bytes ,默認值為 1GB
  • 消費者程序在 消費 時能 直接命中 頁緩存,從而避免 昂貴的物理磁碟IO操作

JVM層

  1. 堆大小,經驗值為 6~8GB
  • 如果需要精確調整,關注 Full GC後堆上存活對象的總大小 ,然後將堆大小設置為該值的 1.5~2倍
  • jmap -histo:live 可以人為觸發Full GC
  1. 選擇垃圾收集器
  • 推薦使用 G1 ,主要原因是 優化難度比CMS小
  • 如果使用G1後,頻繁Full GC,配置 -XX:+PrintAdaptiveSizePolicy ,查看觸發Full GC的原因
  • 使用G1的另一個問題是 大對象 ,即 too many humongous allocations
  • 大對象一般指的是 至少占用半個Region大小的對象 ,大對象會被直接分配在 大對象區
  • 可以適當增大 -XX:+G1HeapRegionSize=N
  1. 儘量避免Full GC!!

框架層

儘量保持 客戶端 版本和 Broker端 版本 一致 ,否則可能會喪失很多 性能收益 ,如 Zero Copy

應用程式層

  1. 不要頻繁創建 Producer和Consumer對象實例,構造這些對象的 開銷很大
  2. 用完及時關閉
  • Producer對象和Consumer對象會創建很多物理資源,如Socket連接、ByteBuffer緩衝區,很容易造成 資源泄露
  1. 合理利用 多線程 來改善性能,Kafka的Java Producer是線程安全的,而Java Consumer不是線程安全的

性能指標調優

TPS != 1000 / Latency(ms) **

  1. 假設Kafka Producer以2ms的延時來發送消息,如果 每次都只發送一條消息 ,那麼 TPS=500
  2. 但如果Producer不是每次只發送一條消息,而是在發送前 等待一段時間 ,然後 統一發送一批消息
  3. 如Producer每次發送前等待8ms,總共緩存了1000條消息,總延時累加到了10ms,但 TPS=100,000
  • 雖然延時增加了4倍,但TPS卻增加了200倍,這就是 批次化微批次化 的優勢
  • 用戶一般願意用 較小的延時增加 的代價,去換取 TPS的顯著提升 ,Kafka Producer就是採用了這樣的思路
  • 基於的前提: 內存操作 (幾百納秒)和 網絡IO操作 (毫秒甚至秒級)的時間量級不同

調優吞吐量

  1. Broker端
  • 適當增加 num.replica.fetchers (默認值為1),但 不用超過CPU核數
  • 生產環境中,配置了 acks=all 的Producer程序吞吐量被拖累的首要因素,就是 副本同步性能
  • 調優GC參數避免頻繁Full GC
  1. Producer端
  • 適當增加 batch.size (默認值為16KB,可以增加到 512KB1MB
  • 增加消息批次的 大小
  • 適當增加 linger.ms (默認值為0,可以增加到10~100)
  • 增加消息批次的 緩存時間
  • 修改 compression.type (默認值為none,可以修改為 lz4zstd ,適配最好)
  • 修改 acks (默認值為1,可以修改為 01
  • 優化的目標是吞吐量,不要開啟 acks=all (引入的 副本同步時間 通常是吞吐量的瓶頸)
  • 修改 retries (修改為 0
  • 優化的目標是吞吐量,不要開啟重試
  • 如果多線程共享同一個Producer,增加 buffer.memory (默認為 32MB )
  • TimeoutException:Failed to allocate memory within the configured max blocking time
  1. Consumer端
  • 採用多Consumer進程或線程 同時消費 數據
  • 適當增加 fetch.min.bytes (默認值為1Byte,可以修改為 1KB 或更大)

end:如果你覺得本文對你有幫助的話,記得關注點贊轉發,你的支持就是我更新動力。

文章來源: https://twgreatdaily.com/zh-my/C2eLRG4BMH2_cNUgzLpl.html