Linux性能調(diào)優(yōu)指南

在很久以前,就對(duì)性能調(diào)優(yōu)有非常濃厚的興趣。雖然之前也在做過一些性能調(diào)優(yōu)的工作,但是主要集中在代碼層面,以及業(yè)務(wù)層面。對(duì)如何從Linux操作系統(tǒng)方面進(jìn)行調(diào)優(yōu),一直都沒有一個(gè)清晰的認(rèn)識(shí)。不過,最近偶然發(fā)現(xiàn)了一本IBM出的Linux調(diào)優(yōu)指南,于是就拜讀了一下。

讀完一些之后,就發(fā)現(xiàn)這本書確實(shí)就是我所需要的一本書。

雖然之前讀過一些關(guān)于操作系統(tǒng)的書籍,但是并不懂如何把它們應(yīng)用到性能調(diào)優(yōu)中。而從網(wǎng)上看到的一些關(guān)于性能調(diào)優(yōu)的文章,也主要是集中在檢測(cè)并發(fā)現(xiàn)性能瓶頸這些我們?cè)缇颓宄膬?nèi)容。對(duì)于發(fā)現(xiàn)瓶頸之后,如何調(diào)優(yōu),從哪些方面進(jìn)行調(diào)優(yōu),這背后的原理是什么,為什么要這么調(diào)優(yōu),卻沒有詳細(xì)的說明。

而這本書恰恰彌補(bǔ)了這個(gè)空缺。彌補(bǔ)了操作系統(tǒng)高層理論以及底層調(diào)優(yōu)之間的空缺。我們熟悉的操作系統(tǒng),以及計(jì)算機(jī)網(wǎng)絡(luò),他們的處理過程,都是一些可以優(yōu)化的點(diǎn)。

這本書,其實(shí)稱為指南更合適。從CPU,內(nèi)存,IO,計(jì)算機(jī)網(wǎng)絡(luò)等方面,一一為我們展示了優(yōu)化的過程。

這本指南也不厚,大概只有160頁。內(nèi)容不多,非常精簡(jiǎn)。同時(shí)也造成了一個(gè)缺點(diǎn),就是,很多內(nèi)容并不能全面鋪開。

但是感覺用這本指南來進(jìn)入性能調(diào)優(yōu)的世界,還是綽綽有余的。

這本指南的名稱是,《Linux Performance and Tuning Guidelines》

這篇文章,便是我在讀完這本指南的時(shí)候,摘錄的一些筆記。

CPU方面

處理器指標(biāo)

  • CPU使用率: 每個(gè)處理器的利用率
  • user time: CPU執(zhí)行用戶代碼的時(shí)間,包括nice time
  • system time: CPU執(zhí)行內(nèi)核代碼的時(shí)間,包括IRQ和softirq time
  • waiting: CPU等待IO的時(shí)間
  • Idle time: CPU空閑并等待任務(wù)的時(shí)間
  • nice time: CPU花在改變進(jìn)程優(yōu)先級(jí)以及執(zhí)行順序的時(shí)間
  • load average: 任務(wù)隊(duì)列中,等待被CPU執(zhí)行的任務(wù)的總數(shù),以及那些等待不可中斷任務(wù)完成的任務(wù)的總數(shù),它們的平均值。也就是,系統(tǒng)中處于TASK_RUNNABLE以及TASK_UNINTERRUPTIBLE狀態(tài)的任務(wù)的總數(shù)的平均值。
  • Runnable process: 等待被CPU執(zhí)行的任務(wù)的總數(shù)
  • Blocked: 那些因?yàn)镮O操作被掛起的進(jìn)程的數(shù)量
  • Context switch: 系統(tǒng)中線程切換的總數(shù)。
  • Interrupt: 硬中斷和軟中斷的次數(shù)。

消除CPU瓶頸的方法

  • 確保后臺(tái)沒有不必要的程序
  • 給那些不重要并且是CPU密集型的應(yīng)用調(diào)整優(yōu)先級(jí),讓其優(yōu)先級(jí)相對(duì)較低一些
  • 更新CPU

內(nèi)存方面

