Centos內核參數優化(大並發)


眾所周知在默認參數情況下linux對高並發支持並不友好,主要受限於單進程最大打開文件數限制,內核tcp參數方面和io時間分配機制等,下面從幾個方面來調整是linux系統能夠支持高並發環境。

1.iptables相關

  如非必要,關掉或卸載iptables防火牆,並阻止kernel加載iptables模塊。這些會影響並發性。

2.單進程打開文件數限制

  一般發行版,限制單進程最大可以打開1024個文件,這是遠遠不能滿足高並發需求的,調整過程如下:

  ulimit -n 查詢當前數值,ulimit -n 65535設為最大值

  如果輸出“Operationnotpermitted”之類,說明修改失敗,實際上是因為指定的數值超過了Linux系統對該用戶打開文件數的軟限制或硬限制,因此就需要修改Linux系統對用戶關於打開文件數的軟限制和硬限制。

  第一步修改limits.conf,並添加

  

 

   其中*號表示修改所有用戶限制,soft或hard指定要修改軟限制或硬限制;65536則指定了想要修改的新的限制,即最大打開文件數(請注意軟限制要小於或等於硬限制)。修改完保存文件。

  第二步修改/etc/pam.d/login文件,在文件中添加如下行:

  

 

   這是告訴Linux在用戶完成系統登錄后,在應該調用pam_limits.so模塊來設置系統對該用戶可使用的各種資源數量的最大限制(包括用戶可打開的最大文件數限制),而pam_limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值。修改后保存此文件。

  第三步查看linux系統級的最大打開文件數限制,使用如下命令:

  cat/proc/sys/fs/file-max

  輸出:ex:32568

  這表明這台Linux系統最多允許同時打開(即包含所有用戶打開文件總和)32568個文件,是linux系統的硬限制,所有用戶級的打開文件數限制都不應超過這個數值。通常這個系統級硬限制是Linux系統在啟動時根據系統硬件資源狀況計算出來的最佳的最大同時打開文件數限制,如果沒有特殊需要,不應該修改此限制。修改此限制的方法是修改/etc/sysctl.conf文件內fs.file-max=131072,這是讓linux啟動后強行將系統級打開文件數硬限制設置為131072。修改完成后保存文件。

  完成上述步驟后重啟系統,一般情況下就可以將Linux系統對指定用戶的單一進程允許同時打開的最大文件數限制設為指定的數值。如果重啟后用ulimit -n命令查看用戶可打開文件數限制仍然低於上述步驟中設置的最大值,這可能是因為在用戶登錄腳本/etc/profile中使用ulimit -n命令已經將用戶可同時打開文件數做了限制。由於通過ulimit -n修改系統對用戶可同時打開文件的最大數限制時,新修改的值只能小於或等於上次ulimit -n設置的值,因此想用此命令增大這個限制值是不可能的。所以如果有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查詢是否使用了ulimit -n限制了用戶可同時打開的最大文件數量,如果找到,則需要刪除這條命令,或者將其改為合適的值,然后保存文件用戶退出並重啟。

  通過上述步驟,就為支持高並發TCP連接處理的通訊處理程序解除關於打開文件數量方面的限制。

