Linux核心最佳化

來源:互聯網
上載者:User

Linux核心最佳化

聲明:本文檔來自互連網整理部份加自已實驗部份所得:

TCP 相關部份

常用名詞說明:

retries(再試)、

TCP 伺服器 <---> 用戶端通訊狀態

SYN---------------->

<--------------SYN,ACK

ACK---------------> 建立串連

Data1---------------->

<---------------Data1,ACK

Data2---------------->

<---------------未回複

Data2---------------->重傳 [ 序列參數 tcp_sack, tcp_fack ]

[ 重傳次數參數: tcp_retries1,tcp_retries2, tcp_orphan_retries ]

資料轉送

FIN------------------>

<-----------------FIN,ACK(有時候FIN,ACK分兩次)

ACK-----------------> 中斷連線.主動關閉

FIN------------------>

<-----------------CLOSE_WAIT

SYN表示建立串連, RTT(Round-Trip Time): 往返時延

FIN表示關閉串連, RTO(Retransmission TimeOut)即重傳逾時時間

ACK表示響應,

PSH表示有 DATA資料轉送,

RST表示串連重設

TCP 抓包常見錯誤

tcp out-of-order(tcp有問題) #多數是網路擁塞引起的

tcp segment of a reassembled PDU #TCP 分區標識

Tcp previous segment lost(tcp先前的分區丟失)

Tcp acked lost segment(tcp應答丟失)

Tcp window update(tcp視窗更新)

Tcp dup ack(tcp重複應答)

Tcp keep alive(tcp保持活動)

Tcp retransmission(tcp 重傳)

 

核心參數解釋

net.ipv4.tcp_timestamps = 1

說明:

該參數控制RFC 1323 時間戳記與視窗縮放選項。預設情況下,啟用時間戳記與

視窗縮放,但是可以使用標誌位進行控制。0位控制視窗縮放,1 位控制時間戳記。

值為0(禁用 RFC 1323選項)

值為1(僅啟用視窗縮放)

值為2(僅啟用時間戳記)

值為3(兩個選項均啟用)

net.ipv4.tcp_timestamps=0

說明:

時間戳記可以避免序號的卷繞。一個1Gbps的鏈路肯定會遇到以前用過的序號。時間戳記能夠讓核心接受這種“異常”的資料包。這裡需要將其關掉。

值為0(禁用時間戳記)

值為1(啟用時間戳記)

只有用戶端和服務端都開啟時間戳記的情況下,才會出現能ping通不能建立tcp三向交握的情況,所以做為提供服務的公司,不可能保證所有的使用者都關閉時間戳記,這個功能,所以我們必須關閉時間戳記,這樣才能給所用使用者提供正常的服務。

net.ipv4.tcp_window_scaling = 1

net.ipv4.tcp_sack = 1

使用 Selective ACK﹐它可以用來尋找特定的遺失的資料報— 因此有助於快速恢複狀態。該檔案表示是否啟用有選擇的應答(Selective Acknowledgment),這可以通過有選擇地應答亂序接收到的報文來提高效能(這樣可以讓寄件者只發送丟失的報文段)。(對於廣域網路通訊來說這個選項應該啟用,但是這會增加對 CPU 的佔用。)

net.ipv4.tcp_fack = 1

開啟FACK(Forward ACK)擁塞避免和快速重傳功能。(注意,當tcp_sack設定為0的時候,這個值即使設定為1也無效)

net.ipv4.tcp_retrans_collapse = 1

net.ipv4.tcp_syn_retries = 5

對於一個建立串連,核心要發送多少個 SYN 串連請求才決定放棄。不應該大於255,預設值是5,對應於180秒左右時間。(對於大負載而物理通訊良好的網路而言,這個值偏高,可修改為2.這個值僅僅是針對對外的串連,對進來的串連,是由tcp_retries1 決定的)

net.ipv4.tcp_synack_retries = 5

tcp_synack_retries顯示或設定 Linux 核心在回應 SYN 要求時會嘗試多少次重新發送初始 SYN,ACK 封包後才決定放棄。這是所謂的三段交握 (threeway handshake) 的第二個步驟。即是說系統會嘗試多少次去建立由遠端啟始的 TCP 連線。tcp_synack_retries 的值必須為正整數,並不能超過 255。因為每一次重新發送封包都會耗費約 30 至 40 秒去等待才決定嘗試下一次重新發送或決定放棄。tcp_synack_retries 的預設值為 5,即每一個連線要在約 180 秒 (3 分鐘) 後才確定逾時.

