天天看點

節省2000核CPU:去哪兒Kafka性能優化秘笈

文章概覽

一、背景介紹

二、術語介紹

三、KAFKA生産痛點

四、優化過程

五、方案驗證及上線

六、優化效果:所有叢集節省2000核CPU

作者介紹

餘東,去哪兒旅行大資料運維。主要負責KAFKA以及FLINK叢集的開發和運維,以及自動化運維平台的建設。

賈建東,2015年加入去哪兒旅行資料保障團隊,大資料技術委員會成員。熱愛鑽研技術,對hadoop生态、隊列服務、日志收集等領域有實戰經驗。

徐偉,去哪兒旅行大資料開發工程師,主要負責日志收集平台的開發維護工作;為業務和數倉提供離線和實時基礎資料支撐。

一、背景介紹

1.叢集概況

  • 去哪兒旅行目前KAFKA日志叢集節點145台。單機配置:3TSSD盤,40核,128G記憶體。

2.業務背景

  • 日志KAFKA叢集承載了全司的APPCODE日志,比如我們常用的QTRACE日志,以及實時離線數倉資料,體量非常大。
  • 春節高峰每分鐘流量1.3TP,每分鐘接收20億條資料。
  • 每天資料流量1.5PB,每天接收消息條數超過兩萬億。

3.日志叢集架構圖

節省2000核CPU:去哪兒Kafka性能優化秘笈

二、術語介紹

1.KAFKA術語

  • Broker:kafka叢集中的一個節點。
  • 網絡閑置率:是kafka服務的一個重要名額,即網絡線程池線程平均的空閑比例,通常用于衡量叢集的繁忙程度。叢集沒有流量時為最大值1,随着叢集壓力變大會逐漸變小,達到0.3以下叢集性能就會達到瓶頸,就表明你的網絡線程池非常繁忙,叢集無法保證讀寫請求的及時處理,造成生産丢數已經消費堆積的問題。需要通過增加網絡線程數或将負載轉移給其他伺服器的方式,來給該 Broker 減負。
  • 請求隊列:用戶端發起的請求首先存放在這個隊列,服務端拉取請求并進行處理。主要包含了消費以及生産請求。

2.kubernetes術語

  • kubernetes 是個基于容器技術的分布式叢集管理系統,或者說是容器編排、管理的編排平台。
  • pod 是 k8s 中的最小排程單元,應用以此作為載體排程運作。pod 内可以隻有一個容器也可以包含多個容器,共享網絡命名空間、存儲資源等,我們的filebeat 運作環境便是随着業務 pod 中注入一個 filebeat sidecar 容器來進行業務日志收集。

三、KAFKA生産痛點

痛點一

  • 無法抗住23年春節壓測,在壓測高峰期,部分用戶端無法正常消費,出現堆積,并且也無法正常生産資料,壓測期間采取了降級措施來保證叢集的穩定。
  • 節日高峰期,整個叢集的處理能力大幅縮減,需要人工對高壓力機器進行負載均衡。

痛點二

  • 公司壓測期間叢集網絡閑置率已經降低到0.4以下,部分機器閑置率接近于0,叢集處于壓力瓶頸的邊緣,已經無法通過增加機器來解決叢集本身的性能問題了。
  • 下圖是叢集高峰期的網絡閑置率,每條線代表一台伺服器。
節省2000核CPU:去哪兒Kafka性能優化秘笈

個别機器閑置率接近于0,代表目前KAFKA機器處理能力已經達到上限了。

節省2000核CPU:去哪兒Kafka性能優化秘笈

四、優化過程

從現象及後面的測試發現,增加節點可以解決,但會産生巨大的成本。同時,機器層面還未達到瓶頸,這說明是服務本身需要優化,是以我們着重去優化kafka本身。

綜合考慮後發現有兩個外界因素在影響這個名額,一個是資料量變大,另一個是高峰期pod擴充較多,網絡連結數變大。但具體什麼問題需要精确定位,我們準備從日志、機器硬體名額、應用名額逐個排查。

1.排查日志

通過對網絡閑置率低的機器進行排查,服務端并沒有明顯的日志報錯,日志無法定位具體問題。

2.硬體層面排查

