【Free Style】kafka 解密:破除單機topic數多性能下降魔咒(下)
3.2.4????客戶端分析
Consumer客戶端,使用的是Scala的客戶端。
多硬盤,單分區下,JProfile如下:
400分區如下:
3000分區如下:
3000分區的時候,可以看到,97.8的cpu時間被用來執行了parseFull這個函數,這個函數是創建Streams的時候,對從zk獲取的json文件進行解析,每次只執行一次。
但是由于分區越多,這個文件越大越復雜,導致執行時間非常長,影響了Consumer的TPS。
由于這個函數只執行一次,不會大量被執行,所以當Consumer運行時間越長,那么影響會越小。
最開始使用Scala客戶端的測試,發現多分區下,大量的時間被消耗在日志打印參數的format函數上:
25分區:
這里的代碼,會在分個消息發送的時候,對分區的MAP循環執行如下的函數,這個代碼里面會多次拼接字符串很耗時。
通過屏蔽日志打印函數,避免執行format,可以大大提升TPS:
partitionMetadata.map?{?m?=>
m.leader?match?{
case?Some(leader) =>
//debug("Partition [%s,%d] has leader %d".format(topic, m.partitionId, leader.id))
new?PartitionAndLeader(topic,?m.partitionId,?Some(leader.id))
case?None?=>
//debug("Partition [%s,%d] does not have a leader yet".format(topic, m.partitionId))
new?PartitionAndLeader(topic,?m.partitionId,?None)
}
}.sortWith((s,?t) =>?s.partitionId?
那兩句debug信息打印注釋掉,能大大的提升TPS。
估計還有其他的瓶頸點,之后我們將測試客戶端切換到了java客戶端。
多硬盤一分區下,客戶端的情況(ACK=1):
多硬盤5000分區下,Producer客戶端(ACK=1):
多硬盤5000分區下,Producer客戶端(ACK=0)
我們可以看到,分區數量越大,send函數耗時越長,5000分區下,耗時大半。
ACK=0的時候,客戶端是不需要等待server的響應的,可以說基本上客戶端的TPS和服務器端沒有關系,但是,TPS照樣降低,send照樣消耗大量的時間。
所以,我們判斷,多硬盤下,當分區達到5000以上的時候,瓶頸在客戶端代碼上,可以通過優化客戶端代碼來提升性能。
4?????分析結論
4.1???結論
一、單Broker的分區,主要受以下幾個方面的瓶頸限制:
1、 OS限制:Kafka代碼中沒有對分區做限制,但是分區數量受到OS的文件句柄的數量限制??梢杂胾limit –a查看。需要調整該數目到一個較大的值。
2、?文件系統(磁盤刷盤):單硬盤下,磁盤IO和util會隨著分區數目增大而增大,導致Kafka的性能會下降。
主要原因:
刷盤是一個很昂貴的操作,雖然OS提供了Group Commit和排序等優化機制,但是當分區數量太多之后,無法完全消除影響。每個分區寫入是磁盤順序寫,但是多個分區同時順序寫入在操作系統層面變為了隨機寫入。
另外,當Pagecache的dirty數據達到一定限制之后,刷盤操作會阻塞應用的write操作,也會帶來影響。
3、?客戶端瓶頸:
通過追加硬盤可以解決單硬盤下的文件系統瓶頸。但是當達到5000以上,客戶端會成為瓶頸。
這個是由于發送消息的時候需要獲取Topic下的分區信息而產生的。
實際生產中,這個限制的影響應該不大,因為不會在1個Topic下劃分太多的分區,而是會有多個Topic,每個Topic下有一些分區。測試的時候為了測試方便,采取了一種比較極端的測試方法(單個Topic下掛上數千的分區)。
當有需要的時候,也可以考慮優化。
建議分區數量:
1、單臺服務器單硬盤下,推薦值1000,最好不超過2000。
2、單臺服務器多硬盤下(7個),推薦值3000,最好不要超過5000。(當分區被分散到多個Topic的時候,這個值會更高,預計至少可以達到7000以上)。
二、集群(多節點)的分區限制:
理論上是隨著節點增加而線性增加。但是實際還是受到Zookeeper的影響。節點最大支持數量估計在1w(zookeeper的限制)左右,那么整個集群分區的支持估計在百萬左右(但是實際上受網絡速度的影響,分區越大,存放在zookeeper的數據量越多等各種因素影響肯定會有個折扣)。
預計10w左右的分區支持問題不大。
1)????????參考LinkedIn的Kafka集群部署規模:
http://www.slideshare.net/miguno/apache-kafka-08-basic-training-verisign
2)?? 在這篇文章中,提到曾經在單broker上使用了上萬的分區。
http://www.confluent.io/blog/how-to-choose-the-number-of-topicspartitions-in-a-kafka-cluster/
4.2?? 社區意見參考
這里,kafka的committer有很明確的答復,基本上和我們驗證的結果一致:
http://www.quora.com/How-many-topics-can-be-created-in-Apache-Kafka
有幾個主要觀點:
1、 Kafka的分區數量兩個因素的影響:文件系統和zookeeper。
2、?實際應用中,分區數量不應該成為一個問題。分區的數量在實際中應該隨著消費者數量擴展,不應該根據Data的特征來擴展。
4.3??解決方案
針對目前的幾個瓶頸的解決方案如下:
1、 OS限制:通過調整Server的支持文件數目的句柄來解決。
2、?文件系統(磁盤刷盤):通過追加硬盤或追加Broker Node的方式來解決。
單個硬盤支持的分區數量推薦1000。多個硬盤:N*1000。
3、?客戶端:當一個Topic下有過多的分區的時候(>3000),客戶端預計會成為瓶頸。
如果有這種需求,可以考慮優化客戶端來解決這里的瓶頸。
5?????備注
5.1???參考資料
5.1.1????Cloudera配置Kafka的建議
http://blog.cloudera.com/blog/2015/07/deploying-apache-kafka-a-practical-faq/
非常好的實際經驗。
http://blog.cloudera.com/blog/category/kafka/
是否應當為Kafka Broker使用?固態硬盤?(SSD)
實際上使用SSD盤并不能顯著地改善?Kafka?的性能,主要有兩個原因:
·?????????Kafka寫磁盤是異步的,不是同步的。就是說,除了啟動、停止之外,Kafka的任何操作都不會去等待磁盤同步(sync)完成;而磁盤同步(syncs)總是在后臺完成的。這就是為什么Kafka消息至少復制到三個副本是至關重要的,因為一旦單個副本崩潰,這個副本就會丟失數據無法同步寫到磁盤。
·?????????每一個Kafka Partition被存儲為一個串行的WAL(Write Ahead Log)日志文件。因此,除了極少數的數據查詢,Kafka中的磁盤讀寫都是串行的。現代的操作系統已經對串行讀寫做了大量的優化工作。
如何對Kafka Broker上持久化的數據進行加密
目前,Kafka不提供任何機制對Broker上持久化的數據進行加密。用戶可以自己對寫入到Kafka的數據進行加密,即是,生產者(Producers)在寫Kafka之前加密數據,消費者(Consumers)能解密收到的消息。這就要求生產者(Producers)把加密協議(protocols)和密鑰(keys)分享給消費者(Consumers)。
另外一種選擇,就是使用軟件提供的文件系統級別的加密,例如Cloudera Navigator Encrypt。Cloudera Navigator Encrypt是Cloudera企業版(Cloudera Enterprise)的一部分,在應用程序和文件系統之間提供了一個透明的加密層。
Apache Zookeeper正成為Kafka集群的一個痛點(pain point),真的嗎?
Kafka高級消費者(high-level consumer)的早期版本(0.8.1或更早)使用Zookeeper來維護讀的偏移量(offsets,主要是Topic的每個Partition的讀偏移量)。如果有大量生產者(consumers)同時從Kafka中讀數據,對Kafka的讀寫負載可能就會超出它的容量,Zookeeper就變成一個瓶頸(bottleneck)。當然,這僅僅出現在一些很極端的案例中(extreme cases),即有成百上千個消費者(consumers)在使用同一個Zookeeper集群來管理偏移量(offset)。
不過,這個問題已經在Kafka當前的版本(0.8.2)中解決。從版本0.8.2開始,高級消費者(high-level consumer)能夠使用Kafka自己來管理偏移量(offsets)。本質上講,它使用一個單獨的Kafka Topic來管理最近的讀偏移量(read offsets),因此偏移量管理(offset management)不再要求Zookeeper必須存在。然后,用戶將不得不面臨選擇是用Kafka還是Zookeeper來管理偏移量(offsets),由消費者(consumer)配置參數?offsets.storage?決定。
Cloudera強烈推薦使用Kafka來存儲偏移量。當然,為了保證向后兼容性,你可以繼續選擇使用Zookeeper存儲偏移量。(例如,你可能有一個監控平臺需要從Zookeeper中讀取偏移量信息。)?假如你不得不使用Zookeeper進行偏移量(offset)管理,我們推薦你為Kafka集群使用一個專用的Zookeeper集群。假如一個專用的Zookeeper集群仍然有性能瓶頸,你依然可以通過在Zookeeper節點上使用固態硬盤(SSD)來解決問題。
Kafka是否支持跨數據中心的可用性
Kafka跨數據中心可用性的推薦解決方案是使用MirrorMaker。在你的每一個數據中心都搭建一個Kafka集群,在Kafka集群之間使用MirrorMaker來完成近實時的數據復制。
使用MirrorMaker的架構模式是為每一個”邏輯”的topic在每一個數據中心創建一個topic:例如,在邏輯上你有一個”clicks”的topic,那么你實際上有”DC1.clicks”和“DC2.clicks”兩個topic(DC1和DC2指得是你的數據中心)。DC1向DC1.clicks中寫數據,DC2向DC2.clicks中寫數據。MirrorMaker將復制所有的DC1 topics到DC2,并且復制所有的DC2 topics到DC1。現在每個DC上的應用程序都能夠訪問寫入到兩個DC的事件。這個應用程序能夠合并信息和處理相應的沖突。
另一種更復雜的模式是在每一個DC都搭建本地和聚合Kafka集群。這個模式已經被Linkedin使用,Linkedin Kafka運維團隊已經在?這篇Blog?中有詳細的描述(參見“Tiers and Aggregation”)。
5.1.2????大數據領域的架構圖
http://www.blogbus.com/navigating-logs/272257444.html
5.1.3????源代碼High level分析
http://ju.outofmemory.cn/entry/124628
5.1.4????Kafka的配置推薦
http://bbs.chinacloud.cn/archiver/showtopic-29836.aspx
http://liyonghui160com.iteye.com/blog/2163899
5.1.5????Zookeeper的討論
http://bbs.chinacloud.cn/archiver/showtopic-29836.aspx
重要的記錄:
5.1.6????Kafka跨集群同步方案
http://jingyan.baidu.com/article/8065f87fea4d3a233124989f.html
http://tangzhaohui.net/post/524
5.1.7????實踐部署與使用apache kafka
http://blog.csdn.net/zhongwen7710/article/details/41252649
5.1.8????從Apache Kafka?重溫文件高效讀寫
http://calvin1978.blogcn.com/articles/kafkaio.html
ZooKeeper Kafka
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。