1. 程式人生 > >kafka效能優化詳解

kafka效能優化詳解

KAFKA Cluster模式最大的優點:可擴充套件性和容錯性。下圖是關於Kafka叢集的結構圖: 在這裡插入圖片描述 一、Kafka Broker個數決定因素 在這裡插入圖片描述 二、作業系統優化 大部分Linux釋出版本預設的核心引數配置能讓大部分應用工作的相當好。但對於實際的Kafka broker場景來說,做稍些改變會提升broker效能。主要涉及的配置:虛擬記憶體、網路和磁碟掛載(用來儲存log segment),一般在 /etc/sysctl.conf (CentOS系統) 1、Virtual Memory 一般來說,Linux的虛擬記憶體會根據系統負載自動調整。記憶體頁(page)swap到磁碟會顯著的影響Kafka的效能,並且Kafka重度使用page cache,如果VM系統swap到磁碟,那說明沒有足夠的記憶體來分配page cache。   避免swap的一種方式是設定swap空間為0。但是,swap會在系統崩潰時提供安全機制,或者會在out of memory的情況下阻止作業系統 kill 掉程序。由於這個原因,推薦 vm.swappiness 引數設定為一個非常低的值:1 。這個引數表示 VM系統中的多少百分比用來作為swap空間。   另外一種方式是通過核心調節“髒頁”(注:“髒頁”會被刷到磁碟上)。Kafka依賴磁碟I/O效能來提高producer的響應時間。這也是為什麼通常優先把log segment功能放在可以快速響應的磁碟中(比如,SSD)。這樣使得flush程序把“髒資料”寫入磁碟前,“髒頁”數目就減少了,可以設定 vm.dirty_background_ratio(表示佔用系統記憶體的百分比)引數的值為 10 以下。大部分應用場景下,vm.dirty_background_ratio 設定為 5 就夠用了,要注意了:這個引數值不能設定為 0 ,因為設定為 0 後會引起核心持續刷“髒頁”,使得核心的buffer write功能沒法施展。   “髒頁”的總量可以通過 vm.dirty_ratio 來改變,預設值是 20 (此處也是百分比),這個值的設定範圍較大,一般建議設定 60 到 80 為合理的值。但是 vm.dirty_ratio 引數也引來了不小的風險,會造成大量unflush的資料在硬刷到磁碟時產生較長的I/O停頓。如果vm.dirty_ratio 值設定的較大時,強烈建議Kafka開啟備份功能,以備系統崩潰。 在設定了這些引數後,需要監控Kafka叢集執行時“髒頁”的數量,當前“髒頁”數量可由如下方式檢視 在這裡插入圖片描述

2、磁碟 除了考慮磁碟硬體本身和RAID配置外,磁碟的filesystem對Kafka叢集的影響最大。雖然有許多filesystem,但最常用的是EXT4或者XFS。在這裡XFS檔案系統比EXT4稍好,具體原因Google下。 另外一點是,建議開啟mount的noatime mount選項。檔案系統在檔案被訪問、建立、修改等的時候會記錄檔案的一些時間戳,比如:檔案建立時間(ctime)、最近一次修改時間(mtime)和最近一次訪問時間(atime)。預設情況下,atime的更新會有一次讀操作,這會產生大量的磁碟讀寫,然而atime對Kafka完全沒用 3、網路 Linux釋出版本的網路引數對高網路流量不適用。對於Kafka叢集,推薦更改每個socket傳送和接收buffer的最大記憶體:net.core.wmem_default 和 net.core.rmem_default 為128 kb,net.core.wmem_max 和 net.core.rmem_max 為 2 Mb。另外一個socket引數是TCP socket的傳送和接收buffer: net.ipv4.tcp_wmem 和 net.ipv4.tcp_rmem

三、Kafka叢集穩定 1、GC調優 調GC是門手藝活,幸虧Java 7引進了G1 垃圾回收,使得GC調優變的沒那麼難。G1主要有兩個配置選項來調優:MaxGCPauseMillis 和 InitiatingHeapOccupancyPercent,具體引數設定可以參考Google,這裡不贅述。   Kafka broker能夠有效的利用堆記憶體和物件回收,所以這些值可以調小點。對於 64Gb記憶體,Kafka執行堆記憶體5Gb,MaxGCPauseMillis 和 InitiatingHeapOccupancyPercent 分別設定為 20毫秒和 35。Kafka的啟動指令碼使用的不是 G1回收,需要在環境變數中加入: 在這裡插入圖片描述