內(nèi)存指標(biāo)

  • Free memory: 空閑內(nèi)存。在Linux中,內(nèi)核會(huì)將沒有使用的內(nèi)存中的大部分分配給文件系統(tǒng)緩存。所以,F(xiàn)ree memory減去buffers以及cache占用的內(nèi)存的數(shù)量,才是系統(tǒng)中真正的空閑內(nèi)存的數(shù)量。
  • swap usage: swap in/out衡量?jī)?nèi)存是否出現(xiàn)了瓶頸才更加正確。因?yàn)長(zhǎng)inux內(nèi)核如果發(fā)現(xiàn)內(nèi)存中的一些page,長(zhǎng)時(shí)間沒有被用到,就回將它放到swap中。而并不是說,只有當(dāng)內(nèi)存不足的時(shí)候,才會(huì)將page放到swap中。如果每秒有200-300次 swap in/out,那么說明系統(tǒng)的內(nèi)存可能是瓶頸。
  • Buffer and cache: 為文件系統(tǒng)和block size分配的緩存
  • slab: 內(nèi)核使用的內(nèi)存數(shù)量。需要注意的是,內(nèi)核使用的page不能被page out到磁盤中
  • active versus inactive memory: inactive memory將會(huì)被kswapd daemon swap out到磁盤中。

free工具輸出解釋

0.png

消除內(nèi)存瓶頸的方法

  • 調(diào)整page的大小
  • 調(diào)整處理active和inactive內(nèi)存的方式
  • 降低page-out的速度
  • 限制服務(wù)器上每個(gè)用戶能夠使用的內(nèi)存的數(shù)量
  • 停止不需要的service
  • 增加內(nèi)存

文件系統(tǒng)方面

文件系統(tǒng)指標(biāo)

  • IOWait: CPU等待IO操作的時(shí)間
  • Average queue length: 未完成的IO請(qǐng)求的數(shù)量
  • Average wait: IO請(qǐng)求等待被處理的時(shí)間,毫秒級(jí)
  • Transfers per second: 每秒有多少IO操作被執(zhí)行
  • Blocks read/write per seconds: 每秒中讀和寫block的數(shù)量。在2.6版本的內(nèi)核中,以block大小為1KB衡量。不同的內(nèi)核版本中,block大小不同,從512bytes到4KB不等
  • Kilobytes per second read/write: 每秒讀寫block device的數(shù)據(jù)量,用kilobytes來衡量

Linux中常見的文件系統(tǒng)

  • Ext2
  • Ext3
  • ReiserFS
  • Journal File System(JFS)
  • XFS

其中,Ext3能夠保證數(shù)據(jù)的一致性。而且,還能夠通過配置journal mode,在數(shù)據(jù)的完整性和速度之間取得一個(gè)較好的平衡。

而JFS和XFS,主要用在需要支持大文件的場(chǎng)景中。

消除文件系統(tǒng)瓶頸的方法

  • 如果程序訪問磁盤的方式是順序訪問,那么就換一個(gè)更好的磁盤控制器。如果是隨機(jī)訪問的,那么就增加更多的磁盤控制器
  • 使用RAID。RAID的讀性能比較高,但是寫性能低一些。而且,優(yōu)先使用基于硬件實(shí)現(xiàn)的RAID。
  • 給磁盤合理分區(qū)
  • 增加內(nèi)存
  • 通過/proc/sys/vm/dirty_background_ratio來調(diào)整內(nèi)存中有多少臟數(shù)據(jù)時(shí),pdflush daemon才將這些數(shù)據(jù)寫入到磁盤
  • 通過ionice來分配IO操作的優(yōu)先級(jí):
    • idle: 最低的優(yōu)先級(jí),只有當(dāng)沒有高優(yōu)先級(jí)的進(jìn)程訪問磁盤時(shí),才有資格訪問磁盤
    • Best-effort: 默認(rèn)優(yōu)先級(jí)。從CPU優(yōu)先級(jí)中繼承
    • Real time: 最高的優(yōu)先級(jí)。進(jìn)程總是能夠訪問磁盤。
  • 禁止access time updates
  • 選擇合適的文件系統(tǒng),以及合適的journal模式
  • 調(diào)整block size:
    如果你的服務(wù)器,更多的是處理小的文件,那么將block size調(diào)小一點(diǎn),可能會(huì)提高性能。但是如果處理大文件更多,那么調(diào)大一點(diǎn)可能會(huì)提高性能。但是這一項(xiàng)對(duì)性能提升并不大,所以,默認(rèn)使用操作系統(tǒng)的4k的block size就好。