3.內核TCP參數方面

  Linux系統下,TCP連接斷開后,會以TIME_WAIT狀態保留一定的時間,然后才會釋放端口。當並發請求過多的時候,就會產生大量的TIME_WAIT狀態的連接,無法及時斷開的話,會占用大量的端口資源和服務器資源。這個時候我么可以優化TCP的內核參數,來及時將TIME_WAIT狀態的端口清理掉。

  下面介紹的方法只對擁有大量TIME_WAIT狀態的連接導致系統資源消耗有效,如果不是這種情況下,效果可能不明顯。可以試用netstat命令去查TIME_WAIT狀態的連接狀態,輸入下面的組合命令,輸入一面的組合命令查看當前TCP連接的狀態和對應的連接數量:

  netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

  

 

 

   我們只用關心TIM_EWAIT的個數,在這個可以看到,有18000多個TIME_WAIT,這樣就占用了18000多個端口。要知道端口的數量只有65536個,占用一個少一個,嚴重的影響到后繼的新連接。這種情況下,我們就有必要調整下linux的TCP內核參數,讓系統更快的釋放TIME_WAIT連接。

  編輯配置文件:/etc/sysctl.conf,這這個文件中,修改或加入下面的幾行內容:

  vim /etc/sysctl.conf

  net.ipv4.tcp_syncookies=1   #表示開啟syncookies。當出現syn等待隊列溢出時,啟用cookies來處理,可防范少量syn攻擊,默認為0,表示關閉。

  net.ipv4.tcp_tw_reuse=1    #表示開啟重用。允許將TIME_WAIT Sockets重新用於新的TCP連接,默認為0表示關閉。

  net.ipv4.tcp_tw_recycle=1    #表示開啟tcp連接中TIME_WAIT Sockets的快速回收,默認為0表示關閉。

  net.ipv4.tcp_fin_timeout=30  #修改系統默認的TIMEOUT時間

  保存關閉輸入sysctl-p使修改生效

  在經過這樣的調整之后,除了會進一步提升服務器的負載能力之外,還能夠防御小流量程度的Dos、CC、SYN攻擊。

  此外,如果你的連接數本身就很多,我們可以在優化一下TCP的可使用端口范圍,進一步提升服務器的並發能力。依然是往上面的參數文件中,修改或加入下面這些配置

  net.ipv4.tcp_keepalive_time=1200     #表示當keepalive起用的時候,tcp發送keepalive消息的頻度。缺省是2小時,改為20分鍾。

  net.ipv4.ip_local_port_range=1024 65535 #表示用於向外的連接的端口范圍。缺省值默認的情況下很小

  net.ipv4.tcp_max_syn_backlog=8192   #表示SYN隊列的長度,默認為1024,加大隊列長度為8192,可以容納更多等待連接的網絡連接數。

  net.ipv4.tcp_max_tw_buckets=5000   #表示系統同時保持TIME_WAIT的最大數量,如果超出這個數字,TIME_WAIT將立刻被清除並打印警告信息。默認180000,改為5000,此項參數可以控制TIME_WAIT的最大數量。

  保存關閉輸入sysctl-p使修改生效

4.內核其他參數說明

  net.ipv4.tcp_max_syn_backlog= 65536 #記錄的那些尚未收到客戶端確認信息的連接請求的最大值。對於有128M內存的系統而言,缺省值是1024,小內存的系統則是128

  net.core.netdev_max_backlog= 32768 #每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。

  net.core.somaxconn= 32768 #例如web應用中listen函數的backlog默認會給我們內核參數的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG默認為511,所以有必要調整這個值。

  net.core.wmem_default= 8388608

  net.core.rmem_default= 8388608

  net.core.rmem_max= 16777216 #最大socketbuffer,可參考的優化值:873200

  net.core.wmem_max= 16777216 #最大socketbuffer,可參考的優化值:873200

  net.ipv4.tcp_timestsmps= 0 #時間戳可以避免序列號的卷繞。一個1Gbps的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種“異常”的數據包。這里需要將其關掉。

  net.ipv4.tcp_synack_retries= 2 #為了打開對端的連接,內核需要發送一個SYN並附帶一個回應前面一個SYNACK。也就是所謂三次握手中的第二次握手。這個設置決定了內核放棄連接之前發送SYN+ACK包的數量。

  net.ipv4.tcp_syn_retries= 2 #在內核放棄建立連接之前發送SYN包的數量。

  #net.ipv4.tcp_tw_len= 1

  net.ipv4.tcp_tw_reuse= 1 #開啟重用。允許將TIME-WAITsockets重新用於新的TCP連接。

  net.ipv4.tcp_wmem= 8192 436600 873200 #TCPbuffer,可參考的優化值:8192 436600 873200

  net.ipv4.tcp_rmem = 32768 436600 873200 #TCPbuffer,可參考的優化值:32768 436600 873200

   net.ipv4.tcp_mem= 94500000 91500000 92700000

   #同樣有3個值,意思是:

  #net.ipv4.tcp_mem[0]:低於此值,TCP沒有內存壓力。

  #net.ipv4.tcp_mem[1]:在此值下,進入內存壓力階段。

  #net.ipv4.tcp_mem[2]:高於此值,TCP拒絕分配socket

  #上述內存單位是頁,而不是字節。可參考的優化值是:7864321048576 1572864

   net.ipv4.tcp_max_orphans= 3276800

  #系統中最多有多少個TCP套接字不被關聯到任何一個用戶文件句柄上,如果超過這個數字,連接將即刻被復位並打印出警告信息,這個限制僅僅是為了防止簡單的DoS攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個值(如果增加了內存之后)

  net.ipv4.tcp_fin_timeout= 30

  #如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。對端可以出錯並永遠不關閉連接,甚至意外當機。缺省值是60秒。2.2 內核的通常值是180秒,你可以按這個設置,但要記住的是,即使你的機器是一個輕載的WEB服務器,也有因為大量的死套接字而內存溢出的風險,FIN-WAIT-2的危險性比FIN-WAIT-1要小,因為它最多只能吃掉1.5K內存,但是它們的生存期長些。

  同時還涉及了一個TCP擁塞算法的問題,你可以用以下的命令去查看本機提供的擁塞算法控制模塊:

  sysctl net.ipv4.tcp_available_congestion_control

  #對於幾種算法的分析,詳情可以參考下:TCP擁塞控制算法的優缺點、適用環境、性能分析,比如高延時可以試用hybla,中等延時可以試用htcp算法等。

  net.ipv4.tcp_congestion_control=hybla #如果想設置TCP 擁塞算法為hybla

  net.ipv4.tcp_fastopen= 3 #額外的,對於內核版高於於3.7.1的,我們可以開啟tcp_fastopen