net.ipv4.tcp_max_orphans = 131072

系統所能處理不屬於任何進程的TCP sockets最大數量。假如超過這個數量,那麼不屬於任何進程的串連會被立即reset,並同時顯示警告資訊。之所以要設定這個限制﹐純粹為了抵禦那些簡單的 DoS 攻擊﹐千萬不要依賴這個或是人為的降低這個限制,更應該增加這個值(如果增加了記憶體之後)。每個孤兒通訊端最多能夠吃掉你64K不可交換的記憶體。

net.ipv4.tcp_max_tw_buckets = 5000

表示系統同時保持TIME_WAIT通訊端的最大數量,如果超過這個數字,TIME_WAIT通訊端將立刻被清除並列印警告資訊。預設為180000。設為較小數值此項參數可以控制TIME_WAIT通訊端的最大數量,避免伺服器被大量的TIME_WAIT通訊端拖死。

net.ipv4.tcp_keepalive_time = 7200

net.ipv4.tcp_keepalive_probes = 9

net.ipv4.tcp_keepalive_intvl = 75
用執行個體進行說明上述三個參數:

如果某個TCP串連在idle 2個小時後,核心才發起probe(探查).如果probe 9次(每次75秒既tcp_keepalive_intvl值)不成功,核心才徹底放棄,認為該串連已失效。

net.ipv4.tcp_retries1 = 3

放棄回應一個TCP串連請求前﹐需要進行多少次重試。RFC 規定最低的數值是3﹐這也是預設值﹐根據RTO的值大約在3秒 - 8分鐘之間。(注意:這個值同時還決定進入的syn串連)

(第二種解釋:它表示的是TCP傳輸失敗時不檢測路由表的最大的重試次數,當超過了這個值,我們就需要檢測路由表了)

net.ipv4.tcp_retries2 = 15

在丟棄啟用(已建立通訊狀況)的TCP串連之前﹐需要進行多少次重試。預設值為15,根據RTO的值來決定,相當於13-30分鐘(RFC1122規定,必須大於100秒).(這個值根據目前的網路設定,可以適當地改小,我的網路內修改為了5)

(第二種解釋:表示重試最大次數,只不過這個值一般要比上面的值大。和上面那個不同的是,當重試次數超過這個值,我們就必須放棄重試了)

net.ipv4.tcp_orphan_retries

主要是針對孤立的socket(也就是已經從進程上下文中刪除了,可是還有一些清理工作沒有完成).對於這種socket,我們重試的最大的次數就是它

net.ipv4.tcp_fin_timeout = 30

表示如果通訊端由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間

net.ipv4.tcp_tw_recycle = 1

表示開啟TCP串連中TIME-WAITsockets的快速回收,預設為0,表示關閉

net.ipv4.tcp_stdurg = 0

net.ipv4.tcp_rfc1337 = 0

net.ipv4.tcp_max_syn_backlog = 8192

表示SYN隊列的長度,預設為1024,加大隊列長度為8192,可以容納更多等待串連的網路連接數。

(第二種解釋:連接埠最大backlog 核心限制。此參數限制服務端應用程式 可以設定的連接埠最大backlog 值 (對應於連接埠的 syn_backlog 和 backlog 隊列長度)。動機是在記憶體有限的伺服器上限制/避免應用程式配置超大 backlog 值而耗盡核心記憶體。如果應用程式設定 backlog 大於此值,作業系統將自動將之限制到此值。)

net.ipv4.tcp_abort_on_overflow = 0

當 tcp 建立串連的 3 路握手完成後,將串連置入ESTABLISHED 狀態並交付給應用程式的 backlog 隊列時,會檢查 backlog 隊列是否已滿。若已滿,通常行為是將串連還原至 SYN_ACK狀態,以造成 3 路握手最後的 ACK 包意外丟失假象 —— 這樣在用戶端等待逾時後可重發 ACK —— 以再次嘗試進入ESTABLISHED 狀態 —— 作為一種修複/重試機制。如果啟用tcp_abort_on_overflow 則在檢查到 backlog 隊列已滿時,直接發 RST 包給用戶端終止此串連 —— 此時用戶端程式會收到 104Connection reset by peer 錯誤。

警告:啟用此選項可能導致高峰期使用者訪問體驗到 104:Connection reset by peer 或白屏錯誤(視瀏覽器而定)。在考慮啟用此選項前應先設法最佳化提高服務端應用程式的效能,使之能更快接管、處理串連。