網(wǎng)絡(luò)方面

網(wǎng)絡(luò)指標(biāo)

  • Packets received and sent
  • Bytes received and sent
  • Collisions per second: 網(wǎng)絡(luò)中發(fā)生的碰撞數(shù)量。一個(gè)配置正確的網(wǎng)絡(luò)中,應(yīng)當(dāng)很少發(fā)生碰撞
  • Packet dropped: 被丟棄的包的數(shù)量。包括被防火墻過濾掉的,以及由于buffer空間不夠而丟掉的
  • Overruns: buffer空間溢出的次數(shù)
  • Errors: 出錯(cuò)的包的數(shù)量

數(shù)據(jù)傳輸?shù)倪^程

  • 應(yīng)用程序開啟一個(gè)Socket并將數(shù)據(jù)寫入到這個(gè)Socket的buffer中
  • 數(shù)據(jù)經(jīng)過TCP/IP協(xié)議棧一層層地做一些處理,包裝。數(shù)據(jù)并不會(huì)層層復(fù)制,因?yàn)檫@樣性能不好。在內(nèi)核中,只是修改buffer中的引用,將其傳遞給下一層
  • 數(shù)據(jù)通過網(wǎng)絡(luò)到達(dá)另一臺(tái)主機(jī),我們暫且稱它為主機(jī)B
  • 如果這個(gè)包的MAC地址就是主機(jī)B,那么把它放到主機(jī)B的socket buffer中
  • 主機(jī)B給CPU發(fā)出一個(gè)硬中斷
  • 主機(jī)B再將數(shù)據(jù)通過TCP/IP協(xié)議棧的層層處理,傳遞給應(yīng)用層

Linux中的協(xié)議棧,更注重的是可靠性和低延遲,而不是低開銷和高吞吐量。

由于每一個(gè)數(shù)據(jù)包都會(huì)引發(fā)一次中斷,所以,Linux中引入了一項(xiàng)叫做NAPI的技術(shù)。當(dāng)?shù)谝粋€(gè)數(shù)據(jù)包到來時(shí),還是跟之前一樣,會(huì)引發(fā)一次中斷。但是從此之后,網(wǎng)絡(luò)接口會(huì)啟動(dòng)輪訓(xùn)模式,即,當(dāng)有數(shù)據(jù)包到達(dá)時(shí),不會(huì)發(fā)出中斷,而是直到buffer都滿了的時(shí)候,才發(fā)出一個(gè)中斷。這樣就能減少中斷的次數(shù)。

TCP/IP傳輸窗口

TCP/IP傳輸窗口指的是,在收到ACK響應(yīng)之前,最多能夠發(fā)送的數(shù)據(jù)量。接收主機(jī)會(huì)通過TCP首部中的window size字段告訴發(fā)送主機(jī)傳輸窗口的大小。通過使用傳輸窗口,TCP能夠處理地效率更高一些,因?yàn)榘l(fā)送主機(jī)不需要等待每一個(gè)數(shù)據(jù)包的ACK。

高速網(wǎng)絡(luò)中,可以使用一種叫做窗口伸縮的技術(shù),來增加傳輸窗口的大小。

Offload

如果你的網(wǎng)絡(luò)適配器支持offload功能,那么你可以內(nèi)核就可以將一部分工作轉(zhuǎn)移到網(wǎng)絡(luò)適配器,來減少CPU的工作量,進(jìn)而提高性能。

常見的offload功能有:

  • Checksum Offload: 每一個(gè)數(shù)據(jù)包中,都會(huì)有一個(gè)校驗(yàn)碼,用于驗(yàn)證這個(gè)數(shù)據(jù)包是否在傳輸過程中出現(xiàn)了問題
  • TCP segmentation offload: 當(dāng)要傳輸?shù)臄?shù)據(jù)量大于MTU的時(shí)候,就要對(duì)數(shù)據(jù)進(jìn)行分段處理。