閑置率低的機器排查機器本身的資源使用,發現網卡流量、磁盤使用率、記憶體使用、cpu使用都沒有達到上限、下面是各個名額的監控圖:

網絡流量監控,壓測期間入口流量有所上漲,出口流量上漲不明顯。

節省2000核CPU:去哪兒Kafka性能優化秘笈

磁盤IO監控,可以發現壓測期間IO使用率有所上漲,但并沒有達到上限。

節省2000核CPU:去哪兒Kafka性能優化秘笈

記憶體監控,記憶體沒有明顯的變化。

節省2000核CPU:去哪兒Kafka性能優化秘笈

cpu在壓測期間反而在下降,充分說明叢集性能此時已經出現問題。

節省2000核CPU:去哪兒Kafka性能優化秘笈

tcp連結數沒有明顯變化,說明長連結并沒有大的變化。

節省2000核CPU:去哪兒Kafka性能優化秘笈

3.參數優化

影響網絡閑置率最直接的兩個參數就是io線程數和網絡線程數。

系統預設值 num.io.threads=3、num.network.threads=8 這兩個參數分别是代表磁盤IO的線程數量、處理網絡請求的線程數量。這兩個值叢集已經做過優化,繼續調大之後并沒有效果。

原參數
num.io.threads=32
num.network.threads=64


修改後參數
num.io.threads=128
num.network.threads=64           

4. 網絡架構分析

深入分析KAFKA架構,從用戶端發起請求,到用戶端處理邏輯流程進行深入分析。其中包含了用戶端的發起請求後,服務端如何接收請求,以及如何處理請求後,回報給用戶端。

基于此分析,發現了KAFKA叢集缺失了很多重要的監控資訊,比如請求隊列大小,請求耗時,用戶端請求量。于是我們根據網絡架構進行必要的監控添加,用于發現瓶頸。

節省2000核CPU:去哪兒Kafka性能優化秘笈

5.增加監控

kafka服務的各項名額,都是從jmx中擷取,由于jmx中有大量名額,我們平時擷取隻關注了重點部分名額,這次準備把可能有關聯的相關名額都打出來觀察。

增加了下面這些名額:RequestQueueSize大小,ResponseQueueSize大小 ,日志刷盤持續時長,BROKER生産請求數,Produce耗時名額 P999,FetchFollower耗時名額 P999,FetchConsumer耗時名額P999,TotalFetchRequestsPerSec,TotalProduceRequestsPerSec。

添加名額後經過觀察,趨勢有相關的名額有 RequestQueueSize大小、日志刷盤持續時長、BROKER生産請求數,下面重點排查這些名額。

6.刷盤時間名額驗證

當閑置率低的時候,發現刷盤時間也在增長,刷盤時間有兩部分因素控制,一部分是Kafka本身的參數,另一部分就是磁盤的IO。我們通過兩部分的測試來驗證是否有關聯。

Kafka 的刷盤時間指的是将資料從記憶體重新整理到持久儲存設備(如硬碟)所需的時間。Kafka 的性能直接影響其可以處理的消息量,而這個時間就是影響這一性能的一個關鍵因素。刷盤時間相關重要的兩個參數為:

  • log.flush.interval.messages:在日志檔案的緩沖區中積累指定數量的消息後,觸發一次刷盤操作。
  • log.flush.interval.ms:在日志檔案的緩沖區中積累指定時間後,觸發一次刷盤操作。

通過對這兩個參數的不同數值的調整,最後發現對閑置率沒有影響。

log.flush.interval.messages=10000
log.flush.interval.ms=1000           

對于磁盤IO的影響,線上我們都是用單盤提供服務,如果我們改用雙盤,兩個盤理論上是單盤IO兩倍的性能,但是加盤之後,同樣的壓測資料,對閑置率沒有影響。

  • 單盤閑置率0.67
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 雙盤閑置率0.68
節省2000核CPU:去哪兒Kafka性能優化秘笈

7.請求數名額驗證

kafka每個broker會有一個請求隊列,這個隊列有一個預設值大小。當隊列打滿的時候說明服務端無法快速消化大量打過來的請求,這個名額和【BROKER生産請求數】名額可以對應上。同時也可以解釋外部的兩個因素,流量上漲和pod擴容。