net.ipv4.tcp_syncookies = 1

在 tcp 建立串連的 3 路握手過程中,當服務端收到最初的 SYN 請求時,會檢查應用程式的 syn_backlog 隊列是否已滿。若已滿,通常行為是丟棄此 SYN 包。若未滿,會再檢查應用程式的 backlog 隊列是否已滿。若已滿並且系統根據記錄判斷該應用程式不會較快消耗串連時,則丟棄此 SYN 包。如果啟用 tcp_syncookies 則在檢查到 syn_backlog 隊列已滿時,不丟棄該 SYN 包,而改用 syncookie 技術進行 3 路握手。

警告:使用 syncookie 進行握手時,因為該技術挪用了 tcp_options 欄位空間,會強制關閉 tcp 進階流控技術而退化成原始 tcp 模式。此模式會導致封包 丟失時 對端 要等待 MSL 時間來發現丟包事件並重試,以及關閉串連時 TIME_WAIT 狀態保持 2MSL 時間。該技術應該僅用於保護syn_flood 攻擊。如果在正常伺服器環境中伺服器負載較重導致 syn_backlog 和 backlog 隊列滿時,應最佳化服務端應用程式的負載能力,加大應用程式 backlog 值。不過,所幸該參數是自動值,僅在 syn_backlog 隊列滿時才會觸發 (在隊列恢複可用時此行為關閉)。

? 服務端應用程式設定連接埠backlog 值,核心理論上將允許該連接埠最大同時接收 2*backlog 個並發串連”請求”(不含已被應用程式接管的串連) ——分別存放在 syn_backlog 和 backlog 隊列—— 每個隊列的長度為backlog 值。syn_backlog 佇列儲存體 SYN_ACK 狀態的串連,backlog 則儲存 ESTABLISHED 狀態但尚未被應用程式接管的串連。

? syn_backlog 隊列實際上是個 hash 表,並且 hash 表大小為 2 的次方。所以實際 syn_backlog 的隊列長度要略大於應用程式設定的 backlog 值—— 取對應 2 的次方值。

? 當 backlog 值較小,而高峰期並發串連請求超高時,tcp 建立串連的三路握手 網路時延將成為瓶頸 —— 並發串連超高時,syn_backlog 隊列將被充滿而導致 `can’t connect` 錯誤。此時,再提高服務端應用程式的吞吐能力已不起作用,因為串連尚未建立,服務端應用程式並不能接管和處理這些串連—— 而是需要加大backlog 值 (syn_backlog 隊列長度) 來緩解此問題。

? 啟用 syncookie 雖然也可以解決超高並發時的`can’t connect` 問題,但會導致 TIME_WAIT 狀態 fallback 為保持 2MSL 時間,高峰期時會導致用戶端無可複用串連而無法串連伺服器 (tcp 串連複用是基於 <src_ip, src_port, dst_ip, dst_port> 四元組值必須不相同,就訪問同一個目標伺服器而言,<src_ip, dst_ip, dst_port> 三元組值不變,所以此時可用的串連數限制為僅src_port 所允許數目,這裡處於 TIME_WAIT 狀態的相同 src_port 串連不可複用。Linux 系統甚至更嚴格,只使用了 <src_ip, src_port, dst_ip> 三元組…)。故不建議依賴syncookie。

net.ipv4.tcp_orphan_retries = 0

本端試圖關閉TCP串連之前重試多少次。預設值是7,相當於50秒~16分鐘(取決於RTO)。如果你的機器是一個重載的WEB伺服器,你應該考慮減低這個值,因為這樣的通訊端會消耗很多重要的資源。參見tcp_max_orphans

net.ipv4.tcp_sack = 1

SACK(SelectiveAcknowledgment,選擇性確認)技術,使TCP只重新發送互動過程中丟失的包,不用發送後續所有的包,而且提供相應機制使接收方能告訴發送方哪些資料丟失,哪些資料重發了,哪些資料已經提前收到了。如此大大提高了用戶端與伺服器端資料互動的效率。

net.ipv4.tcp_reordering = 3

net.ipv4.tcp_ecn = 2

net.ipv4.tcp_dsack = 1

允許TCP發送”兩個完全相同”的SACK。

net.ipv4.tcp_mem = 178368 237824 356736

同樣有3個值,意思是:
net.ipv4.tcp_mem[0]: 低於此值,TCP沒有記憶體壓力.
net.ipv4.tcp_mem[1]: 在此值下,進入記憶體壓力階段.
net.ipv4.tcp_mem[2]: 高於此值,TCP拒絕分配socket.

