Kafka最佳實踐


 

一、硬件考量

1.1、內存

不建議為kafka分配超過5g的heap,因為會消耗28-30g的文件系統緩存,而是考慮為kafka的讀寫預留充足的buffer。Buffer大小的快速計算方法是平均磁盤寫入數量的30倍。推薦使用64GB及以上內存的服務器,低於32GB內存的機器可能會適得其反,導致不斷依賴堆積機器來應付需求增長。(我們在生產環境使用的機器是64G內存的,但也看到LinkedIn用了大量28G內存的服務器。)

1.2、CPU

kafka不算是CPU消耗型服務,在主頻和CPU核數之間,選擇后者,將會獲得多核帶來的更好的並發處理性能。

1.3、磁盤

毋庸置疑,RAID是優先推薦的,它在底層實現了物理磁盤的負載均衡和冗余,雖然會犧牲一些磁盤空間和寫入性能。更進一步,我們推薦在配置中使用多目錄,每個目錄掛在在不同的磁盤(或者RAID)上。需要注意的是,NAS是不可取的,無論供應商如何吹噓他們的NAS的卓越性能。另外,我們經常看到用戶咨詢kafka是否一定要采用SSD,答案是沒有必要。

1.4網絡

分布式系統中,網絡的速度和可靠性異常重要,千兆甚至萬兆網絡現在應該成為數據中心的標配。避免kafka集群出現跨數據中心的情況,更要避免有很大的物理空間跨度,尤其中國還有詭異的聯通電信問題。kafka集群中各個節點地位均等,一旦因為延時導致分布式集群不穩定,排錯尤其困難。

1.5、文件系統

ext4是最佳選擇。

1.6、其它

在硬件越來越強大和雲計算如火如荼的今天,你需要在超高配置的服務器和IaaS供應商的數百個虛擬機之間做取舍。我們建議使用中等配置的服務器,因為集群規模越大,單台超高配置的服務器運行的節點越多,集群穩定性隨之下降,復雜度則會上升。

二、JVM的考慮

對於java應用,jvm和gc是繞不過去的坎。實踐表明,官方JDK1.7u51會是一個不錯的選擇,配合以G1來做垃圾回收。推薦配置可參考:

-Xms4g -Xmx4g -XX:PermSize=48m -XX:MaxPermSize=48m -XX:+UseG1GC-XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35

注:kafka版本更新會帶來變化。請隨時關注。我們現在的版本是kafka_2.11-0.8.2.1

三、File descriptors

kafka會使用大量文件和網絡socket,所以,我們需要把file descriptors的默認配置改為100000。修改方法如下:

#vi /etc/sysctl.conf

fs.file-max = 32000

#vi /etc/security/limits.conf

yourusersoftnofile10000

youruserhardnofile30000

四、關鍵配置項解讀

盡管默認配置已經很不錯,但出於性能和實際集群部署情況,我們還是需要講解一些重要的配置項。除此之外,如果對某個默認參數存在質疑,在詳細了解改參數的作用前,建議采用默認配置。

4.1、zookeeper.connect

必配參數,建議在kafka集群的每天機器都配置所有zk。

4.2、broker.id

必配參數。集群節點的標示符,不得重復。取值范圍0~n。

4.3、log.dirs

建議參照文章前面描述的磁盤配置,不要使用默認的“/tmp/kafka-logs”

4.4、advertised.host.name

注冊到zk供用戶使用的主機名。內網環境通常無需配置,而IaaS一般需要配置為公網地址。默認為“host.name”,可以通過java.net.InetAddress.getCanonicalHostName()接口獲取該值。

4.5、advertised.port

注冊到zk供用戶使用的服務端口,通常在IaaS環境需要額外配置。

4.6、num.partitions

自動創建topic的默認partition數量。默認是1,為了獲得更好的性能,建議修改為更大。最優取值參考后文。

4.7、default.replication.factor

自動創建topic的默認副本數量,官方建議修改為2;但通常一個副本就足夠了。

4.8、min.insync.replicas

ISR提交生成者請求的最小副本數。

4.9、unclean.leader.election.enable

是否允許不具備ISR資格的replicas選舉為leader作為不得已的措施,甚至不惜犧牲部分數據。默認允許。建議允許。數據異常重要的情況例外。

4.10、controlled.shutdown.enable

在kafka收到stop命令或者異常終止時,允許自動同步數據。建議開啟。

五、動態調整配置

大部分kafka配置是寫死在properties文件里的。然而,許多關於topic的參數我們可以動態調配,kafka-topic.sh工具提供了該功能,更改將一直生效直到服務器重啟。可以調整的參數如下:

unclean.leader.election.enable:不嚴格的leader選舉,有助於集群健壯,但是存在數據丟失風險。

min.insync.replicas:如果同步狀態的副本小於該值,服務器將不再接受request.required.acks為-1或all的寫入請求。

max.message.bytes:單條消息的最大長度。如果修改了該值,那么replica.fetch.max.bytes和消費者的fetch.message.max.bytes也要跟着修改。

cleanup.policy:生命周期終結數據的處理,默認刪除。

flush.messages:強制刷新寫入的最大緩存消息數。

flust.ms:強制刷新寫入的最大等待時長。

還有segment.bytes、segment.ms、retention.bytes、retention.ms和segment.jitter.ms。詳見官方解釋。

六、性能優化技巧

6.1、配置合適的partitons數量。

這似乎是kafka新手必問得問題。首先,我們必須理解,partiton是kafka的並行單元。從producer和broker的視角看,向不同的partition寫入是完全並行的;而對於consumer,並發數完全取決於partition的數量,即,如果consumer數量大於partition數量,則必有consumer閑置。所以,我們可以認為kafka的吞吐與partition時線性關系。partition的數量要根據吞吐來推斷,假定p代表生產者寫入單個partition的最大吞吐,c代表消費者從單個partition消費的最大吞吐,我們的目標吞吐是t,那么partition的數量應該是t/p和t/c中較大的那一個。實際情況中,p的影響因素有批處理的規模,壓縮算法,確認機制和副本數等,然而,多次benchmark的結果表明,單個partition的最大寫入吞吐在10MB/sec左右;c的影響因素是邏輯算法,需要在不同場景下實測得出。

這個結論似乎太書生氣和不實用。我們通常建議partition的數量一定要大於等於消費者的數量來實現最大並發。官方曾測試過1萬個partition的情況,所以不需要太擔心partition過多的問題。下面的知識會有助於讀者在生產環境做出最佳的選擇:

a、一個partition就是一個存儲kafka-log的目錄。

b、一個partition只能寄宿在一個broker上。

c、單個partition是可以實現消息的順序寫入的。

d、單個partition只能被單個消費者進程消費,與該消費者所屬於的消費組無關。這樣做,有助於實現順序消費。

e、單個消費者進程可同時消費多個partition,即partition限制了消費端的並發能力。

f、partition越多則file和memory消耗越大,要在服務器承受服務器設置。

g、每個partition信息都存在所有的zk節點中。

h、partition越多則失敗選舉耗時越長。

k、offset是對每個partition而言的,partition越多,查詢offset就越耗時。

i、partition的數量是可以動態增加的(只能加不能減)。

我們建議的做法是,如果是3個broker的集群,有5個消費者,那么建議partition的數量是15,也就是broker和consumer數量的最小公倍數。當然,也可以是一個大於消費者的broker數量的倍數,比如6或者9,還請讀者自行根據實際環境裁定。

 

本文摘自:http://www.jianshu.com/p/8689901720fd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM