《Apache Kafka實戰》讀書筆記-調優Kafka集羣

              《Apache Kafka實戰》讀書筆記-調優Kafka集羣
html

                                              做者:尹正傑數據庫

版權聲明:原創做品,謝絕轉載!不然將追究法律責任。緩存

 

 

 

一.肯定調優目標服務器

1>.常見的非功能性要求網絡

一.性能(performance)
    最重要的非功能性需求之一。大多數生產環境對集羣性能都有着嚴格的要求。不一樣的系統對於性能有着不一樣的訴求。好比對數據庫系統來講,最重要的性能是請求的響應時間(response time)。用戶老是但願一條查詢或更新操做的總體響應時間越短越好;而對kafak而言,性能通常指的是吞吐量和延時兩個方面
1>.吞吐量(throughput/TPS)
    broker或clients應用程序每秒能處理多少字節(或消息)。
2>.延時(latency)
    一般指代producer端發送消息到broker端持久化保存消息之間的時間間隔。該概念也用於統計端到端(end-to-end,E2E)的延時,好比producer端發送一條消息到consumer端消費這條消息的時間間隔。

二.可用性
    在某段時間內,系統或組建正常運行的機率或在時間上的比率。業界通常用N個9來量化可用性,好比常見的「年度4個9」即指系統可用性要達到99.99%, 即一年中系統宕機的時間不能超過53分鐘(365 x 24 x 60 x 0.01% = 53).

三.持久性
    確保了已提交操做系統產生的消息須要被持久化的保持,即便系統出現崩潰。對於kafka來講,持久性一般意味着已提交的消息須要持久化到broker底層的物理日誌而不能發送丟失。
    
    因爲篇幅有限,上述僅僅羅列出了對Kafka很是重要的的非功能性需求,接下來咱們會進行詳細的展開來討論如何從這些方面調優kafka集羣。
     

2>.只有明確目標才能明確調優的方向session

   如上所述,咱們須要從四個方面來考慮調優目標:吞吐量,延時,持久性和可用性。爲了明確用戶生產環境中的目標,用戶須要結合業務仔細思考Kafka集羣的使用場景和初衷。好比使用kafka集羣的目的是什麼?是做爲一個消息隊列使用,仍是做爲數據存儲,抑或是用做流失數據處理,更或是以上全部?app

 

明確這個目標有兩個重要的做用:tcp

   2.1>.萬物皆有度,世界上沒有十全十美的事情。你不可能同時最大化上述四個目標。它們彼此之間多是矛盾的,到底看重哪一個方面其實是一個權衡選擇(trade-off)。ide

舉個例子:
    假設producer每秒發送一條消息須要花費2毫秒(即延時是2毫秒),那麼顯然producer的吞吐量就應該是500條/秒,由於1秒能夠發送1/0.002=500條消息。所以,吞吐量和延時的關係彷佛可使用共識來表示:TPS=1000/Latency(毫秒)。

    其實,二者的關係遠非上面公司表示的那麼簡單。咱們依然以kafka producer來舉例子,假設它仍然 以2毫秒的延時來發送消息。若是每秒之發送一條消息,那麼TPS天然就是500條/秒。因而可知,延時增大了4倍,但TPS卻增大的了將近200倍。

    上面的場景解釋了目前爲何批次化(batchingi)以及微批次話(micro-batchingh)流行的緣由。實際環境中用戶幾乎老是願意用增長較小延時的待見去換取TPS的顯著提高。畢竟從2毫秒到10毫秒的延遲增長一般是能夠忍受的。值得一提的是,kafka producer也採起了這樣的理念,這裏的9毫秒就是producer等待8毫秒積攢出的消息數遠遠多於同等時間內producer可以發送的消息數。

    有的讀者會問:producer等待8毫秒就能積累1000條消息嗎?不是發送一條消息就須要2毫秒嗎?這裏須要解釋一下,producer累積消息通常僅僅是將消息發送到內存中的緩衝區,而發送消息卻須要設計網絡I/O傳輸。內存操做和I/O操做的時間量級不是不一樣的,前者一般是基百納秒級別,然後者從毫秒到秒級別不等,故producer等待8毫秒積攢出的消息數遠遠多於同等時間內producer可以發送的消息數。
    
    說了這麼多其實就想強調上面4個調優目標統籌規劃時互相關聯,互相制約的。固然,這種制約以爲不是徹底互斥,即提升一個目標必定會使其餘目標下降。換句話說,就是用戶不能同時使這4個目標達到最優成都。這就是在調優前明確優化目標的第一個含義。

 

   2.2>.用戶須要明確調優的重點才能針對性的調整不一樣的Kafka參數。Kafka提供的各種參數已達幾百個之多。只有咱們明確要調優哪些方面才能肯定適合的參數。好比若是要爲集羣中全部topic進行優化,那麼就須要調整broker的參數,而若是是隻是爲某些topic進行優化,性能

