《Kafka權威指南》讀書筆記-操做系統調優篇html
做者:尹正傑算法
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。api
大部分Linux發行版默認的內核調優參數配置已經可以知足大多數應用程序的運行需求,不過仍是能夠經過調整一些參數來進一步提高Kafka的性能。這些參數主要與虛擬內存,網絡子系統和用來存儲日誌片斷的磁盤掛在點有關。這些參數通常配置在「/etc/sysctl.conf」 文件裏,不過在對內核參數進行調整時,最好參考官方提供的操做系統文檔。緩存
一.虛擬內存安全
通常來講,Linux的虛擬內存會根據系統的工做負荷進行自動調整。咱們能夠對交換分區的處理方式和內存髒頁進行調整,從而讓Kafka更好的處理工做負載。對於大多數依賴吞吐量的應用程序來講,要儘可能避免內存交換。內存頁和磁盤之間的交換對Kafka各方面的性能都有重大影響。kafka大量地使用系統頁面緩存,若是虛擬內存被交換到磁盤,說明已經沒有多餘的內存能夠分配該頁面緩存啦。服務器
1>.把vm.swappiness的值設置的更小一點(默認值是60,推薦設置爲小於10的數字,好比1。)網絡
一種避免內存交換的方法是不設置任何交換分區。內存交換不是必須的 ,不過它確實可以在操做系統發生災難性錯誤時提供一些幫助。進行內存交換能夠防止操做系統因爲內存不足而忽然終止進程。基於上述緣由,建議把vm.swappiness的值設置的更小一點,好比1.該參數指明瞭操做系統將如何使用交換分區,而不是把內存頁從頁面緩存裏移除。要優先考慮減小頁面緩存,而不是進行內存交換。詳細操做步驟可參考個人筆記(連接在下文中能夠看到)。app
2>.爲何不把vm.swappiness設置爲零jvm
先前,人們建議把vm.swapiness設置爲0,它意味着「除非發生內存益處,不然不要進行內存交換」。直到Linux內核3.5-rcl版本發佈,這個值的意義才發生了變化。這個變化被一直到其餘的發行版本上,包括RedHat企業版內核2.6.32-303。在發生變化以後,0意味着「在任何狀況下都不要發生交換」。因此如今建議把這個值設置爲1。 性能
3>.Linux虛擬內存(swap)調優篇-「swappiness」,「vm.dirty_background_ratio」和「vm.dirty_ratio」
詳情請參考:http://www.javashuo.com/article/p-npamtzcy-m.html
二.磁盤與文件系統
除了選擇合適的磁盤硬件設備和使用RAID外,文件系統是性能影響的另外一個重要因素。有不少中文件系統可供選擇,不過對於本地文件系統來講,EXT4(第四代可擴展文件系統)和XFS最爲常見。近來,XFS稱爲不少Linux發行版默認的文件系統,由於它只須要作少許的調優即就能夠承擔大部分的工做負荷,比EXT4具備更好的表現。EXT4也能夠作得很好,但須要作更多的調優,存在較大的風險。其中包括設置設置更長的時間間隔(默認是5)一邊下降刷新的頻率。EXT4還引入了塊分配延遲,一旦系統崩潰,更容易形成數據的丟失和文件系統損壞。XFS也使用分配延遲算法,不過比EXT4的要安全些。
XFS爲Kafka提供了更好的性能,除了有文件系統提供的自動優化以外,無需額外的調優。批量寫入具備更高的效率,能夠提高總體的I/O吞吐量。換句話說,這種性能的提高主要影響的是Kafka的寫入能力。根據官網的測試報告,使用XFS的寫入時間大約是160ms,而使用Ext4大約是250ms。所以生產環境中最好使用XFS文件系統。
無論使用哪種文件系統來存儲日誌片斷,最好要對掛在點的noatime參數進行合理的設置。文件元數據包括三個時間戳:建立時間(ctime),最後修改時間(mtime)以及最後訪問時間(atime)。默認狀況下,每次文件被讀取後,都會更新atime,這會致使大量的磁盤讀寫操做,並且atime屬性用處不大,除非某些應用程序想要某個文件在最後一次修改後有沒有訪問過(這種狀況可使用retime)。Kafka用不到該屬性,因此徹底能夠把它禁用掉。爲掛載點設置noatime參數能夠防止更新atime,但不會影響ctime和mtime。
對於XFS用戶而言,推薦設置largeio參數,該參數將影響stat調用返回的I/O大小。對於大數據量的磁盤寫入操做而言,它可以提高必定的性能。largeio是標準的mount屬性,故可以使用與nobh相同的方式設置。
咱們只須要修改「/etc/fstab」這個開機啓動時會加載的文件便可,它主要時記錄操做系統開機自動掛載的事情,咱們能夠經過「df -h」查看磁盤掛載的狀況。咱們須要修改的地方我已經標識出來啦:
三.網絡
這裏指的的是OS級別的Socket緩衝區大小,而非Kafka本身提供的Socket緩衝區參數。事實上,Kafka本身的參數將其設置爲64KB,這對於普通的內網環境而言是足夠的,由於內網環境下往返時間(round-trip time,RRT)通常都很低,不會產生過多的數據堆積在Socket緩衝區中,但對於那些跨地區的數據傳輸而言,僅僅增長Kafka參數就不夠了,由於前者也受限於OS級別的設置。所以若是是作遠距離的數據傳輸,那麼建議將OS級別的Socket緩衝區調大,好比增長到128KB,甚至更大。
還有就是關掉沒有用不到的網絡服務,好比IPV6等,具體實操請參考個人筆記:http://www.javashuo.com/article/p-hewxfrui-m.html。
四.文件描述符限制優化
Kafka會頻繁地建立並修改文件系統中的文件,這包括消息的日誌文件,索引文件以及各類元數據管理文件等。咱們可使用ulimit進行資源管控,設置文件打開數據和用戶打開進程數等等,咱們也能夠編輯配置文件(/etc/security/limits.conf)並添加如下內容:(添加後推出當前終端,下一次登錄服務器時就會生效!)
[root@yinzhengjie ~]# cat /etc/security/limits.conf | grep -v ^# | grep -v ^$ * soft nofile 32768 * hard nofile 1048576 * soft nproc 65536 * hard nproc unlimited * soft memlock unlimited * hard memlock unlimited [root@yinzhengjie ~]#
除了上面的參數,咱們還能夠適當調大用戶打開的進程數:
[root@yinzhengjie ~]# cat /etc/security/limits.d/20-nproc.conf | grep -v ^# | grep -v ^$ * soft nproc 40960 root soft nproc unlimited [root@yinzhengjie ~]#
五.JVM參數優化
鑑於Kafka broker主要使用的時堆外內存,即大量使用操做系統的頁緩存,所以並不須要爲JVM分配太多的內存。在實際使用中,一般broker設置不超過6GB的堆空間,我們關於kafka的JVM調優對象主要針對2個配置文件,即:「kafka-run-class.sh」和「kafka-server-start.sh」兩個腳本(這兩個腳本都在Apache kafka安裝包解壓後的bin目錄下)。
1>."kafka-run-class.sh"
找到「# JMX settings」 這一行,咱們能夠自定義JMX的端口,舉個案例以下:
if [ -z "$KAFKA_JMX_OPTS" ]; then KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" fi
找到「# Generic jvm settings you want to add」這一行,你能夠自行添加JVM的參數列表,舉個案例以下:(注意,這個腳本會被kafka-server-start.sh腳本調用,所以這裏配置了就最好不要在其餘位置配置喲!)
# Generic jvm settings you want to add if [ -z "$KAFKA_OPTS" ]; then KAFKA_OPTS="-Xmx6g -Xms6g -XX:MetaspaceSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=85" fi
2>."kafka-server-start.sh"
咱們能夠找到「export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G」這一行參數,它定義了kafka啓動的堆內存大小,通常推薦不要超過6G,由於Kafka並非很吃內存,它主要吃的的是離堆內存。所以咱們須要把更多的內存留給OS。而kafka在寫數據時,數據並非真正寫入磁盤,而是寫到頁緩存中,而這些頁緩存就是OS的內存空間,最終數據由操做系統負責寫入磁盤。Kafka並不負責底層直接和內存進行交互。
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then export KAFKA_HEAP_OPTS="-Xmx5G -Xms5G" fi
舒適提示,咱們這裏制定了Kafka的heap內存爲5G,若是你在"kafka-run-class.sh"腳本中指定了Kafka的參數時,你會發現這個腳本的配置並不會生效,緣由是咱們在使用"kafka-server-start.sh"時會調用「kafka-run-class.sh」這個腳本,即Kafka的變量被覆蓋啦!所以咱們在啓動時發現kafka的heap內存爲6G。