net.ipv4.tcp_wmem = 4096 16384 4194304

TCP寫buffer,可參考的最佳化值: 8192436600 873200

net.ipv4.tcp_rmem = 4096 87380 4194304

TCP讀buffer,可參考的最佳化值:32768 436600 873200

net.ipv4.tcp_app_win = 31

net.ipv4.tcp_adv_win_scale = 2

net.ipv4.tcp_tw_reuse = 1

表示開啟重用。允許將TIME-WAITsockets重新用於新的TCP串連,預設為0,表示關閉;

net.ipv4.tcp_frto = 2

開啟F-RTO,一個針對TCP重傳逾時(RTOs)的增強恢複演算法。在無線環境下特別有益處,因為在這種環境下分組丟失典型地是因為隨機無線電幹擾而不是中間路由器組塞。參考RFC 4318瞭解更多的細節。

這個檔案擁有下列值之一:

? 0 禁用。

? 1 開啟基本版本的F-RTO演算法。

? 2 如果流使用SACK的話,開啟SACK-增強F-TRO演算法。不過當使用SACK時是基本版本也是可以使用的,因為有這種情境存在,F-RTO和開啟SACK的TCP流分組計數合作不好。

net.ipv4.tcp_frto_response = 0

當F-RTO偵測到TCP逾時是偽的時(例如,通過設定了更長的逾時值避免了逾時),TCP有幾個選項決定接下來如何去做。可能的值是:

? 1 基於速率減半;平滑保守的響應,導致一個RTT之後擁塞視窗(cwnd)和慢啟動閥值(ssthresh)減半。

? 2非常保守的響應;不推薦這樣做,因為即時有效,它和TCP的其他部分互動不好;立即減半擁塞視窗(cwnd)和慢啟動閥值(ssthresh)。

? 3侵佔性的響應;廢棄現在已知不必要的擁塞控制措施(或略一個將引起TCP更加謹慎保守的丟失的重傳);cwnd and ssthresh恢複到逾時之前的值。

net.ipv4.tcp_slow_start_after_idle = 1

表示擁塞視窗在經過一段空閑時間後仍然有效而不必重新初始化。

net.ipv4.tcp_low_latency = 0

允許 TCP/IP 協議棧適應在高輸送量情況下低延時的情況;這個選項應該禁用。

net.ipv4.tcp_no_metrics_save = 0

一個tcp串連關閉後,把這個串連曾經有的參數比如慢啟動門限snd_sthresh,擁塞視窗snd_cwnd 還有srtt等資訊儲存到dst_entry中, 只要dst_entry 沒有失效,下次建立立相同串連的時候就可以使用儲存的參數來初始化這個串連.tcp_no_metrics_save 設定為1就是不保持這些參數(經驗值),每次建立串連後都重新摸索一次. 我覺得沒什麼好處. 所以系統預設把它設為0。

net.ipv4.tcp_moderate_rcvbuf = 1

開啟了TCP記憶體自動調整功能(1為開啟、0為禁止)

net.ipv4.tcp_tso_win_divisor = 3

單個TSO段可消耗擁塞視窗的比例,預設值為3。

net.ipv4.tcp_congestion_control = cubic

net.ipv4.tcp_available_congestion_control = cubic reno

net.ipv4.tcp_allowed_congestion_control = cubic reno

丟包使得TCP傳輸速度大幅下降的主要原因是丟包重傳機制,控制這一機制的就是TCP擁塞控制演算法。 congestion(擁塞)

Linux核心中提供了若干套TCP擁塞控制演算法,已載入進核心的可以通過核心參數net.ipv4.tcp_available_congestion_control看到:

沒有載入進核心的一般是編譯成了模組,可以用modprobe載入,這些演算法各自適用於不同的環境。

? reno是最基本的擁塞控制演算法,也是TCP協議的實驗原型。

? bic適用於rtt較高但丟包極為罕見的情況,比如北美和歐洲之間的線路,這是2.6.8到2.6.18之間的Linux核心的預設演算法。

? cubic是修改版的bic,適用環境比bic廣泛一點,它是2.6.19之後的linux核心的預設演算法。

? hybla適用於高延時、高丟包率的網路,比如衛星鏈路。

載入tcp_hybl模組 modprobe tcp_hybla

TCP擁塞控制 演算法對TCP傳輸速率的影響可很大。

net.ipv4.tcp_abc = 0