則須要調整topic級別的參數。

 

二.集羣基礎調優

   可參考我以前的筆記:《Kafka權威指南》讀書筆記-操做系統調優篇(https://www.cnblogs.com/yinzhengjie/p/9993719.html)

   關於內核調優的參數,我只是微調了一下,僅僅調試了12個內核參數,以下:(僅供參考,你們能夠根據本身的實際環境調試相應的內核參數)

[root@yinzhengjie ~]# tail -13 /etc/sysctl.conf    
#Add by yinzhengjie
net.ipv6.conf.all.disable_ipv6=1
vm.dirty_ratio = 80
vm.dirty_background_ratio = 5
vm.swappiness = 1
net.core.wmem_default = 256960
net.core.rmem_default = 256960
net.ipv4.tcp_wmem = 8760  256960  4088000
net.ipv4.tcp_rmem = 8760  256960  4088000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.core.netdev_max_backlog = 2000
vm.max_map_count=262144
[root@yinzhengjie ~]# 

 

三.調優吞吐量

   若要調優吞吐量(TPS),producer,broker和consumer都須要進行調整,以便讓他們在相同的時間內傳輸更多的數據。衆所周知,Kafka基本的並行單元就是分區。producer在設計時就被要求可以同時向多個分區發送消息,這些消息也要可以被寫入到多個broker中供多個consumer同時消費。所以一般來講,分區數越多TPS越高。那麼這是否意味着咱們每次建立topic時都要建立大量的分區呢?答案顯然是否認的。這依然是一個權衡(trade-off)的問題:

一.過多的分區可能有哪些弊端呢?
1>.server/clients端將佔用更多的內存。
    producer默認使用緩衝區爲每一個分區緩存消息,一旦知足條件producer便會批量發出緩存的消息。看上去這是一個提高性能的設計,不過因爲該參數時分區級別的,所以若是分區不少,這部分緩存的內存佔用也會變大;而在broker端,每一個broker內部都維護了不少分區的元數據,好比controller,副本管理器,分區管理器等等。顯然,分區數越多,緩存的成本越大。

2>.分區屬越多,系統文件句柄書也越多
    每一個分區在底層文件系統都有專屬目錄。該目錄下廚了3個索引文件以外還會保存日誌段文件。一般生產環境下的日誌短文件可能有多個,所以保守估計一個分區就可能要佔用十幾個甚至幾十個文件句柄。當kafka一旦打開文件並不會顯式關閉該文件,故文件句柄書時不會釋放的。那麼隨着分區數的增長,系統文件句柄書也會相應地增加。


3>.分區數過多會致使controller處理週期過長
    每一個分區一般都有若干個副本而副本保存在不一樣的broker上。當leader副本掛掉了,controller回自動監測到,而後在zookeeper的幫助下選擇新的leader。雖然在大部分狀況下leader選舉只有很短的延時,但若分區數不少,當broker掛掉後,須要進行leader選舉的分區數就會不少。當前controller時單線程處理事件的,因此controller只能一個個地處理leader的變動請求,可能會拉長總體系統恢復的時間。



二.設置合理的分區數:
    基於以上3點,分區數的選擇毫不是多多益善的。用戶須要結合自身的實際環境基於吞吐量等指標進行一系列測試來肯定須要選擇多少分區數。有的用戶老是抱怨自身環境沒法達到官網給出的性能結果。其實官網的基準測試對用戶的實際意義不大,由於不一樣的硬件,軟件,網絡,負載狀況必然會帶來不一樣的測試結果。好比用戶使用1KB大小的啊消息進行測試,最後發現吞吐量才1MB/是,而官網說的每秒能達到10MB/s。這是由於官網使用的是100字節的消息體進行測試的,故根本沒有可比性。
    雖然無法給出統一的分區數,但用戶基本上能夠遵循下面的步驟來嘗試肯定分區數:
        1>.建立單分區的topic,而後在實際生產機器上分別測試producer和consumer的TPS,分別爲T(p) 和T(c)。
        2>.假設目標TPS是T(t),那麼分區數大體能夠肯定爲T(t)/max(T(p),T(c))。
    Kafka提供了專門的腳本kafka-producer-perf-test.sh和Kafka-consumer-perf-test.sh用於計算T(p) 和T(c)。這兩個腳本的具體使用方啊可參考我筆記:https://www.cnblogs.com/yinzhengjie/p/9953212.html。

  好了,關於吞吐量的調優我就不廢話了,直接總結一下調優TPS的一些參數清單和要點:

一.broker端
1>.適當增長num.replica.fetchers(該值控制了broker端follower副本從leader副本處獲取消息的最大線程數,默認值1表示follower副本只使用一個線程去實時拉取leader處的最新消息。對於設置了acks=all的producer而言,主要的延時可能都耽誤在follower與leader同步的過程,故增長該值一般可以縮短同步的時間間隔,從而間接地提高producer端的TPS),但不要超過CPU核數

2>.調優GC避免常常性的Full GC


二.producer端
1>.適當增長batch.size,好比100~512KB

2>.適當增長limger.ms,好比10~100ms

3>.設置compression.type=lz4(當前Kafka支持GZIP,Snappy和LZ4,但因爲目前一些固有配置等緣由,Kafka+LZ4組合的性能是最好的,所以推薦在那些CPU資源充足的環境中啓用producer端壓縮。)

4>.ack=0或1

5>.retries=0

6>.若干線程共享producer或分區數不少,增長buffer.memory


三.consumer端
1>.採用多consumer實例


2>.增長fetch.min.bytes(該參數控制了leader副本每次返回consumer的最小數據字節數。經過增長該參數值,默認值是1,Kafka會爲每一個FETCH請求的repsonse填入更多的數據,從而減小了網絡開銷並提高了TPS。),好比10000

 

 

四.調優延時

  針對不一樣的組件,延時(latency)的定義可能不一樣。對於producer而言,延時主要是消息發送的延時,即producer發送PRODUCE請求到broker端返回請求response的時間間隔;對consumer而言,延時衡量了consumer發送FETCH請求到broker端返回請求resonse的時間間隔。還有隻用延時定義表示的是集羣的端到端延時(end-to-end latency),即producer端發送消息到consumer端「看到」這條消息的時間間隔。不管是那種延時,他們調優的思想大體是相同的。

  下面總結一下調優延時的一些參數清單:

一.broker端

1>.適度增長num.replica.fetchers(該值控制了broker端follower副本從leader副本處獲取消息的最大線程數,默認值1表示follower副本只使用一個線程去實時拉取leader處的最新消息。對於設置了acks=all的producer而言,主要的延時可能都耽誤在follower與leader同步的過程,故增長該值一般可以縮短同步的時間間隔,從而間接地提高producer端的TPS)

2>.避免建立過多topic分區


二.producer端
1>.設置linger.ms=0

2>.設置compression.type=none


3>.設置acks=1或者0



三.consumer端

1>.設置fetch.min.bytes=1(該參數控制了leader副本每次返回consumer的最小數據字節數,默認值是1)

 

 

五.調優持久性

   顧名思義,持久性(durability)定義了Kafka集羣中消息不容易丟失的程度。持久性越高表面kafka越不會丟失消息。持久性一般由冗餘的手段就是備份機制(reolication)。它保證每條Kafka消息最終會保存在多臺broker上。這樣即便單個broker崩潰,數據依然是可用的。

  下面是總結調優醜就行的參數清單和要點:

一.broker端
1>.設置unclean.leader.election.enable=false(0.11.0.0以前版本須要顯式設置。0.11.0.0版本開始unclean.leader.election.enable參數的默認值由原來的true改成false,能夠關閉unclean leader election,也就是不在ISR(IN-Sync Replica)列表中的replica,不會被提高爲新的
leader partition。kafka集羣的持久化力大於可用性,若是ISR中沒有其它的replica,會致使這個partition不能讀寫。)


2>.設置auto.create.topics.enable=false(否容許自動建立topic,默認值是true,如果false,就須要經過命令建立topic,推薦設置爲false)


3>.設置replication.factor=3(指定分區的副本數,默認是1),min.insync.replicas(指定最少分區數據同步的個數,默認是1.)=replication.factor -1

4>.default.replication.factor=3(指定默認的分區數,默認是1)


5>.設置broker.rack屬性分區數據到不一樣幾家

6>.設置log.flush.interval.messages(指定了kafka寫入多少條消息後執行一次消息「落盤」,是頻率緯度上的參數)和log.flush.interval.ms( 指定款Kafka多長時間執行一次消息「落盤」,是時間維度上的參數)爲一個較小的值


二.producer端
1>.設置acks=all

2>.設置retries爲一個較大的值,好比10~303>.設置max.in.flight.requests.per.connection=1(客戶端在阻塞以前在單個鏈接上發送的未確認請求的最大數量。注意,若是該設置設置大於1,而且發送失敗,則存在因爲重試(即,若是啓用了重試)而致使消息從新排序的風險。默認值是5。簡單的來講,設置爲1能夠規避消息亂序的風險。)

4>.設置enable.idempotence=true(保證同一條消息只被broker寫入一次)啓用冪等性


三.consumer端
1>.設置auto.commit.enable=false(關閉自動提交位移)
2>.消息消費成功後調用commitSync提交位移(設置auto.commit.enable=false既然是手動提交,用戶須要調用commitSync方法來提位移,而不是使用commitAsync方法)。

 

六.調優可用性

  所謂可用性(availability)反應的是Kafka集羣應對崩潰的能力。不管broker,producer或consumer出現崩潰,kafka服務器依然保持可用狀態而不會由於failure就中斷服務。調優可用性就是要讓Kafka 更快地從崩潰中恢復。

一.broker端
1>.避免建立過多地分區

2>.設置unclean.leader.election.enable=true

3>.設置min.insync.replicas=1

4>.設置num.recovery.threads.per.data.dir=broker端參數log.dirs中設置的目錄數。


二.producer端

1>.設置acks=1,若必定要設置爲all,則遵循上面broker端的min.insync.replicas配置


三.consumer端
1>.設置session.timeout.ms爲較低的值,好比5~10秒。

2>.設置max.poll.interval.ms(默認是300000ms,即5分鐘。該參數賦予了consumer實例更多的時間來處理消息)爲此消息平均處理時間稍大的值。(0.10.1.0及以後版本)

3>.設置max.poll.records和max.partition.fetch.bytes減小consumer處理消息的總時長,避免頻繁rebalance。(0.10.1.0以前版本)
相關文章
相關標籤/搜索