■ 河南 劉建臣
在使用Linux時,必然要和系統內核進行交互,在用戶和內核之間其實是通過“/proc”這個虛擬文件系統進行聯系的。在其中提供了一些虛擬文件,當用戶對其進行讀寫時,就可以與內核進行交互。當然,這些虛擬文件都是動態建立的。因為其活動在內存中,因此如果使用普通的方法對其進行查看,是無法顯示其真實大小的。
例如在“/proc/sys/kernel”目錄中保存和內核相關的參數,例如在CentOS 7.X中執行“echo “1” >/proc/sys/net/ipv4/ip_forward”命令,可以打開代理轉發功能。執行“sysctl kernel.msgmnb”命令,可以顯示單個隊列中允許的最大字節長度。執行“sysctl-w kernel.msgmnb=40960”命令,可以對該參數進行修改。但是,如果重啟系統后,進行的修改就會消失。為此可以執行諸如“vim/etc/sysctl.conf”命令,在該文件中添加“sysctl kernel.msgmnb=40960”行,保存后執行“sysctl -p”命令,可以讓修改操作立即生效。
執行“echo 1 >/proc/sys/kernel/panic”命令,設置當內核出錯時,可以自動重啟。執行“echo 196608>/proc/sys/kernel/pid_max”命令,可以設置進程數量最大值。執行“echo 1>/proc/sys/kernel/ctrlalt-del”命令,可以禁止按下Ctrl+Alt+Delete組合鍵時系統重啟。執行“echo"core.%e.%p " >/proc/sys/kernel/core_pattern”命令,設置Core文件保存位置信息。
在“/proc/sys/fs”目錄中保存和文件系統相關的參數。例如,執行“echo"10485750">/proc/sys/fs/file-max”命令,可以設置分配的文件句柄的最大數目。執行“echo "8192000">/proc/sys/fs/inotify/max_user_watches”命令,可以設置每個Real User ID可創建的inotify instatnces的數量上限。磁盤一般包括機械硬盤和固態硬盤,實際上,不管何種形式的磁盤,其隨機I/O的速度都要比順序I/O慢得多。
對于順序I/O來說,會采取預讀取的方式,來降低I/O請求次數,進而優化性能。在Linux中如果出現大量讀請求,默認的請求隊列因為長度不夠,可能無法應對。為此可以動態調整請求隊列數來解決問題。
為了提高預讀取性能,可以對“/sys/block/sdb/queue/read_ahead_kb”參數進行適當調整,其默認值為128字節。當不同的進程在請求I/O資源時,系統就需要對其進行合理的調度。
對于Deadline調度算法來說,通過降低性能而獲得更短的等待時間,提供了最小的讀取延遲和較好的吞吐量,比較適用于數據庫服務器等讀取量較大的環境。對于固態磁盤,以及RAID磁盤陣列來說,比較適合使用電梯調度算法。
對于CFQ調度算法來說,使用了QoS策略為所有任務分配等量的帶寬,實現了較低的延遲,結合了以上兩個算法的優點,對于多用戶環境比較適用。可以根據實際情況,針對不同的磁盤設置合適的算法。例如執行“echo'cfq'>/sys/block/sdb/queue/scheduler”命令,將指定的磁盤設定為CFQ調度算法。
對于固態硬盤來說,使用Trim技術可以大幅提高數據讀寫性能。例如,執行“lsblk-D/dev/sdb”命令,可以檢測SSD磁盤是否支持Trim功能。如果在返回信息中的“DISC-GRAN”和“DISC-MAX”列中為非零值,說明其支持Trim功能。注意,只有Ext4和XFS格式支持Trim功能。
執行“mount -t ext4-o discard/dev/sdb1/mnt”命令,可以在指定的分區上啟用Trim功能,還可以執行“/usr/sbin/fstrim-a”命令,自動檢測硬盤是否支持TRIM功能,并在已掛載文件系統上執行TRIM功能。
對于CentOS7.X中已經使用了性能更加優異的XFS文件系統,在對磁盤進行格式化時,可以同步進行優化操作。
在“/proc/sys/net”中保存和網絡相關的參數,對于Web服務器來說,合理的配置這些參數,對于有效的提高系統的性能。
例如,執行“echo 2 >/proc/sys/net/ipv4/tcp_syn_retries”命令,可以設置當內核要2個SYN連接請求后才才放棄一個新建連接。執行“echo 300>/proc/sys/net/ipv4/tcp_keepalive_time”命令,可以設置TCP發送keepalive消息的頻度。執行“echo 1 >/proc/sys/net/ipv4/tcp_orphan_retries”命令,可以重試后放棄Socket連接。
執行“echo 1 >/proc/s ys/net/ipv4/ tcp_syncook ies”命令,可以啟用SYN Cookies功能,可以有效防御SYN攻擊。執行“echo 8192>/proc/sys/net/ipv4/tcp_max_syn_backlog”命令,將SYN隊列長度設置為8192,可以接受更多的網絡連接。
執行“echo 2 >//proc/sys/net/ipv4/tcp_synack_retries”命令,將SYN+ACK報文重試次數設置為2。
執行“echo 1 >/proc/sys/net/ipv4/ tcp_tw_recycle”命令,啟用TCP連接中TIME-WAIT Sockets快速回收功能。
執行“netstat -n | aw k '/^tcp/ {++state[$NF]};END {for(key in state) p rint key," ",state[key]}'”,“netstat -n | awk'/^tcp/ {++arr[$NF]};END{for(k in arr) print k," ",arr[k]}'”等命令,可以查看系統的TIME-WAIT狀態信息。
執行“echo 1 >/proc/sys/net/ipv4/tcp_tw_reuse”命令,可以允許將TIME-WAIT sockets重新用于新的TCP連接。當然,這必須同時開啟TIME-WAIT Sockets快速回收功能。
執行“cho 15 >/proc/sys/net/ipv4/tcp_fin_timeout”命令,設置處于TIME_WAIT狀態的連接在回收前必須等待的最小時間。執行“echo 5>/proc/sys/net/ipv4/ tcp_keepalive_probes”命令,設置超時前的等待次數。
執行“echo 3000>/pro c/sys/net/ipv4/ netdev_max_backlog”命令,設置每個網絡接口接收數據包的速率大于內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。執行“echo 16777216>/proc/sys/net/core/rmem_max”,“echo 16777216>/proc/sys/net/core/wmem_max”命令,設置接收/發送套接字緩沖區大小的最大值,單位為字節。
執行“echo "4096 87380 16777216">/proc/sys/net/ipv4/tcp_rmem”,“echo"4096 65536 16777216">/proc/sys/net/ipv4/tcp_rmem”命令,分別設置內核自動對Socket緩沖區進行讀取/寫入的最小值,默認值和最大值。執行“echo 4096 >/proc/sys/net/core/somaxconn”命令,可以設置Socket監聽的隊列上限。
對內存設置進行優化,必須搞清楚Buffer(緩沖)和Cache(緩存)的關系。Cached工作在CPU與內存之間的層面,經常被應用到磁盤I/O請求上。Buffer工作在內存與磁盤之間的層面。Cache將CPU讀取過的數據保存起來,便于CPU下次需要時快速讀取,而不必重復從磁盤中讀取這些數據。如果Cache中沒有搜索到數據,系統才會從磁盤中讀取。而且系統會根據CPU讀取的頻率,將最頻繁的數據存放到Cache中最容易找到的位置。
對于Buffer來說,存儲的是需要寫入磁盤的數據。Buffe是針對不同的進程進行分配的。在Linux中Cache的讀寫是分別進行的。
一方面磁盤數據會被讀取到Page Cache進行緩存,程序要會從中直接讀取數據讀取數據。
另一方面當刷新Page Cache的數據時,Page Cache會將其提交給Buffer Cache,由其將所有數據定期寫入到磁盤中。對于Page Cache來說,是文件系統層級的緩存。對于Buffer Cache來說,是用于磁盤等塊設備的緩沖。
例如,執行Sync命令,可以手工將Buffer Cache的數據寫入磁盤。當讀取文件時,系統會首先在Page Cache中查找,當執行時系統只是將數據暫寫入Page Cache中,并將該頁置上dirty標志,這些數據會被定期批量保存到文件系統中。
在“/proc/sys/vm”目錄中保存和內存設置相關的參數,對于Page Cache進行優化,主要包含“vm.dirty_background_ratio”和“vm.dirty_ratio”參數。
例如,執行“echo 5>/proc/sys/vm/dirty_background_ratio”命令,設置當文件系統緩存臟數據數量達到系統內存5%時,就會觸發Pdflush等后臺回寫進程運行。
執行“echo 10 >/proc/sys/vm/dirty_ratio”命令,設置當文件系統緩存臟數據數量達到系統內存10%時,必須開始處理緩存臟頁,其要大于或者等于前者的數值,因為此時臟頁數量已經比較多,為了避免數據丟失需要將一定臟頁寫入磁盤。
如果需要立即回收Cache,可以執行“echo 1 >/proc/sys/vm/drop_caches”命令,釋放Page Cache。
執行“sync”命令,將緩存寫入磁盤。執行“echo 3>/proc/sys/vm/drop_cache s”命令,可以釋放文件節點緩存和目錄項緩存。
執行“echo 3 >/proc/sys/vm/drop_caches”命令,可以釋放以上所有緩存項目。在“/proc/sys/vm/dirty_expire_centisecs”參數中設置臟數據在內存中駐留時間,如果超過超過該值的話,Pdflush進程在下一次將把這些數據寫回磁盤。在“/proc/sys/vm/dirty_writeback_centisecs”參數中設置新進程pdflush的運行間隔,該進程用于刷新內核的臟數據。
在“/proc/sys/vm/vfs_cache_pressure”參數中內核回收用于directory和inode cache內存的傾向。在“/proc/sys/vm/min_free_kbytes”參數中設置強制Linux VM最低保留多少空閑內存。
在“/proc/sys/vm/over commit_memory”參數中設置內存分配策略,如果為0表示當應用程序申請內存時,如果有足夠的可用內存則申請允許,否則內存申請失敗,并把錯誤返回給應用進程。如果為1表示內核允許分配所有的物理內存,如果為2表示內核允許分配超過所有物理內存和交換空間總和的內存。
在“/proc/sys/vm/panic_on_oom”參數的值如果為0,表示當內存耗盡時內核會觸發OOM killer清除最耗內存的進程。
如果設置為1表示在OOM時系統會Panic。使用交換分區,可以緩解內存不足的問題。