5.IO時間分配機制

  在linux啟動高並發Tcp連接,必須確認應用程序是否使用了合適的網絡I/O技術和I/O時間分派機制。可用的I/O技術有同步I/O,非阻塞式同步I/O,以及異步I/O。在高並發的情況下,如果使用同步I/O,這會嚴重阻塞程序的運轉,除非為每個TCP連接的I/O創建一個線程。但是過多的線程又會因系統對線程的調度造成巨大開銷。

  因此在高並發的情況下使用同步I/O是不可取的,這是可以考慮使用非阻塞是同步I/O或異步I/O。非阻塞是同步I/O的技術包括使用select(),poll(),epoll等機制。異步I/o的技術就是使用AIO。從I/O事件分派機制來看,使用select()是不合適的,因為它所支持的並發連接數有限制(通常是1024個)。如果考慮性能,poll()也是不合適的,盡管它可以支持較高的tcp並發數,但是由於其采用“輪詢”機制,當並發數較高時,其運行效率相當低,並可能存在I/O事件分派不均,導致部分TCP連接上的I/O出現“飢餓”現象。

  而如果使用epoll或AIO,則沒有上述問題(早期linux內核的AIO技術實現是通過在內核中為每個I/O請求創建一個線程來實現,這種實現機制在高並發TCP的情形下使用其實也有嚴重的性能問題,但在新的Linux內核中,AIO的實現已經得到改進)。

  綜上所述,在開發支持高並發TCP連接的linux應用程序時,應盡量使用epoll或AIO技術來實現並發的TCP連接上的I/O控制,這將為提升程序對高並發TCP連接的支持提供有效的I/O保證。

  經過這樣的優化配置之后,服務器的TCP並發處理能力會顯著提高。以上配置僅供參考,用於生產環境請根據自己的實際情況調整觀察再調整。

6.安裝大數據組件環境基礎優化

  1. 系統盤raid1,存儲盤raid0,hdfs三備份不用raid造成冗余,若對元數據安全系數特別高,namenode元數據所在磁盤可做raid1雙備份。
  2. 關閉硬件節能模式(bios)
  3. 雙網卡模式選擇bound6(平衡負載)
  4. 存儲盤多塊,減少磁盤IO
  5. 禁用swap
  6. 時間同步
  7. 關閉selinux
  8. 關閉防火牆iptables
  9. root啟動的單一進程的最大可以打開的文件數設置為65535個(ulimitn 65535

返回目錄


免責聲明!

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



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