net.ipv4.tcp_mtu_probing = 0

net.ipv4.tcp_fastopen

GoogleTFO特性,kernel 3.6以上版本支援,具體實現方法參考本文檔 Google TFO特性。

net.ipv4.tcp_base_mss= 512

分組層路徑MTU發現(MTU探測)中使用的search_low的初始值。如果允許MTU探測,這個初始值就是串連使用的初始MSS值。

net.ipv4.route.min_adv_mss= 256

該檔案表示最小的MSS(MaximumSegment Size)大小,取決於第一跳的路由器MTU。

net.ipv4.tcp_workaround_signed_windows = 0

net.ipv4.tcp_dma_copybreak= 4096

下限.以位元組為單位.socket 的大小將卸載到一個 dma 複製引擎.如果存在一個在系統和核心配置為使用 config_net_dma 選項。

net.ipv4.tcp_max_ssthresh= 0

慢啟動階段,就是當前擁塞視窗值比慢啟動閾值(snd_ssthresh)小的時候,所處的階段就叫做慢啟動階段。

當我們收到一個新的ACK時,則會調用tcp_slow_start()這個函數,並且為擁塞視窗增加1.(Linux中擁塞視窗的值代表資料包的個數,而不是實際的發送

位元組數目。實際可以發送的位元組數等於可以發送的資料包個數*MSS。)

直到慢啟動階段出現資料包的丟失。

而引入了tcp_max_ssthresh 這個參數後,則可以控制在慢啟動階段擁塞視窗增加的頻度。

預設這個參數不開啟,如果這個參數的值設定為1000,則當擁塞視窗值大於1000時,

則沒收到一個ACK,並不再增加擁塞視窗一個單位了,而是約收到2個ACK才增加一個視窗單位。收到2ACK並不是決定值!!

需要根據當前的擁塞視窗值,tcp_max_ssthresh值進行判斷。

net.ipv4.tcp_thin_linear_timeouts= 0

這個函數RTO逾時的處理函數。如果是thin流,則不要新設RTO是原先的2倍。

net.ipv4.tcp_thin_dupack= 0

與tcp_thin_linear_timeouts同為快速重傳演算法參數

net.core.netdev_max_backlog=300

進入包的最大裝置隊列.預設是300,對重負載伺服器而言,該值太低,可調整到1000。

ip link set eth0mtu 1500

設定網卡mtu大小。

IP 相關部份

net.ipv4.ip_local_port_range = 1024 65000

表示用於向外串連的連接埠範圍。預設情況下很小:32768到61000,改為1024到65000。

net.ipv4.ip_conntrack_max = 655360

在核心記憶體中netfilter可以同時處理的“任務”(串連跟蹤條目)another

# 避免放大攻擊

net.ipv4.icmp_echo_ignore_broadcasts = 1

# 開啟惡意icmp錯誤訊息保護

net.ipv4.icmp_ignore_bogus_error_responses = 1

# 開啟SYN洪水攻擊保護

net.ipv4.tcp_syncookies = 1

# 開啟並記錄欺騙,源路由和重新導向包

net.ipv4.conf.all.log_martians = 1

net.ipv4.conf.default.log_martians = 1

# 處理無源路由的包

net.ipv4.conf.all.accept_source_route = 0

net.ipv4.conf.default.accept_source_route = 0

# 開啟反向路徑過濾

net.ipv4.conf.all.rp_filter = 1

net.ipv4.conf.default.rp_filter = 1

# 確保無人能修改路由表

net.ipv4.conf.all.accept_redirects = 0

net.ipv4.conf.default.accept_redirects = 0

net.ipv4.conf.all.secure_redirects = 0

net.ipv4.conf.default.secure_redirects = 0

# 不充當路由器

net.ipv4.ip_forward = 0

net.ipv4.conf.all.send_redirects = 0

net.ipv4.conf.default.send_redirects = 0

# 開啟execshild

kernel.exec-shield = 1

kernel.randomize_va_space = 1

網路相關部份(/sys)

sys/class/net/eth0/statistics.rx_packets:

收到的資料包資料

sys/class/net/eth0/statistics.tx_packets:

傳輸的資料包數量

sys/class/net/eth0/statistics.rx_bytes:

接收的位元組數

sys/class/net/eth0/statistics.tx_bytes:

傳輸的位元組數

sys/class/net/eth0/statistics.rx_dropped:

收包時丟棄的資料包

sys/class/net/eth0/statistics.tx_dropped:

發包時丟棄的資料包

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.