消除網(wǎng)絡(luò)瓶頸的方法

  • 確保網(wǎng)卡的配置和路由器以及交換機(jī)的配置配套
  • 調(diào)整網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)
  • 使用更快的網(wǎng)卡
  • 在內(nèi)核中調(diào)整關(guān)于網(wǎng)絡(luò)的參數(shù)
    • MTU
    • 接收和發(fā)送緩沖區(qū)的大小
    • 傳輸窗口
    • 通過調(diào)整net.ipv4.tcp_tw_reuse參數(shù)讓處于TIME_WAIT狀態(tài)的Socket對(duì)新連接可重用
    • 通過調(diào)整tcp_fin_timeout參數(shù),讓處于FIN-WAIT-2狀態(tài)的Socket可以早一些關(guān)閉,進(jìn)而節(jié)省內(nèi)存
    • 通過調(diào)整tcp_keepalive_time參數(shù),調(diào)整keepalive連接的關(guān)閉時(shí)間
    • 通過調(diào)整tcp_max_syn_backlog參數(shù)來調(diào)整最大能夠容納的處于半連接狀態(tài)的socket的數(shù)量
  • 關(guān)閉一些不需要的服務(wù),以及端口號(hào)

Linux的工具

性能監(jiān)控工具

  • top
  • vmstat
  • uptime, w
  • ps, pstree
  • free
  • iostat
  • sar
  • mpstat
  • numastat
  • pmap
  • netstat
  • iptraf
  • tcpdump, etheral
  • nmon
  • strace
  • proc file system
  • KDE System guard
  • Gnome System Monitor

分析工具

  • lmbench
  • iozone
  • netperf

/proc

/proc目錄中的內(nèi)容,對(duì)于查看系統(tǒng)狀態(tài),應(yīng)用程序的狀態(tài)至關(guān)重要。

/proc目錄中,又有這么幾塊:

  • 名稱為數(shù)字的目錄:每一個(gè)這樣的目錄,里面都包含了pid為這個(gè)數(shù)字的對(duì)應(yīng)的進(jìn)程的信息,比如,進(jìn)程使用的虛擬內(nèi)存
  • acpi: ACPI中包含一些高級(jí)配置,以及電源管理等信息。因?yàn)锳CPI主要是用在筆記本,或者個(gè)人PC中,所以,在服務(wù)器上,一般是禁用的
  • bus: 包含了一些和bus相關(guān)的信息,比如PCI bus或者USB接口
  • irq: 包含和中斷相關(guān)的信息。每個(gè)子目錄都對(duì)應(yīng)一種中斷。我們可以通過直接修改對(duì)應(yīng)子目錄的信息,來將中斷綁定到一個(gè)CPU上
  • net: 包含和網(wǎng)絡(luò)相關(guān)的統(tǒng)計(jì)信息
  • scsi: 包含和SCSI相關(guān)的信息
  • sys: 包含和內(nèi)核相關(guān)的參數(shù)
  • tty: 包含和tty相關(guān)的信息

從安裝Linux就開始調(diào)優(yōu)

考慮下面幾個(gè)問題:

  • 安裝什么版本的Linux?
    • 商業(yè)版的還是開源版本的?
    • 選擇商業(yè)版的哪一個(gè)版本?
  • 選擇正確的內(nèi)核
    有這么幾種內(nèi)核。
    • standard: 應(yīng)用在單處理器上
    • SMP: 支持SMP以及超線程技術(shù)。一些實(shí)現(xiàn)也支持NUMA.
    • Xen: 包括一個(gè)可以在Xen虛擬機(jī)上運(yùn)行的Linux版本
  • 如何給磁盤分區(qū)?
    盡可能使用交換分區(qū)而不是交換文件。交換分區(qū)相對(duì)于交換文件來講,沒有文件系統(tǒng)上的開銷。
  • 使用什么文件系統(tǒng)?
  • 安裝時(shí),盡可能少安裝包還是安裝全部的包?
  • 防火墻配置
  • SELinux
  • Runlevel選擇
    除非有特別需求,否則服務(wù)器上都是使用runlevel 3.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容