2、資料中心佈局 原則上Kafka broker不建議都在一個機架上,為了容災。 3、Zookeeper Kafka叢集利用ZK來儲存broker、topic和partition的元資料資訊。在Kafka 0.9.0之前,consumer利用ZK來直接儲存consumer group的資訊,包括topic的消費情況、每個partition消費的週期性commit。在0.9.0版本,提供新的consumer介面利用Kafka broker來管理。   Consumer可以選擇使用Zk或者Kafka來提交 offset和 提交間隔。如果consumer使用ZK管理offset,那每個consumer在每個partition的每個時間間隔寫入ZK。合理的offset提交間隔是1分鐘,但如果一個Kafka叢集有大量的consumer消費時,這個ZK流量將是巨大的。所以如果ZK不能處理大流量,那隻能把offset提交間隔設大,但同時也帶來丟資料的風險。最保險的建議是使用Kafka來提交offset。   另外,建議Kafka叢集不要和其他應用使用同一組ZK,因為Kafka對於ZK的延遲和超時是相當敏感的,ZK的不通將會導致Kafka的不可預測性

Kafka效能調優.

一、partition數量配置 partition數量由topic的併發決定,併發少則1個分割槽就可以,併發越高,分割槽數越多,可以提高吞吐量在這裡插入圖片描述 二、日誌保留策略設定 當kafka broker的被寫入海量訊息後,會生成很多資料檔案,佔用大量磁碟空間,kafka預設是保留7天,建議根據磁碟情況配置,避免磁碟撐爆。 Log.retention.hours=72 段檔案配置1GB,有利於快速回收磁碟空間,重啟kafka載入也會加快(如果檔案過小,則檔案數量比較多,kafka啟動時是單執行緒掃描目錄(log.dir)下所有資料檔案) 在這裡插入圖片描述 三、檔案刷盤策略 為了大幅度提高producer寫入吞吐量,需要定期批量寫檔案。建議配置:在這裡插入圖片描述 在這裡插入圖片描述 四、網路和io操作執行緒配置優化 一般num.network.threads主要處理網路io,讀寫緩衝區資料,基本沒有io等待,配置執行緒數量為cpu核數加1 在這裡插入圖片描述 num.io.threads主要進行磁碟io操作,高峰期可能有些io等待,因此配置需要大些。配置執行緒數量為cpu核數2倍,最大不超過3倍 在這裡插入圖片描述 加入佇列的最大請求數,超過該值,network thread阻塞 在這裡插入圖片描述 server使用的send buffer大小 在這裡插入圖片描述 server使用的recive buffer大小 在這裡插入圖片描述 五、非同步提交 採用同步:1000條8s; 採用非同步:100條或3s非同步寫入,速度提升為1w條2s(ProducerConfig) request.required.acks=0 producer.type=async ##在非同步模式下,一個batch傳送的訊息數量。producer會等待直到要傳送的訊息數量達到這個值,之後才會傳送。但如果訊息數量不夠,達到queue.buffer.max.ms時也會直接傳送。 batch.num.messages=100 ##預設值:200,當使用非同步模式時,緩衝資料的最大時間。例如設為100的話,會每隔100毫秒把所有的訊息批量傳送。這會提高吞吐量,但是會增加訊息的到達延時 queue.buffering.max.ms=100 ##預設值:5000,在非同步模式下,producer端允許buffer的最大訊息數量,如果producer無法儘快將訊息傳送給broker,從而導致訊息在producer端大量沉積,如果訊息的條數達到此配置值,將會導致producer端阻塞或者訊息被拋棄。 queue.buffering.max.messages=1000 ##傳送佇列緩衝長度##預設值:10000,當訊息在producer端沉積的條數達到 queue.buffering.max.meesages 時,阻塞一定時間後,佇列仍然沒有enqueue(producer仍然沒有傳送出任何訊息)。此時producer可以繼續阻塞或者將訊息拋棄,此timeout值用於控制阻塞的時間,如果值為-1(預設值)則 無阻塞超時限制,訊息不會被拋棄;如果值為0 則立即清空佇列,訊息被拋棄。 queue.enqueue.timeout.ms=100 compression.codec=gzip