? 上一篇下一篇 ?

Linux系統內核優化的一些建議,幫助大家更順暢的使用Linux

   Linux操作系統具有其他操作系統所不具備的優勢,但是,在系統內核方面還存在一定的不足,其中包括系統內核調度算法問題和系統內核中基于優先級的可搶占式調度策略問題.針對這兩個問題,該文提出了一些個人的建議

關閉swap

如果服務器上有運行數據庫服務或消息中間件服務,請關閉交換分區

 
1
2
echo "vm.swappiness = 0" >> /etc/sysctl.conf
sysctl -p

OOM Killer

一般我們的linux服務都是混部服務的,每個程序申請的物理內存都是共享的;例如物理內存只有1g,啟動2個程序各申請1g是可以的,linux通過這種過度分配的方式來達到內存的充分利用,當程序實際使用內存超出物理內存時,會被系統按照優先級,殺掉一部分程序以確保其它程序的正常運行;為了避免核心服務被殺,可以將進程文件設置為最高優先級。

 
1
2
# 數值越小越不容易被殺
echo -17 > /proc/$pid/oom_score_adj
 

TCP設置

因為我們提供的數據庫和一些消息中間件服務都是內網工作的,所以可以針對內網對TCP參數進行一些優化。

  • net.ipv4.tcp_syn_retries

默認值為6,參考值為2。主機作為客戶端,對外發起TCP連接時,即三次握手的第一步,內核發送SYN報文的重試次數,超過這個次數后放棄連接。內網環境通信良好,因此可以適度降低此值

  • net.ipv4.tcp_synack_retries

默認值為5,參考值為2。主機作為服務端,接受TCP連接時,在三次握手的第二步,向客戶端發送SYN+ACK報文的重試次數,超過這個次數后放棄連接。內網環境中可適度降低此值

  • net.ipv4.tcp_timestamps

是否開啟時間戳,開啟后可以更精確地計算RTT,一些其他特性也依賴時間戳字段。

  • net.ipv4.tcp_tw_reuse

默認值為0,建議值為1。是否允許將處于TIME_WAIT狀態的socket用于新的TCP連接。這對于降低TIME_WAIT數量很有效。該參數只有在開啟tcp_timestamps的情況下才會生效。

  • net.ipv4.tcp_tw_recycle

是否開啟TIME_WAIT套接字的快速回收,這是比tcp_tw_reuse更激進的一種方式,它同樣依賴tcp_timestamps選項。強烈建議不要開啟tcp_tw_recycle,原因有兩點,一是TIME_WAIT是十分必要的狀態,避免關閉中的連接與新建連接之間的數據混淆,二是tcp_tw_recycle選項在NAT環境下會導致一些新建連接被拒絕,因為NAT下每個主機存在時差,這體現在套接字中的時間戳字段,服務端會發現某個IP上的本應遞增的時間戳出現降低的情況,時間戳相對降低的報文將被丟棄

  • net.core.somaxconn

默認值為128,參考值為2048。定義了系統中每一個端口上最大的監聽隊列的長度。當服務端監聽了某個端口時,操作系統內部完成對客戶端連接請求的三次握手。這些已建立的連接存儲在一個隊列中,等待accept調用取走。本選項就是定義這個隊列的長度。調大該值,可降低高并發場景下服務端的reject次數。

  • net.ipv4.tcp_max_syn_backlog

客戶端的請求在服務端由兩個隊列進行管理,一種是與客戶端完成連接建立后,等待accept的放到一個隊列,這個隊列的長度由somaxconn參數控制;另一種是正在建立但未完成的連接單獨存放一個隊列,這個隊列的長度由tcp_max_syn_backlog控制;默認128,調到至8192.

  • net.ipv4.tcp_max_tw_buckets

默認值為4096,參考值為100000。定義系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數,則TIME_WAIT套接字將立刻被清除并打印警告信息。如果系統被TIME_WAIT過多問題困擾,則可以調節tcp_max_tw_buckets、tcp_tw_reuse、tcp_timestamps三個選項來緩解。TIME_WAIT狀態產生在TCP會話關閉時主動關閉的一端,如果想從根本上解決問題,則讓客戶端主動關閉連接,而非服務端。

page cache

page cache即系統臟頁,是系統的io緩存,當數據寫入磁盤前會先寫入page cache中,然后異步刷入磁盤;寫緩存可以提升IO的訪問速度,但同時也會增加丟失數據的風險。

從page cache刷到磁盤有以下三種時機:

  • 可用物理內存低于特定閾值時,為了給系統騰出空閑內存;

  • 臟頁駐留時間超過特定閾值時,為了避免臟頁無限期駐留內存;

  • 被用戶的sync()或fsync()觸發。

由系統執行的刷盤有兩種寫入策略:

  • 異步執行刷盤,不阻塞用戶I/O;

  • 同步執行刷盤,用戶I/O被阻塞,直到臟頁低于某個閾值。

   在一般情況下,系統先執行第一種策略,當臟頁數據量過大,異步執行來不及完成刷盤時,切換到同步方式。

我們可以通過內核參數調整臟數據的刷盤閾值:

  • vm.dirty_background_ratio,默認值為10。該參數定義了一個百分比。當內存中的臟數據超過這個百分比后,系統使用異步方式刷盤。

  • vm.dirty_ratio,默認值為30。同樣定義了一個百分比,當內存中的臟數據超過這個百分比后,系統使用同步方式刷盤,寫請求被阻塞,直到臟數據低于dirty_ratio。如果還高于dirty_background_ratio,則切換到異步方式刷盤。因此 dirty_ratio 應高于dirty_background_ratio。

   除了通過百分比控制,還可以指定過期時間:vm.dirty_expire_centisecs,默認值為3000(30秒),單位為百分之1秒,超過這個時間后,臟數據被異步刷盤。

可以通過下面的命令查看系統當前的臟頁數量:

 
1
2
3
4
5
cat /proc/vmstat |egrep "dirty|writeback"
nr_dirty 951
nr_writeback 0
nr_writeback_temp 0
#輸出顯示有951個臟頁等待寫到磁盤。默認情況下每頁大小為4KB。另外,也可以在/proc/meminfo文件中看到這些信息。

如果數據安全性要求沒有那么高,想要多“cache”一些數據,讓讀取更容易命中cache,則可以增加臟數據占比和過期時間:

 
1
2
3
vm.dirty_background_ratio = 30
vm.dirty_ratio = 60
vm.dirty_expire_centisecs = 6000

同理,如果不希望因為刷盤導致io被阻,可適當減少異步刷盤的數值,這樣可以讓io更加平滑:

 
1
2
vm.dirty_background_ratio = 5
vm.dirty_ratio = 60

 

   操作系統完成一個任務時,與系統自身設置、網絡拓撲結構、路由設備、路由策略、接入設備、物理線路的多個方面都密切相關,任何一個環節出現問題,都會影響整個系統的性能。因此當linux應用出現問題是,應當重應用程序、操作系統、服務器硬件、網絡環境等方面綜合排查,定位問題出現在哪個部分,然后集中解決。

 

在應用程序、操作系統、硬件服務、網絡環境等方面,影響性能最大的是應用程序和操作系統兩個方面,應為這兩個方面出現問題不易察覺,隱蔽性很強。而硬件、網絡方面只要出現問題,一般都能馬上定位

照傳統,Linux不同的發