通過測試環境确認,當broker請求量達到一定值以後,請求隊列逐漸打滿,閑置率開始下降,cpu使用率開始下降,複現了線上的現象。

确認了問題的關鍵是請求量之後,需要想辦法降低請求量,kafka的請求在filebeat用戶端。我們需要研究filebeat的參數配置。

從filebeat官網确認,涉及到批次發送的有兩個參數bulk_flush_frequency 和 bulk_max_size,線上使用的filebeat沒有配置這兩個參數。

其中含義如下:

  • bulk_flush_frequency 批量發送kafka request需要等待的時間,預設0不等待;
  • bulk_max_size 單次kafka request請求批量的消息數量,預設2048。

針對這兩個參數我們做了測試:

  • 測試結果

由于單條資料量不同會産生不同的效果,我們對不同的的資料長度做了測試,針對我司日志特點(單條日志大小),最後得到一個最優的組合如下,增加了這倆參數後,KAFKA TOPIC在不丢數的情況下,請求數降低了10倍左右。

  • 相關參數
bulk_flush_frequency: 0.1
 bulk_max_size: 1024           
  • 資料樣本1測試結果 平均資料長度: 1.62KB
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 資料樣本2測試結果 平均資料長度: 606KB
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • SNAPPY壓縮測試

從上面測試結果可以看到不同的批次下,網卡流量會有變化,這個現象最初我們了解為kafka性能的下降。通過測試發現,批次提高後壓縮比會提高,網絡層面也是一個間接的優化效果。而且不光是網絡,磁盤也會有節約,下面是不同批次下的壓縮資料測試。

通過測試可以發現,條數超過50條的時候壓縮比基本保持一緻。這裡的資料單條1KB。

節省2000核CPU:去哪兒Kafka性能優化秘笈

五、方案驗證及上線

1.線上灰階測試

找到線上的一些代表性的topic進行測試,測試結果符合預期,生産請求數降到原來的1/10,所在機器閑置率提高0.02-0.06,同時分區所在機器CPU使用降低了5個點。

節省2000核CPU:去哪兒Kafka性能優化秘笈

2.上線

灰階測試沒問題後,開始釋出線上版本,但線上應用,需要重新釋出才能生效。釋出一周後效果明顯,cpu、網絡流量、磁盤都有不同程度的資源節約。

下面是上線一周後的資料:

  • CPU從52%掉到34%
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 請求數從6億掉到3.5億
節省2000核CPU:去哪兒Kafka性能優化秘笈

六、優化效果,所有叢集節省2000核CPU

  • 日志叢集:節省了1334核CPU
節省2000核CPU:去哪兒Kafka性能優化秘笈

日志叢集CPU明細圖, 降低了145*40*23%=1334核

節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 網絡閑置率:從最低0.72提升到0.93,提升了23%。閑置率提高,代表了KAFKA的處理性能得到了提升。
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 用戶端請求量:從6億降到2.3億
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 磁盤使用率:從44%降到35%
節省2000核CPU:去哪兒Kafka性能優化秘笈
  • 網絡流量:從2.5G降到2G
節省2000核CPU:去哪兒Kafka性能優化秘笈

七、最終效果

3個KAFKA叢集一起優化後,最終節約2000核。

節省2000核CPU:去哪兒Kafka性能優化秘笈

後續動作

經過上述優化後,cpu不再是單機的性能瓶頸,轉而變成網卡和磁盤。

  • 磁盤方面:目前叢集的主流磁盤是3T,高峰時期磁盤使用率叢集均值已經達到60%,單機已經達到85%,我們準備每台機器再添加一塊3T盤來擴充存儲能力和IO的壓力。
  • 網絡方面:目前叢集網卡平均出口流量峰值已經超過4G,單機最大會超過8G,如果流量繼續上升,網卡會成為新的瓶頸,我們準備把10G網卡提升到25G或改為雙通道20G。

在不改變CPU和記憶體的情況下,通過這兩方面的改造後,預計可以繼續提升叢集50%以上的性能。

作者丨餘東&賈建東&徐偉

來源丨公衆号:Qunar技術沙龍(ID:QunarTL)

dbaplus社群歡迎廣大技術人員投稿,投稿郵箱:[email protected]