Red Hat Training
A Red Hat training course is available for Red Hat Enterprise Linux
效能微調指南
優化 Red Hat Enterprise Linux 6 的子系統處理能力
版 4.0
Red Hat 主題專員
編輯者
Don Domingo
編輯者
Laura Bailey
摘要
章 1. 總覽
- 功能
- 各個子系統的章節皆詳述了 RHEL 6 專屬(或以不同方式實作於 RHEL 6 中)的效能功能。這些章節亦討論關於 RHEL 6 的更新,這些更新已大幅改善了 RHEL 5 的特定子系統。
- 分析
- 本書亦列舉了各個子系統的效能指標。這些指標的典型數值將以特定服務的角度來詳述,以協助您理解這些數值在真實世界的生產系統上,會帶來什麼樣的影響。此外,《效能微調指南》亦顯示了擷取子系統效能資料的各種方式(也就是分析)。請注意,在此提到的分析工具另外詳述於其它文件中。
- 配置
- 本書中最重要的資訊也許是如何調整 RHEL 6 特定子系統的相關指示。《效能微調指南》解釋了如何為特定服務優化 RHEL 6 的子系統。
1.1. 讀者
- 系統分析師 / 企業分析師
- 本書以高階的方式列舉和解釋了與 RHEL 6 效能有關之功能,並提供了足夠的資訊,以詳述子系統在(就預設值和經過優化後)進行特定工作時的效能。用來詳述 RHEL 6 效能功能的詳細程度,足以協助潛在客戶與銷售工程人員理解此平台是否適用於提供高資源需求的服務。《效能微調指南》亦儘可能擴充性各項功能提供了更詳細的文件連結。如此程度的詳細資訊,足以讓讀者理解這些效能功能,以構成高階的策略方案,建置和優化 RHEL 6。這能讓讀者「同時」開發、並評估基礎結構的計劃。此文件的精細程度專注於「功能」上,適合擁有高度 Linux 子系統和企業級網路知識的讀者。
- 系統管理員
- 列舉在本書中的相關程序適合持有 RHCE [1] 證照的系統管理員(或具備相等經驗及技術,也就是擁有 3-5 年建置和管理 Linux 的經驗者)閱讀。《效能微調指南》儘可能的提供了有關於各項配置所帶來的影響之詳細資訊;即代表我們也詳述了所有可能會遇上的效能利弊情況。效能微調所需的技術本質,不在於知道如何分析和微調子系統,而在於負責進行效能微調的系統管理員,必須知道如何「根據特定用途」,平衡並優化一部 RHEL 6 系統。這代表管理員「也必須」知道在嘗試一項配置,以提升某個子系統的效能時,所造成的效能利弊是否能被接受。
1.2. 水平擴充能力
1.2.1. 平行運算
1.3. 分散式系統
- 通訊
- 水平擴充能力需要同步處理許多任務。因此,這些任務必須有「程序間的通訊能力」(interprocess communication)來協同運作。更進一步來說,擁有水平擴充能力的平台應該能與其它系統共享任務。
- 儲存裝置
- 單靠本機儲存裝置並不足以解決水平擴充能力的需要。這需要一些分散式或共享式的儲存裝置,有著一層萃取層讓單一儲存卷冊的容量,可以透過任意增加儲存裝置而加大空間。
- 管理
- 分散式運算的最重要任務是「管理」。管理層會協調所有軟硬體元件,有效地管理通訊、儲存以及共享資源。
1.3.1. 通訊
- 硬體
- 軟體
電腦間最常見的通訊方式是透過乙太網路。時至今日,系統的預設網路為「GbE」(十億位元乙太網路,Gigabit Ethernet),且大部分伺服器都有二到四個 GbE 連接埠。GbE 的頻寬大、延遲低,是現代大部分分散式系統的基礎。就算系統擁有更快的網路硬體,使用 GbE 作為管理介面依舊是非常常見的作法。
高階伺服器、甚至是中階伺服器,正在快速採用「10GbE」(百億位元乙太網路)技術。10GbE 的速度是 GbE 的十倍。它最大的好處是用於現代的多核心處理器時,可讓通訊與運算達到完美的平衡。您可以比較使用 GbE 的單核心系統、以及使用八核心的 10GbE 系統。後者在維護系統整體效能與避免通訊瓶頸上,特別能彰顯其價值。
Infiniband 的速度甚至比 10GbE 更快。除了 TCP/IP 與 UDP 網路透過乙太網路連接以外,Infiniband 也支援共享記憶體的通訊。這能讓 Infiniband 透過「RDMA」(遠端直接記憶體存取,remote direct memory access)與系統一起運作。
「RoCCE」(使用乙太網路的 RDMA,RDMA over Ethernet)將 Infiniband 類型的通訊(包括 RDMA)在 10GbE 架構上實作出來。隨著 10GbE 產品愈來愈普遍、價格愈來愈低,可以預期許多系統與應用程式都會更廣泛地運用 RDMA 與 RoCCE。
1.3.2. 儲存環境
- 多台系統將資料儲存在單一位置上
- 單一儲存單元(例如卷冊)是由多個儲存裝置所組成
NFS(網路檔案系統,Network File System)能讓多台伺服器或使用者,透過 TCP 或 UDP 掛載、使用同樣的遠端儲存裝置。NFS 廣泛用於儲存多種應用程式共享的資料。對於儲存大量資料來說,NFS 也非常方便。
SAN(儲存區域網路,Storage Area Networks)使用光纖通道、或 iSCSI 通訊協定,提供遠端存取儲存裝置的能力。光纖通道架構(例如光纖主匯流排介面卡、交換器、以及儲存陣列)結合了高效能、高頻寬、以及大量的儲存空間。SAN 能將儲存裝置與處理方式隔開,讓設計系統時更有彈性。
- 控制對儲存裝置的存取
- 管理大量資料
- 佈建系統
- 備份、複製資料
- 建立快照
- 支援系統備援
- 確保資料的整合性
- 遷移資料
Red Hat 的「GFS2」(Global File System 2,全球檔案系統 2)檔案系統提供了多種特殊功能。GFS2 的基本功能是提供單一檔案系統,包括同步讀寫、在叢集間的多個成員間共享等。這表示叢集的每個成員都會看到 GFS2 檔案系統「上面」的同樣資料。
1.3.3. 聚集網路
有了 FCoE,標準的光纖通道指令與資料封包便可以透過單一的「CNA」(聚集網路卡,converged network card),在 10GbE 實體架構上傳輸。標準的 TCP/IP 乙太網路交通與光纖通道儲存的操作,都可以透過同樣連線來傳輸。透過一張實體網路卡(以及一條網路線),FCoE 就可以讓多個邏輯網路與儲存裝置連線。
- 降低連線數量
- FCoE 會降低連線至伺服器的網路數量達百分之五十。使用者還是可以因為效能與可用性考量,選擇多重連線;然而,單一連線即可提供儲存與網路連線,這在機台伺服器與刀鋒伺服器上特別有用,因為這些伺服器的元件空間有限。
- 降低成本
- 降低連線數量也意味著降低網路線、交換器、以及其它網路配備的數量。乙太網路的沿革與規模經濟有關,乙太網路裝置大量導入市場,讓網路成本大幅降低:這在 100 Mb 與 1 Gb 的乙太網路裝置上,都曾發生過。同樣地,10 GbE 也會隨著更多企業導入、採用而變得更便宜。同樣,CNA 硬體已經整合為單一晶片,為大眾所採用也會增加市場上的量,假以時日價格便會大幅降低。
iSCSI 是另一種聚集網路的通訊協定;它是 FCoE 的替代方案。就跟光纖通道一樣,iSCSI 提供了區塊等級的網路儲存裝置。然而,iSCSI 並不提供完整的管理環境。iSCSI 優於 FCoE 的主要好處,是 iSCSI 有著光纖通道的能力與彈性,價格卻較低廉。
章 2. Red Hat Enterprise Linux 6 效能提升
2.1. 支援 64 位元
- 巨型分頁和通透式巨型分頁
- 改善非對稱式記憶體存取
實作於 RHEL 6 中的「巨型分頁」(huge page)能讓系統有效率地管理記憶體負載和使用量。巨型分頁會動態使用 2 MB 的分頁(標準原為 4 KB 的分頁)大小,並讓應用程式能夠有效利用數 GB,甚至是數 TB 的記憶體。
現在許多新的系統皆支援「NUMA」(Non-Uniform Memory Access,非對稱式記憶體存取)。NUMA 可簡化設計、建立較大系統上的硬體之過程;然而,這同時也在應用程式開發上,添加了一層複雜性。比方說,NUMA 會實作本機與遠端的記憶體,而存取遠端記憶體的所需時間,可能會比存取本機記憶體的所需時間長上數倍。這項功能(以及其它功能)將會為效能帶來許多不同影響,它會影響作業系統,以及想要建置的應用程式及系統配置。
2.2. 票證盤旋鎖
2.3. 動態清單結構
2.4. 無計時 kernel
2.5. 控制群組
- 指定給 cgroup 的多項任務
- 分配給這些任務的資源
- CPUset
- 記憶體
- I/O
- 網路(頻寬)
2.6. 改進儲存與檔案系統
ext4 是 RHEL 6 的預設檔案系統。它是 EXT 檔案系統的第四版,理論上支援的最大檔案系統大小為 1 EB,單一檔案的最大大小為 16 TB。RHEL 6 支援的最大檔案系統為 16 TB,單一檔案大小亦為 16 TB。除了儲存空間更大以外,ext4 也有多項新功能,例如:
- 以扇區為基礎的 metadata
- 延遲分配
- 日誌校驗
XFS 是非常穩固、成熟的 64 位元日誌型檔案系統,支援單一主機上非常大型的檔案與檔案系統。這檔案系統最開始由 SGI 公司發展,長時間用在極大型的伺服器與儲存陣列。XFS 的功能包括:
- 延遲分配
- 動態分配 inode
- B-tree 索引,用於未使用空間管理的擴充功能
- 線上磁碟重組與擴充檔案系統
- 複雜的 metadata 事先讀取演算法則
傳統 BIOS 支援的最大磁碟大小為 2.2 TB。RHEL 6 系統可使用新型、支援大於 2.2 TB 磁碟的 BIOS,方法是使用新的磁碟結構,名為「全域分割表」(GPT,Global Partition Table)。GPT 僅能用於資料硬碟;不能搭配 BIOS 用於開機磁碟。因此,開機磁碟的最大大小仍為 2.2 TB。BIOS 最早是為 IBM PC 所建立,並不斷大幅精進以符合現代的硬體,而「統一可延伸韌體介面」(UEFI,Unified Extensible Firmware Interface)則是設計用來支援新興硬體。
重要
重要
章 3. 監控和分析系統效能
3.1. proc 檔案系統
proc
「檔案系統」包含了代表 Linux kernel 現有狀態的檔案階層之目錄。它允許應用程式與使用者從 kernel 的角度,來檢視系統。
proc
目錄也包含了系統的硬體資訊,以及任何執行中程序的資訊。這些檔案大部分都是唯讀的,但有些檔案(尤其是位於 /proc/sys
目錄中的檔案)可以由使用者與應用程式來調整,以改變 kernel 中的配置。
proc
目錄中的檔案之資訊,請參閱《建置指南》,網址為:https://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/?locale=zh-TW。
3.2. GNOME 與 KDE 系統監控程式
「GNOME 系統監控程式」會顯示系統的基本資訊,並讓使用者監控系統程序、資源、或檔案系統的使用量。請在「終端機」中執行 gnome-system-monitor
指令,或點選「應用程式」選單,然後選擇「系統工具 > 系統監控」。
- 系統
- 顯示電腦軟硬體的基本資訊。
- 程序
- 顯示運作中的程序,以及這些程序間的關係,還有每個程序的詳細資訊。它也讓您篩選欲顯示的程序,並對這些程序進行一些動作(啟動、停止、終結、改變優先順序等)。
- 資源
- 顯示目前的 CPU 使用時間、記憶體與置換空間的使用量、以及網路使用量。
- 檔案系統
- 列出所有已掛載的檔案系統,及每個檔案系統的基本資訊,例如檔案系統類型、掛載點、及記憶體使用量。
KDE 的「系統監視器」能讓使用者監控系統現有負載與執行中的程序,也能讓使用者對程序進行操作。請在「終端機」中執行 ksysguard
,或點選「Kickoff 應用程式啟動器」並選取「應用程式 > 系統 > 系統監視器」。
- 行程表
- 顯示執行中程序的清單,預設上按照字母排序。您可以用其它方式排序,包括 CPU 的總使用量、實體或共享記憶體的使用量、擁有者、優先順序等等。您也可以篩選結果、搜尋特定程序、或對程序進行一些動作。
- 系統負載
- 顯示 CPU 使用量、記憶體與置換空間的使用量、以及網路使用量的歷史圖表。將滑鼠移到圖表上,就可以看到詳細的分析與圖例。
3.3. 內建的命令列監控工具
top
top 能以動態、即時的方式,檢視系統上執行中的程序。您會看到多種資訊,包括目前 Linux kernel 所管理的任務。它也有一些管理程序的能力。不管是 top 的運作或顯示的資訊,都是可以加以配置的,任何配置的內容在開機後都會持續存在。
man top
。
ps
ps 工具能取得當下運作中程序的狀態。預設上,這些程序僅限於執行此指令的使用者所執行、且與同樣終端機相關的程序。
man ps
。
vmstat
vmstat(虛擬記憶體的統計數據)會列出系統程序、記憶體、分頁、區塊裝置 I/O、插斷、與 CPU 活動的瞬間資料。
man vmstat
。
sar
sar(系統活動回報程式)會蒐集、回報本日截至目前為止的系統活動資訊。預設的資訊包括本日的 CPU 使用率,每十分鐘採樣一次。
12:00:01 AM CPU %user %nice %system %iowait %steal %idle 12:10:01 AM all 0.10 0.00 0.15 2.96 0.00 96.79 12:20:01 AM all 0.09 0.00 0.13 3.16 0.00 96.61 12:30:01 AM all 0.09 0.00 0.14 2.11 0.00 97.66 ...
man sar
。
3.4. tuned 與 ktune
default
- 預設的省電設定檔。這是最基本的省電設定檔。它僅啟用磁碟與 CPU 的嵌入程式。請注意,這與關閉 tuned-adm 不同,因為此時 tuned 與 ktune 都是停用的。
latency-performance
- 伺服器設定檔,提供典型的延遲效能微調。它會停用 tuned 與 ktune 省電機制。
cpuspeed
模式會變為performance
。每個裝置的 I/O elevator 會變為deadline
。為求電源管理的服務品質,cpu_dma_latency
所需要的值會被註冊為0
。 throughput-performance
- 伺服器的設定檔,用於典型的效能吞吐微調環境。如果系統沒有企業級的儲存裝置,建議使用此設定檔。它與
latency-performance
非常類似,僅有以下不同:kernel.sched_min_granularity_ns
(排程器的最小多工之精細程度)設為10
ms;kernel.sched_wakeup_granularity_ns
(排程器的喚醒功能之精細程度)設為15
ms;vm.dirty_ratio
(虛擬機器「需要變更」(dirty) 的比例)設為 40%;同時- 啟用通透式巨型分頁。
enterprise-storage
- 建議將此設定檔用於搭配了企業級儲存裝置(包括含備用電池的控制器快取保護,以及磁碟上的快取管理)的企業級伺服器配備。它與
throughput-performance
設定檔相似,外加一項設定:檔案系統會以barrier=0
重新掛載。 virtual-guest
- 建議將此設定檔用於搭配了企業級儲存裝置(包括含備用電池的控制器快取保護,以及磁碟上的快取管理)的企業級伺服器配備。它與
throughput-performance
設定檔相似,除了:readahead
的值設為4x
,同時- 非 root/boot 的檔案系統會以
barrier=0
重新掛載。
virtual-host
- 根據
enterprise-storage
設定檔,virtual-host
也會降低虛擬記憶體的 swap 動作,並更積極啟用需要變更分頁的回寫(writeback)功能。這設定檔可在 RHEL 6.3 以後找到,建議用在虛擬主機上,包括 KVM 與 RHEV 的主機。
3.5. 應用程式設定檔工具
3.5.1. SystemTap
3.5.2. OProfile
- 效能監控的樣本可能不夠精準:因為處理器可能不會照順序執行指令,樣本可能是從鄰近指令的紀錄而來,而非來自觸發插斷的指令。
- 因為 OProfile 是系統全域的程式,並將程序重複執行多次,因此可以累積多次執行樣本。這表示您可能需要清除之前執行的樣本資料。
- OProfile 專注於辨明受限於 CPU 的程序之問題,因此並不會辨明休眠中、等待被其它事件鎖定之程序。
/usr/share/doc/oprofile-<version>
。
3.5.3. Valgrind
man valgrind
指令以讀取 man page。相關的文件可以從以下地方找到:
/usr/share/doc/valgrind-<version>/valgrind_manual.pdf
/usr/share/doc/valgrind-<version>/html/index.html
3.5.4. Perf
perf stat
- 這指令提供了一般效能事件的全面統計資料,包括所執行的指令與消耗的時脈週期。您可以透過選用的旗標來蒐集事件資訊,而不是預設的評量事件。自 RHEL 6.4 起,使用者可以執行
perf stat
,根據一或多個控制群組(cgroup)來篩選監控資料。欲知更多詳情,請參閱 man page,指令為:man perf-stat
。 perf record
- 這指令會將效能資料記錄至檔案中,以方便日後使用
perf report
進行分析。欲知更多詳情,請參閱 man page,指令為:man perf-record
。 perf report
- 這指令會從檔案中讀取效能資料,並加以分析。欲知更多詳情,請參閱 man page,指令為:
man perf-report
。 perf list
- 這指令會列出特定機器上的可用事件。這些事件會根據系統的效能監控之軟硬體配置,而有所不同。欲知更多詳情,請參閱 man page,指令為:
man perf-list
。 perf top
- 這指令的效用與 top 類似。它會即時產生、顯示效能記數器的側寫資料。欲知更多詳情,請參閱 man page,指令為:
man perf-top
。
3.6. Red Hat Enterprise MRG
- 與電源管理、錯誤偵測、與系統管理插斷的 BIOS 參數;
- 網路設定,例如插斷聯合(interrupt coalescing)與 TCP 的使用;
- 在日誌型檔案系統中的日誌活動;
- 系統日誌;
- 插斷與使用者程序是否由一個或一群 CPU 所處理;
- 是否使用 swap 空間;以及
- 如何處理記憶體不足的例外情況。
章 4. CPU
拓樸
執行續
插斷
4.1. CPU 拓樸
4.1.1. CPU 與 NUMA 拓樸
- 序列匯流排
- NUMA 拓樸
- 系統的「拓樸」為何?
- 目前應用程式在何處執行?
- 最近的記憶體插槽在哪裡?
4.1.2. 微調 CPU 效能
- 一顆處理器(0-3 的任何一顆)將記憶體位址傳給本地的記憶體控制器。
- 記憶體控制器設定對記憶體位址的存取。
- CPU 對那組記憶體位址進行讀或寫。

圖形 4.1. NUMA 拓樸的本地與遠端記憶體存取
- 一顆處理器(0-3 的任何一顆)將記憶體位址傳給遠端的記憶體控制器。
- 針對遠端記憶體位址的 CPU 需求會傳到遠端的記憶體控制器上,看起來就像從該節點的本機存取節點。
- 遠端記憶體控制器設定對遠端記憶體位址的存取。
- CPU 對那組遠端記憶體位址進行讀或寫。
- 系統拓樸(系統元件是如何相連的)、
- 應用程式執行時所使用的核心、以及
- 最近的記憶體插槽之位置。
4.1.2.1. 使用 taskset 設定 CPU 關聯
0x00000001
表示編號為 0 的處理器,而 0x00000003
表示編號為 0 與 1 的處理器。
# taskset -p mask pid
# taskset mask -- program
-c
選項加上以逗號分隔的個別處理器清單(或處理器範圍),例如:
# taskset -c 0,5,7-9 -- myprogram
man taskset
。
4.1.2.2. 使用 numactl 控制 NUMA 政策
numactl
會使用特定的排程或記憶體取代政策,執行程序。所選擇的政策會套用在該程序與其子程序上。numactl
也可以為共享記憶體區段或檔案,設定一致性的政策;並為程序設定 CPU 關聯與記憶體關聯。它會使用 /sys
檔案系統來決定系統拓樸。
/sys
檔案系統包含了 CPU、記憶體、與周邊裝置是如何透過 NUMA 相互連結的資訊。特別是 /sys/devices/system/cpu
目錄包含了系統 CPU 如何相互連結的資訊。/sys/devices/system/node
目錄包含了系統上的 NUMA 節點的資訊、以及這些節點之間的相對距離。
--show
- 顯示現有程序的 NUMA 政策設定。這參數並不需要其他參數,用法類似:
numactl --show
。 --hardware
- 顯示系統上可用節點的清單。
--membind
- 僅能從特定節點分配記憶體。當使用此選項時,如果這些節點上的記憶體不足,分配運作就會失敗。此參數的用法為
numactl --membind=nodes program
,其中 nodes 是您想要分配記憶體的節點清單,program 是向節點索求記憶體之程式。節點的編號可以是用逗號分隔的清單、一段範圍、或是以上二者的結合。numactl 的更多資訊可以在 man page 中找到:man numactl
。 --cpunodebind
- 只在屬於特定一或多個節點上的 CPU 執行一個指令(與其子程序)。此參數的用法是
numactl --cpunodebind=nodes program
,其中 nodes 是該與特定程式(program)綁定的 CPU 之節點清單。節點的編號可以是用逗號分隔的清單、一段範圍、或是以上二者的結合。numactl 的更多資訊可以在 man page 中找到:man numactl
。 --physcpubind
- 僅在特定處理器上執行指令(及其子程序)。此參數的用法是
numactl --physcpubind=cpu program
,其中 cpu 是以逗號隔開的實體 CPU 編號,如/proc/cpuinfo
檔案中的處理器欄位所列,而 program 是僅在這些 CPU 上執行的程式。CPU 也可以透過相對於現有cpuset
來指定。詳情請參閱 numactl 的 man page,指令為:man numactl
. --localalloc
- 表示記憶體應該總是分配至現有節點上。
--preferred
- 可能的話,記憶體會分配至指定的節點。如果記憶體無法分配至指定的節點上,就會改分配到其它節點。這選項只接受單一節點編號,例如:
numactl --preferred=node
。詳情請參閱 numactl 的 man page,指令為:man numactl
。
man numa(3)
。
4.1.3. numastat
重要
numastat
,沒有任何選項或參數)對於相容性採取嚴格的措施;請注意使用此指令並加上選項或參數後,會顯著改變螢幕輸出的內容及其格式。
numastat
會顯示每個節點上,多少記憶體分頁是由以下事件類別所佔據。
numa_miss
與 numa_foreign
值愈低,表示 CPU 的效能愈好。
預設的追蹤類別
- numa_hit
- 成功分配至此節點的數目。
- numa_miss
- 試圖分配到其它節點,但因為其它節點的記憶體不足而分配至此節點的數目。每個
numa_miss
事件都有相對應至另一個節點的numa_foreign
事件。 - numa_foreign
- 一開始試圖分配至此節點,但最後卻分配至其它節點的數目。每個
numa_foreign
事件都有相對應至另一個節點的numa_miss
事件。 - interleave_hit
- 用交錯政策成功分配至此節點的數目。
- local_node
- 此節點上,一組程序成功分配記憶體至此節點的次數。
- other_node
- 此節點上,其它節點上的一組程序分配記憶體至此節點的次數。
-c
- 水平濃縮資訊表。這在擁有大量 NUMA 節點的系統上非常有用,但欄寬與欄間距難以預測。使用此選項時,記憶體數量會四捨五入至最近的 MB 數。
-m
- 以每個節點為基礎,顯示系統全域的記憶體使用資訊,與
/proc/meminfo
中的資訊類似。 -n
- 顯示與原始
numastat
指令所列出的相同資訊(numa_hit、numa_miss、numa_foreign、interleave_hit、local_node、以及 other_node),加上更新的格式,單位為 MB。 -p pattern
- 根據指定的樣式(pattern),顯示每個節點的記憶體資訊。如果 pattern 的值包括數字,numastat 會假設那是數字型態的程序 ID。反之,numastat 會從程序的命令列搜尋特定的樣式。
-p
選項之後的引數會被視為用來篩選的樣式。額外的樣式會加大篩選條件,而非縮小。 -s
- 根據
total
欄位,降冪顯示資料,讓最消耗記憶體的程序列在上面。或者,您可以指定 node(節點),那麼表格就會根據 node 欄位來排序。使用此選項時, node 的值必須緊跟在-s
選項之後,如以下所示:numastat -s2
不要在此選項及其值之間,加入任何空白字元。 -v
- 顯示更詳盡的資料。亦即:多程序的程序資訊會以詳盡的方式列出。
-V
- 顯示 numastat 的版本資訊。
-z
- 忽略所顯示資訊中,任何欄、列的零。請注意,一些接近零而被四捨五入為零的值還是會被列出。
4.1.4. NUMA 關聯管理 daemon(numad)
/proc
檔案系統存取資訊,以節點為單位監控可用的系統資源。接下來 daemon 會試著將重要程序放到擁有足夠記憶體與 CPU 資源的 NUMA 節點上,好將 NUMA 效能最大化。程序管理的現有門檻為單一 CPU 至少 50%,以及至少 300 MB 的記憶體。numad 會試圖維持資源的利用等級,並在需要於 NUMA 節點間移動程序時讓整個分配重新達到平衡。
-w
選項,以了解預先配置的建議,指令為:man numad
。
4.1.4.1. numad 的好處
4.1.4.2. 操作模式
注意
- 以服務方式執行
- 以可執行檔方式執行
4.1.4.2.1. 使用 numad 作為服務
# service numad start
# chkconfig numad on
4.1.4.2.2. 以執行檔方式執行 numad
# numad
/var/log/numad.log
檔案裡。
# numad -S 0 -p pid
-p pid
- 將特定的 pid 明確加入清單中。此處指定的程序只有在達到 numad 程序的顯著門檻時,才會受到管理。
-S mode
-S
參數會指定程序掃描類型。設定為0
會限制 numad 的管理方式為明確納入程序。
# numad -i 0
man numad
。
4.2. CPU 排程
- 即時政策
- SCHED_FIFO
- SCHED_RR
- 正常政策
- SCHED_OTHER
- SCHED_BATCH
- SCHED_IDLE
4.2.1. 即時排程政策
SCHED_FIFO
- 這政策也稱為「靜態優先順序排程」(static priority scheduling),因為此政策為每個執行續定義了固定的優先順序(介於 1 到 99)。這個排程器會以優先順序掃描 SCHED_FIFO 執行續清單,並排程擁有最高執行順序的執行續以執行之。這個執行續會一直執行,直到被阻絕、退出、或被擁有更高優先順序的執行續所取代為止。即使是最低權限的即時執行續,也比非即時的執行續擁有更高的權限;如果只有一個即時執行續,那麼
SCHED_FIFO
的優先值就無關緊要。 SCHED_RR
- 這是源自
SCHED_FIFO
政策的一種輪詢(round-robin)政策。SCHED_RR
執行續也會被賦予固定的權限值,介於 1 到 99。然而,擁有同樣權限值的執行續會以一固定時間量,又稱「時間配量」(time slice),用輪詢方式執行。sched_rr_get_interval(2)
系統呼叫會傳回這時間值,但這時間長度不能由使用者決定。如果您需要多執行續以同樣的優先順序執行時,此政策就非常有用。
SCHED_FIFO
執行續會一直執行,直到被阻絕、退出、或被擁有更高優先順序的執行續所取代為止。因此我們不建議將優先順序設為 99,因為這會讓該執行續的優先順序與轉移或監控執行續的一樣高。如果您的執行續進入運算上的迴圈,那麼後二者就會被阻絕、無法執行。在這情況下,單一處理器就會漸漸被鎖住。
SCHED_FIFO
政策包括了限定最大頻寬的機制。這會保護即時應用程式師,避免即時應用任務獨占 CPU。這機制可以透過以下 /proc
檔案系統的參數來調整:
/proc/sys/kernel/sched_rt_period_us
- 定義多長時間該被視為 100% 的 CPU 頻寬,單位為 ms(「us」相當於「µs」)。預設值為 1000000µs,也就是 1 秒。
/proc/sys/kernel/sched_rt_runtime_us
- 定義要給執行中的即時執行續之時間,單位為 ms(「us」相當於「µs」)。預設值為 950000µs,也就是 0.95 秒。
4.2.2. 正常的排程政策
SCHED_OTHER
、SCHED_BATCH
、以及 SCHED_IDLE
。然而,SCHED_BATCH
與 SCHED_IDLE
政策都是給非常低優先順序的工作使用,因此本指南不會著墨太多。
SCHED_OTHER
或SCHED_NORMAL
- 預設的排程政策。此政策使用了 CFS(完全公平排程器,Completely Fair Scheduler)好為使用此政策的所有執行續提供完全公平的存取時間。CFS 會建立動態的優先順序清單,部分根據每個執行續的
niceness
值。(此參數的詳細資料請參閱《建置指南》與/proc
檔案系統。)這能給使用者一些非直接的控制等級,以控制程序的優先順序;但動態優先順序清單可以由 CFS 直接改變。
4.2.3. 選擇政策
SCHED_OTHER
,讓系統管理 CPU 的使用率。
SCHED_FIFO
。如果執行續的數目不多,那麼請考慮隔離單一實體 CPU,並將執行續移到該 CPU 的核心上,不讓其它執行續在這些 CPU 核心上競逐時間。
4.3. 微調插斷與 IRQ
/proc/interrupts
檔案會根據每個 CPU 及每個 I/O 裝置,列出插斷的數目。它會顯示 IRQ 編號、每個 CPU 核心處理的插斷數目、以及以逗號隔開的驅動程式清單(這驅動程式清單已註冊以收到該插斷)。(詳情請參閱 pro(5) 的 man page,指令為:man 5 proc
。)
smp_affinity
,這會定義允許為該 IRQ 執行 ISR 的 CPU 核心。這屬性可以透過指定插斷關聯與應用程式的執行續關聯,至一或多個指定的 CPU 核心,進而改善應用程式效能。這允許在特定的插斷與應用程式執行續之間,共享快取線。
/proc/irq/IRQ_NUMBER/smp_affinity
檔案裡,root 使用者可以加以檢視、修改。儲存在這檔案中的值是十進位的位元遮罩,表示系統上的所有 CPU 核心。
# grep eth0 /proc/interrupts 32: 0 140 45 850264 PCI-MSI-edge eth0
smp_affinity
檔案:
# cat /proc/irq/32/smp_affinity f
f
,表示 IRQ 可以接受系統上任何 CPU 的服務。設定這個值為 1
(如下所示)表示只有 CPU 0 可以服務此插斷:
# echo 1 >/proc/irq/32/smp_affinity # cat /proc/irq/32/smp_affinity 1
smp_affinity
的值之間,以分開 32 位元的群組。這在擁有超過 32 核心的系統上是必要的。例如以下範例就顯示,一台 64 核心系統上的所有核心都為 IRQ 40 提供服務:
# cat /proc/irq/40/smp_affinity ffffffff,ffffffff
# echo 0xffffffff,00000000 > /proc/irq/40/smp_affinity # cat /proc/irq/40/smp_affinity ffffffff,00000000
注意
smp_affinity
會設定硬體,讓使用特定 CPU 來服務插斷的決定會在硬體等級上決定,不需要 kernel 干預。
4.4. RHEL 6 中,NUMA 的加強功能
4.4.1. 優化空機系統與可擴充能力
4.4.1.1. 感知拓樸的加強功能
- 增強偵測拓樸的功能
- 這允許作業系統偵測開機時,低階硬體的詳細資料(例如邏輯 CPU、hyperthread、核心、插槽、NUMA 節點、以及節點間的存取時間),以及對系統處理作優化。
- 完全公平排程器
- 這種新的排程模式能確保所有程序皆平等地共享執行時間。將這排程器與偵測拓樸功能相結合,能讓程序納入同樣插槽上的 CPU 之排程中,避免遠端存取記憶體而效能不彰,並儘可能的保留快取內容。
malloc
- 現在
malloc
已經優化,確保分配給一個程序的記憶體區域,會在實體位置上儘可能的接近程序所執行的 CPU 核心。這能加快存取記憶體的速度。 - 分配 skbuff I/O 緩衝區
- 跟
malloc
類似,這功能也已優化,以使用在實體位置上靠近 CPU 處理 I/O 運作(例如插斷)時的記憶體。 - 裝置插斷關聯
- 裝置插斷關聯(device interrupt affinity)是裝置驅動程式記錄的資訊,哪個 CPU 處理哪個插斷的資訊可以用來限制同樣插槽上的 CPU 之插斷處理,保留快取的關聯性,限制插槽間的大量通訊。
4.4.1.2. 多處理器同步的加強功能
- RCU 鎖
- 一般來說,90% 的鎖定都是為了達成唯讀的目的。RCU(Read-Copy-Update,讀取-複製-更新)鎖定機制,能移除存取非修改資料時,取得專一存取鎖定的需求。現在這鎖定模式可用在分配分頁快取記憶體時:現在鎖定模式僅用在分配或取消分配運作上。
- 針對單一 CPU 與單一插槽的演算法則
- 許多演算法則都已經更新,好在同樣插槽上的 CPU 進行鎖定協同作業時,允許更精細的鎖定。多種全域盤旋鎖(spinlock)已經被針對單一插槽的鎖定方式所取代,同時新的記憶體分配程式之區域、以及相關記憶體分頁清單,能讓記憶體分配邏輯在進行分配或取消分配運作時,更有效率地橫跨記憶體對應的資料結構之子集合。
4.4.2. 優化虛擬功能
- 釘選到 CPU
- 釘選到 CPU(CPU pinning)功能能將虛擬客座端固定在特定插槽上執行,以優化使用本地快取,同時移除插槽間通訊與存取遠端記憶體的繁瑣需求。
- 通透式巨型分頁
- 啟用了通透式巨型分頁之後,系統會對大量、連續的記憶體,自動進行感知 NUMA 的記憶體分配需求,降低競逐鎖定與 TLB(翻譯邊旁緩衝區,translation lookaside buffer)記憶體管理的運作次數,讓虛擬客座端的效能增加至多 20%。
- 以 kernel 為基礎的 I/O 實作
- 現在 kernel 中已實作了虛擬客座端的 I/O 子系統,大幅降低節點間通訊、與存取記憶體的時間,因其避免了大量的文本交換、以及同步與通訊的負載。
章 5. 記憶體
5.1. 巨型轉譯後備緩衝區
/usr/share/doc/kernel-doc-version/Documentation/vm/hugetlbpage.txt
。
5.2. 巨型分頁與通透式巨型分頁
- 在硬體的記憶體管理單元裡,增加分頁表的條目
- 增加分頁大小
5.3. 使用 Valgrind 側寫記憶體使用量
valgrind --tool=toolname program
memcheck
、massif
、或 cachegrind
),並以您想以 Valgrind 側寫的檔案名稱取代 program。請注意,使用 Valgrind 時,會讓程式執行速度比平常更慢。
man valgrind
指令來檢視,或在以下位置找到:
/usr/share/doc/valgrind-version/valgrind_manual.pdf
、以及/usr/share/doc/valgrind-version/html/index.html
。
5.3.1. 使用 memcheck 側寫記憶體使用量
valgrind program
指令直接執行,不需要外加 --tool=memcheck
。它會偵測、回報多種難以偵測、診斷的記憶體錯誤,例如不該發生的記憶體存取、使用未定義或未初始化的值、不正確的釋放(free)堆疊記憶體、重疊的指標、以及記憶體洩漏等。使用 memcheck 後,程式的執行時間會比平常慢 10 到 30 倍。
/usr/share/doc/valgrind-version/valgrind_manual.pdf
。
--leak-check
- 啟用這選項時,memcheck 會在用戶端程式完成執行時,搜尋記憶體漏洞。預設值為
summary
(摘要),會列出漏洞的數目。其它選項包括yes
(是)與full
(完整),兩者都會列出每個漏洞的詳細資料;而選項no
(否)會停用檢查記憶體漏洞的功能。 --undef-value-errors
- 啟用時(設定為
yes
),memcheck 會在使用未定義的值時,回報錯誤。停用時(設定為no
),memcheck 不會回報未定義值的錯誤。預設上這功能是啟用的。停用這功能會稍稍加快 memcheck 的執行速度。 --ignore-ranges
- 允許使用者指定一或多組範圍,讓 memcheck 檢查位址的可用性時,予以忽略。多組範圍可用逗號隔開,例如
--ignore-ranges=0xPP-0xQQ,0xRR-0xSS
。
/usr/share/doc/valgrind-version/valgrind_manual.pdf
。
5.3.2. 以 Cachegrind 側寫快取使用量
# valgrind --tool=cachegrind program
- 第一階指令快取的讀取(或已執行的指令)次數與讀取不到之次數,以及最後一階快取讀取不到指令的次數;
- 資料快取的讀取次數(或記憶體的讀取次數)、讀不到的次數、以及讀不到最後一階快取資料的次數;
- 資料快取的寫入次數(或記憶體的寫入次數)、寫不進的次數、以及寫不進最後一階快取資料的次數;
- 已執行與預測失敗的有條件分支之次數;以及
- 已執行與預測失敗的非直接分支之次數。
cachegrind.out.pid
,其中 pid 是您執行 Cachegrind 的程式之程序 ID)。這檔案可以由相隨的 cg_annotate 工具進一步處理,如:
# cg_annotate cachegrind.out.pid
注意
# cg_diff first second
--I1
- 指定第一階指令快取的大小、相關性、以及行的大小,並以逗號隔開:
--I1=size,associativity,line size
。 --D1
- 指定第一階資料快取的大小、相關性、以及行的大小,並以逗號隔開:
--D1=size,associativity,line size
。 --LL
- 指定最後一階指令快取的大小、相關性、以及行的大小,並以逗號隔開:
--LL=size,associativity,line size
。 --cache-sim
- 啟用或停用蒐集存取快取成功的次數、與存取快取失敗的次數之功能。預設值為
yes
(啟用)。請注意,停用上述選項及--branch-sim
會讓 Cachegrind 不蒐集任何資訊。 --branch-sim
- 啟用或停用蒐集分支指令與預測失敗次數之功能。預設上設為
no
(停用),因為這功能會降低 Cachegrind 約 25% 的速度。請注意,停用上述選項及--cache-sim
會讓 Cachegrind 不蒐集任何資訊。
/usr/share/doc/valgrind-version/valgrind_manual.pdf
。
5.3.3. 使用 Massif 側寫堆積與堆疊空間
massif
作為 Valgrind 所要使用的工具:
# valgrind --tool=massif program
massif.out.pid
,其中 pid 是所指定的 program(程式)之程序 ID。
ms_print
指令來製作圖表,如:
# ms_print massif.out.pid
--heap
- 指定是否要對堆積進行側寫。預設值為
yes
(是)。把這選項設定為no
(否)將不會對堆積進行側寫。 --heap-admin
- 指定側寫堆積時,管理所需的區塊位元組數目。預設值為每個區塊
8
個位元。 --stacks
- 指定是否要對堆疊進行側寫。預設值為
no
(停用)。要啟用對堆疊的側寫,請將此選項設為yes
(啟用),但請注意,這會大幅降低 Massif 的速度。也請注意 Massif 會假定主堆疊的起始大小為零,方便控制程式側寫時,堆疊部分的大小。 --time-unit
- 指定側寫時所用的時間單位。此選項可用的三種值為:所執行的指令(
i
),亦為預設值,適用於大部分情況;即時(ms
,單位為 ms),可以用在某些情況下;以及分配 / 取消分配給堆積與 / 或堆疊的位元組(B
),用於執行時間非常短的程式、以及測試環境,因為這選項非常容易在不同機器上執行。此選項在將 Massif 的結果用ms_print
圖形化時,非常有用。
/usr/share/doc/valgrind-version/valgrind_manual.pdf
。
5.4. 微調處理能力
overcommit_memory
為 1
,請執行:
# echo 1 > /proc/sys/vm/overcommit_memory
sysctl
指令。欲知更多詳情,請參閱《建置指南》,網址為 https://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/?locale=zh-TW。
與處理能力相關的記憶體微調參數
/proc/sys/vm/
裡。
overcommit_memory
- 定義接受或拒絕大型記憶體需求的狀況。此參數有三種可用值:
0
— 預設設定。kernel 會進行探索式的記憶體過度寫入處理,方法是預測記憶體的可用量、並讓公然違規的需求失敗。不幸的是,因為記憶體是以探索式、而非精準的演算法則來分配,因此這設定有時會過度使用系統上的可用記憶體。1
— kernel 不進行記憶體過度寫入處理。在此設定下,過度使用記憶體的機會會增加,但對於頻繁存取記憶體的任務來說,效能也會增加。2
— kernel 拒絕相等或大於總可用置換空間與實體記憶體比例(於overcommit_ratio
指定)的記憶體需求。如果您想要降低記憶體過度寫入的風險,這是最佳設定。注意
這設定建議用於置換空間大於實體記憶體的系統上。
overcommit_ratio
- 指定
overcommit_memory
設為2
的時候,實體記憶體的比例。預設值為50
。 max_map_count
- 定義一組程序可使用的記憶體對應區域之最大值。在大部分情況下,預設值
65530
就很適合。如果應用程式需要對應多於此數目的檔案,請增加這個值。 nr_hugepages
- 定義 kernel 中配置的巨型分頁數。預設值為 0。只有在系統上擁有連續且足夠的實體記憶體時,才可以分配(或取消分配)巨型分頁。以此參數保留的分頁不能用做其它用途。欲知更多資訊,請參閱安裝於系統中的文件:
/usr/share/doc/kernel-doc-kernel_version/Documentation/vm/hugetlbpage.txt
。
與處理能力相關的 kernel 微調參數
/proc/sys/kernel/
裡。
msgmax
- 定義訊息佇列中,任何單一訊息的最大允許大小,單位為位元組。這個值不能超過佇列的大小(
msgmnb
)。預設值為65536
。 msgmnb
- 定義單一訊息佇列的最大大小,單位為位元組。預設值為
65536
位元組。 msgmni
- 定義訊息佇列辨識子的最大數量(也因此是佇列的最大數量)。64 位元電腦的預設值為
1985
;32 位元電腦的預設值為1736
。 shmall
- 定義系統上一次可以使用的共享記憶體總數,單位為位元組。64 位元電腦的預設值為
4294967296
;32 位元電腦的預設值為268435456
。 shmmax
- 定義允許用於 kernel 的最大共享記憶體區段,單位為位元組。64 位元電腦的預設值為
68719476736
;32 位元電腦的預設值為4294967295
。然而請注意,kernel 能支援的數量遠超過這個值。 shmmni
- 定義系統全域的共享記憶體區域之最大數量。64 與 32 位元的預設值均為
4096
。 threads-max
- 定義系統全域中,kernel 一次可使用的執行續(任務)總數。預設值與 kernel 的
max_threads
值相同。使用的公式為:max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE )
threads-max
的最小值為20
。
與處理能力相關的檔案系統微調參數
/proc/sys/fs/
裡。
aio-max-nr
- 定義位於所有非同步 I/O 情況的事件之最大允許數。預設值為
65536
。請注意,改變這個值並不會預先分配任何 kernel 資料結構或改變其大小。 file-max
- 列出 kernel 分配的檔案處理之最大數量。預設值與 kernel 中的
files_stat.max_files
值相符,亦即設定為(mempages * (PAGE_SIZE / 1024)) / 10
或NR_FILE
(RHEL 的值為 8192),兩者取其大者。如果可用的檔案處理不夠而發生錯誤,加大這個值可以解決問題。
OOM Killer 的微調參數
/proc/sys/vm/panic_on_oom
參數設為 0
,會告訴 kernel 在 OOM 發生時,呼叫 oom_killer
函式。通常 oom_killer
會終結有問題的程序,系統便可正常運作。
oom_killer
函式刪除的程序,進行更深的控制。它位於 proc 檔案系統的 /proc/pid/
之下,其中 pid 是程序 ID。
oom_adj
- 定義從
-16
到15
之間的值,決定程序的oom_score
。oom_score
愈高,程序就愈有可能被oom_killer
刪除。設定oom_adj
的值為-17
會取消oom_killer
對於該程序之功能。重要
任何調整過的程序之子程序,都會繼承父程序的oom_score
。舉例來說,如果一組sshd
程序不會被oom_killer
函式所終結,那麼所有由該組 SSH session 所啟動的程序也不會被終結。發生 OOM 時,這會影響oom_killer
函式挽救系統的能力。
5.5. 微調虛擬記憶體
swappiness
- 其值為 0 到 100,控制系統 swap(記憶體置換)的程度。值愈高表示效能優先,系統會積極地將非作用中的程序移出實體記憶體。值愈低則儘可能避免 swap,降低回應的延遲時間。預設值為
60
。 min_free_kbytes
- 系統上保留的最低 swap 空間,單位為 KB。用來計算每個低記憶體區域的浮水印值,然後依照大小比例,指定保留記憶體分頁的值。
警告
設定此參數時請小心,過高或過低的值都會造成傷害。將min_free_kbytes
設定得太低,會讓系統無法取回記憶體。這會導致系統無法回應,並透過 OOM-killing 機制,終結多個程序。然而,將這個值設得太高(系統總記憶體的 5-10%)會馬上導致系統記憶體不足。Linux 的設計,是使用所有可用記憶體來快取檔案系統的資料。將min_free_kbytes
值設定得太高,會讓系統花去太多時間取回記憶體。 dirty_ratio
- 百分比數值。當需要變更的資料累積到系統總記憶體的此百分比時,就開始將需要變更資料寫出(透過 pdflush)。預設值為
20
。 dirty_background_ratio
- 百分比數值。當需要變更的資料累積到系統總記憶體的此百分比時,就開始在背景將需要變更資料寫出(透過 pdflush)。預設值為
10
。 drop_caches
- 將這個值設定為
1
、2
、或3
會讓 kernel 放棄多種分頁快取與 slab 快取的組合。- 1
- 系統會無效判定,並釋放所有分頁快取記憶體。
- 2
- 系統會釋放所有沒用到的 slab 快取記憶體。
- 3
- 系統會釋放所有分頁快取與 slab 快取記憶體。
這是非破壞性的操作。因為需要變更的物件不能被釋放,因此建議您在設定此參數之前,先執行sync
。重要
不建議在正式投產的環境中,使用drop_caches
來釋放記憶體。
swappiness
為 50
,請執行:
# echo 50 > /proc/sys/vm/swappiness
sysctl
指令。欲知更多詳情,請參閱《建置指南》,網址為 https://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/?locale=zh-TW。
章 6. 輸入/輸出
6.1. 功能
- 現在 RHEL 6 可以自動偵測固態硬碟(SSD),並且 I/O 排程器的效能也已經過微調,以有效善用這些裝置每秒所能執行的每秒高 I/O(IOPS)。
- 支援捨棄的功能已附加至 kernel 中,以向基礎儲存裝置回報未使用的區塊範圍。這有助於 SSD 的磨損平均(wear-leveling)演算法。它亦可藉由詳細監控實際的儲存空間使用量,來協助支援邏輯區塊佈建(一種儲存裝置的虛擬位址空間)的儲存裝置。
- 檔案系統屏障實作已在 RHEL 6.1 中大幅修改,以提升效能。
pdflush
已被 per-backing-device 排清執行續取代,這大幅改善了擁有大量 LUN 配置的系統之擴充性。
6.2. 分析

圖形 6.1. aio-stress 對於 1 個執行續和 1 個檔案的輸出
- aio-stress
- iozone
- fio
6.3. 工具
si
(swap in)、so
(swap out)、bi
(block in)、bo
(block out),以及 wa
(I/O wait time)。當您的 swap 空間和您的資料分割區位於相同裝置上的時候,si
和 so
有助於您使用它們來作為整體記憶體壓力的指標。si
和 bi
為讀取作業,而 so
和 bo
則為寫入作業,單位皆為 KB。wa
為閒置時間;它會顯示等待 I/O 完成時,有哪些執行佇列被阻擋。
free
、buff
和 cache
欄位也相當重要。cache
的值會隨著 bo
的值增加,並且 cache
減少和 free
增加代表系統正在執行分頁快取的回寫和無效判定。
avgqu-sz
),您可藉由產生的圖表來估算您儲存裝置的效能,請注意,若平均請求大小為 4KB,而平均佇列大小為 1,則傳輸量不太可能具有極佳的效能。
8,64 3 1 0.000000000 4162 Q RM 73992 + 8 [fs_mark] 8,64 3 0 0.000012707 0 m N cfq4162S / alloced 8,64 3 2 0.000013433 4162 G RM 73992 + 8 [fs_mark] 8,64 3 3 0.000015813 4162 P N [fs_mark] 8,64 3 4 0.000017347 4162 I R 73992 + 8 [fs_mark] 8,64 3 0 0.000018632 0 m N cfq4162S / insert_request 8,64 3 0 0.000019655 0 m N cfq4162S / add_to_rr 8,64 3 0 0.000021945 0 m N cfq4162S / idle=0 8,64 3 5 0.000023460 4162 U N [fs_mark] 1 8,64 3 0 0.000025761 0 m N cfq workload slice:300 8,64 3 0 0.000027137 0 m N cfq4162S / set_active wl_prio:0 wl_type:2 8,64 3 0 0.000028588 0 m N cfq4162S / fifo=(null) 8,64 3 0 0.000029468 0 m N cfq4162S / dispatch_insert 8,64 3 0 0.000031359 0 m N cfq4162S / dispatched a request 8,64 3 0 0.000032306 0 m N cfq4162S / activate rq, drv=1 8,64 3 6 0.000032735 4162 D R 73992 + 8 [fs_mark] 8,64 1 1 0.004276637 0 C R 73992 + 8 [0]
Total (sde): Reads Queued: 19, 76KiB Writes Queued: 142,183, 568,732KiB Read Dispatches: 19, 76KiB Write Dispatches: 25,440, 568,732KiB Reads Requeued: 0 Writes Requeued: 125 Reads Completed: 19, 76KiB Writes Completed: 25,315, 568,732KiB Read Merges: 0, 0KiB Write Merges: 116,868, 467,472KiB IO unplugs: 20,087 Timer unplugs: 0
- Q — 區塊 I/O 已被排入佇列
- G — 取得請求新排入佇列的 I/O 不是會與既有請求合併的 I/O,因此已分配新的區塊層請求。
- M — 區塊 I/O 已與一項既有的請求合併。
- I — 請求已插入裝置的佇列中。
- D — 請求已傳送給裝置。
- C — 請求已由驅動程式完成。
- P — 區塊裝置佇列已插入,以讓請求能夠聚集。
- U — 裝置佇列未插入,這能讓已聚集的請求傳送給裝置。
- Q2Q — 請求傳送至區塊層所花費的時間
- Q2G — 從區塊 I/O 排入佇列開始到它被分配到一項請求之間所花費的時間
- G2I — 從請求被分配到它被插入裝置佇列之間所花費的時間
- Q2M — 從區塊 I/O 被排入佇列到它與既有請求合併之間所花費的時間
- I2D — 從請求被插入裝置佇列到它被實際傳送給裝置之間所花費的時間
- M2D — 從區塊 I/O 與既有請求合併到該請求被傳送給裝置之間所花費的時間
- D2C — 裝置請求的服務時間
- Q2C — 花費在請求的區塊層中的時間

圖形 6.2. seekwatcher 的範例輸出
6.4. 配置
6.4.1. 完全公平佇列(CFQ)
ionice
指令來手動指定排程類型,或是透過 ioprio_set
系統呼叫來進行程式性的指定。就預設值,程序會被指定為「BE」排程類型。接著,「RT」與「BE」排程類型會更進一步被分成八個 I/O 優先順序,0 代表最高,7 則代表最低。排程類型為「RT」的程序,其排程性質一般會比「BE」或是閒置的程序要來得重要,因此所有排程為「RT」的 I/O 請求總是會在「BE」或是閒置的 I/O 請求之前進行。這代表擁有「即時」優先順序的 I/O 請求可能會使「BE」與閒置類型的 I/O 請求資源不足。「BE」排程為預設的排程類型,而「4」為此類型中的預設優先順序。閒置排程類型的程序,僅會在系統中沒有其它等待處理的 I/O 請求之後,才會被處理。因此請切記,只有在程序的 I/O 請求完全不會影響順向進度的情況下,才將該程序的 I/O 排程類型設為閒置。
/sys/block/device/queue/iosched/
中,相同名稱的檔案裡,設置下列參數:
slice_idle = 0 quantum = 64 group_idle = 1
group_idle
設為 1 的時候,I/O 依然會有停止的可能性(基於後端儲存裝置因閒置而不忙碌)。然而,這些停止情況在系統中的所有佇列上發生的頻率,會比閒置的情況要來得低。
微調參數
back_seek_max
- 反向搜尋一般會影響效能,因為與正向搜尋相較之下,它們可能會因為要重新調整位置,而導致更嚴重的延遲。然而,若是工作量不大,CFQ 還是會執行它們。此微調選項能控制 I/O 排程器允許進行反向搜尋的最大距離(單位為 KB)。預設值為
16
KB。 back_seek_penalty
- 基於反向搜尋的低效率,各項反向搜尋皆有與其相聯的罰則。此罰則乃一項乘數;比方說,若有個磁頭位於 1024KB。假設佇列中有兩項請求,一個位於 1008KB 而另一個則為 1040KB。這兩項請求與目前的磁頭位置乃是等距離的。然而,在套用了反向搜尋罰則(預設值:2)之後,在磁碟後方位置上的請求,現在其距離便將會與先前的請求接近兩倍。因此,磁頭將會往前移。
fifo_expire_async
- 此微調選項能控制一項 async(緩衝寫入)請求能等待多久。在經過了這段有效時間(單位為 ms)之後,一項資源不足的 async 請求將會被移至分派清單中。預設值為
250
ms。 fifo_expire_sync
- 對於同步(讀取和 O_DIRECT 寫入)請求來說,這與 fifo_expire_async 微調選項相同。預設值為
125
ms。 group_idle
- 當設置後,CFQ 將會閒置在控制群組中,最後一個發出 I/O 請求的程序上。當使用等比例權重 I/O cgroup 時,這應設為
1
,並將slice_idle
設為0
(一般在高速的儲存裝置上會這麼做)。 group_isolation
- 若啟用了群組隔離(設為
1
),它會藉以犧牲傳輸量來換取較強大的隔離機制。一般來講,若群組隔離被停用的話,公平機制則只會套用在循序的工作量上。啟用群組隔離,將能為循序和隨機的工作量同時提供公平機制。預設值為0
(停用)。欲取得更多資訊,請參閱Documentation/cgroups/blkio-controller.txt
。 low_latency
- 當啟用了低度延遲時(設為了
1
),CFQ 會嘗試提供 300 ms 的等待時間最大值。這將會注重公平機制多過於傳輸量。停用低度延遲(設為0
)將會忽略目標延遲,並讓系統中的各項程序取得完整的時間配量。預設值將會啟用低度延遲。 quantum
- 定量(quantum)可控制 CFQ 在一段時間內會傳送至儲存裝置的 I/O 請求數量,基本上就是限制裝置的佇列深度。就預設值,這將會設為
8
。儲存裝置可能能夠支援極深的佇列深度,不過增加quantum
將會負面影響延遲,尤其是當有大量的循序寫入工作時。 slice_async
- 此微調選項可控制撥給各項發出非同步(緩衝寫入)I/O 請求之程序的時間配量。就預設值,它會被設為
40
ms。 slice_idle
- 這指定 CFQ 在等待進一步需求時,應該閒置多久。RHEL 6.1 以前的預設值為
8
ms。RHEL 6.2 以後的預設值為0
。這個 0 改進了外部 RAID 儲存裝置的總處理能力,方法是移除所有佇列與服務樹等級的閒置時間。然而,設定為 0 會降低內部非 RAID 儲存裝置的效能,因為這會增加整體搜尋數目。對於非 RAID 儲存裝置,我們建議使用大於 0 的值來設定slice_idle
。 slice_sync
- 此微調選項可決定撥給多少時間配量給發出同步(讀取或直接寫入)I/O 請求的程序。預設值為
100
ms。
6.4.2. 期限 I/O 排程器
微調參數
fifo_batch
- 這會決定單一批次處理中,發出的讀取與寫入數量。預設值為
16
。將這個值提高會讓總處理能力變高,但延遲時間也會變長。 front_merges
- 如果您確定工作負載永遠不會產生「前端合併」(front merge),您可以將這微調選參數設為
0
。除非您已經測量過這項檢查的工作負荷,否則建議您使用預設設定(1
)即可。 read_expire
- 這項微調參數能讓使用者設定單次讀取所接受的服務時間,單位為 ms。預設值為
500
ms(半秒)。 write_expire
- 這項微調參數能讓使用者設定單次寫入所接受的服務時間,單位為 ms。預設值為
5000
ms(五秒)。 writes_starved
- 此微調參數會控制在處理單一寫入批次處理前,能處理多少寫入批次處理。這個值愈高,能給寫入處理的參照項目就愈多。
6.4.3. Noop
/sys/block/sdX/queue tunables
- add_random
- 在一些情況下,I/O 事件的負載對
/dev/random
的亂數集區的影響,是可以測量的。在這種情況下,將這個值設為零較佳。 max_sectors_kb
- 就預設值,可傳送給磁碟的最大請求大小為
512
KB。此微調選項可被使用來提升或降低這個值。最小值是以邏輯區塊大小所限制的;最大值則是以max_hw_sectors_kb
限制。有些 SSD 在 I/O 大小超過了內部清除區塊大小時,效能會變差。在這種情況下,建議您將max_hw_sectors_kb
微調成清除區塊的大小。您可透過使用一個例如 iozone 或是 aio-stress 的 I/O 產生程式來進行測試,並使用各種不同記錄大小(比方說由512
位元組至1
MB)。 nomerges
- 這個微調選項有助於除錯。大部分工作負載都能得益於合併需求(即使在更快的儲存裝置,例如 SSD 上亦然)。然而在一些情況下,例如想要知道後端儲存裝置的 IOPS 數據時,會想要停用合併功能,而不停用預先讀取或進行隨機讀取。
nr_requests
- 每個需求佇列都有可分配給每個讀、寫 I/O 的需求描述子的限制。預設上,這個數值是
128
,表示在同一個時間內,在把程序放入睡眠狀態之前,佇列中可以有 128 組讀取、以及 128 組寫入。放入睡眠狀態的程序是下一個要試著分配需求的程序,並不一定是已分配所有可用需求的程序。如果應用程式不適合延遲,那麼不妨降低需求佇列的nr_requests
值,並限制儲存裝置的指令佇列深度至低的值(甚至可以低到1
),這樣一來回寫 I/O 就無法分配所有可用需求描述子,並以寫入 I/O 填滿整個裝置佇列。一旦nr_requests
已分配,所有試圖進行 I/O 的其它程序會被放入睡眠狀態,以等待可用需求出現。這會讓事情變得公平,因為接下來需求會以輪詢方式分配(而不是讓單一程序快速地連續消耗所有需求)。請注意,在使用期限排程器或 noop 排程器時,這不會是問題,因為預設的 CFQ 配置會在這種情況下進行保護。 optimal_io_size
- 在一些情況下,下層的儲存裝置會回報最適合的 I/O 大小。這在軟、硬體 RAID 之間最常見,因為最適 I/O 大小正是磁條的大小。如果回報了這個值,應用程式應該會儘可能發出適用於最適 I/O 大小的多組對應。
read_ahead_kb
- 當應用程式從檔案或磁碟循序讀取資料時,作業系統會偵測到此一行為。在這種情況下,作業系統會使用智慧型預先讀取的演算法則,藉以從磁碟中讀取比使用者要求更多的資料。這樣一來,當下一個使用者試著讀取資料時,資料已經位於作業系統的分頁快取中。潛在的壞處是,作業系統可能會從磁碟讀取超過所需的資料,佔據太多分頁快取的空間,對記憶體使用量造成壓力。在這種情況下,太多程序都發生錯誤的預先讀取,會對記憶體造成壓力。對於裝置對應(device mapper)的裝置,將
read_ahead_kb
增加至較大的值,例如8192
,是個好主意。這是因為裝置對應的裝置通常是由多個底層裝置所構成。將這個預設值(128
KB)乘以對應的裝置數量,是進行微調的適合起點。 rotational
- 傳統硬碟通常有著運轉的部件(例如轉盤)。然而 SSD 卻沒有。大部分 SSD 都標榜此一特性。然而,如果您發現有個裝置並不標榜此一特性,也許可以將此值手動設為
0
;當停用此值時,I/O elevator 並不會使用降低搜尋時間的邏輯,因為在非運轉的裝置上進行搜尋,效能幾乎不會降低。 rq_affinity
- 發出 I/O 的 CPU 與完成 I/O 的 CPU 不一定是同一個。將
rq_affinity
設為1
會導致 kernel 將完成 I/O 的動作,發至發出 I/O 的 CPU 上。這可以改善 CPU 資料快取的效能。
章 7. 檔案系統
7.1. 檔案系統微調考量
7.1.1. 格式化選項
區塊大小可在進行 mkfs
時選擇。可用的區塊大小範圍取決於系統本身:最大上限為主機系統的最大分頁大小,而最小限制則取決於所使用的檔案系統。預設的區塊大小適用於大部份的情況。
若您的系統使用等量(striped)的儲存裝置(例如 RAID 5),您可在進行 mkfs
時,將資料和 metadata 與基礎儲存裝置幾何對稱,以改善效能。當使用軟體 RAID(LVM 或是 MD)和某些企業硬體儲存裝置時,這項資訊會被查詢並自動設置,不過在許多情況下,管理員必須在命令列上以 mkfs
來手動指定這項幾何分佈。
工作量若包含大量 metadata,即代表日誌檔案系統(例如 ext4 和 XFS)的記錄檔部分會時常更新。若要儘可能減少檔案系統搜尋日誌的時間,您可將日誌放置在專屬的儲存裝置上。然而請注意,若將日誌放置在速度比主要檔案系統還要慢的外部儲存裝置上,使用該外部儲存裝置所得到的結果可能會不甚理想。
警告
mkfs
時會建立外部日誌,掛載時會指定日誌裝置。欲取得更多資訊,請參閱 mke2fs(8)
、mkfs.xfs(8)
和 mount(8)
man page。
7.1.2. 掛載選項
「寫入屏障」(write barrier)是個用來確保檔案系統 metadata 正確寫入永續性儲存裝置,並正確排序的 kernel 機制;即使停電,揮發性寫入快取的儲存裝置亦能確保資料無誤。啟用了寫入屏障的檔案系統亦可確保任何透過 fsync()
傳輸的資料皆能保有永續性(預防停電的狀況發生)。預設上,RHEL 會在所有支援寫入屏障的硬體上啟用屏障。
fsync()
的應用程式,或是建立和刪除許多小型檔案的應用程式。如果您能接受沒有揮發性寫入快取的儲存裝置、或是因為停電而導致檔案不一致和資料遺失等情況,您可藉由使用 nobarrier
掛載選項來停用屏障。欲取得更多相關資訊,請參閱《儲存裝置管理指南》。
以前讀取檔案時,檔案的存取時間(atime
)必須更新於 inode metadata 中,這包含了額外的寫入 I/O。若不需要正確的 atime
metadata,請以 noatime
選項掛載檔案系統,以避免更新這些 metadata。然而在大部份情況下,基於 Red Hat Enterprise Linux 6 kernel 中的預設相對 atime(或是 relatime
)特性,atime
不會是個極大的額外負荷。relatime
特性僅會在先前的 atime
比修改時間(mtime
)或是狀態更改時間(ctime
)還要早的情況下更新 atime
。
注意
noatime
選項也會啟用 nodiratime
的特性;您無須同時設置 noatime
和 nodiratime
。
「預先讀取」(read-ahead)會透過事先讀取資料,並將之載入分頁快取中(讓這些資料能預先存在記憶體中,而不用再由硬碟存取),以提升檔案存取的速度。某些工作量(例如那些包含了大量循序 I/O 串流的工作量)能有效受益於高度的預先讀取值。
blockdev
指令來檢視並編輯預先讀取值。若要檢視某個區塊裝置目前的預先讀取值,請執行:
# blockdev -getra device
# blockdev -setra N device
blockdev
指令選擇的值不會保有永續性。我們建議您建立一份 runlevel init.d
script,以在開機時設置這個值。
7.1.3. 檔案系統維護
「批次清除」與「線上清除」皆為已掛載之檔案系統,用來清除未使用之區塊所進行的作業。這些作業亦適用於固態硬碟和精簡佈建的儲存裝置。
fstrim
指令來執行「批次清除作業」(batch discard operation)。這項指令會清除檔案系統中,所有符合使用者指定條件的未使用區塊。只要檔案系統下的區塊裝置支援實體清除作業,RHEL 6.2 以上版本搭配 XFS 與 ext4 檔案系統就支援這兩項作業類型。若 /sys/block/device/queue/discard_max_bytes
的值非零的話,即代表實體清除作業受支援。
-o discard
選項(在 /etc/fstab
中或是作為 mount
指令的一部分)來指定,並在無使用者互動的情況下即時執行。線上清除作業僅會清除狀態由「已使用」切換為「可用」的區塊。線上清除作業在 RHEL 6.2 以上版本的 ext4 檔案系統上受到支援,並且也在 RHEL 6.4 以上的 XFS 檔案系統上受到支援。
7.1.4. 應用程式考量
ext4、XFS 和 GFS2 檔案系統皆支援透過 fallocate(2)
glibc 呼叫,來進行高效率的空間預先分配功能。在某些情況下,檔案可能會因為寫入模式而過度分散,並間接影響讀取效能,這時空間預先分配就會是一項非常有幫助的技巧。預先分配功能會標記磁碟空間,在不寫入任何資料的情況下,使該空間猶如早已分配給了某個檔案。直到真實的資料寫入某個預先分配的區塊之前,讀取作業所回傳的值將會是零。
7.2. 檔案系統效能的設定檔
latency-performance
- 用來微調典型延遲效能的伺服器設定檔。它能停用 tuned 和 ktune 省電機制。
cpuspeed
模式會改為performance
(效能)。而 I/O elevator 則會更改各項裝置的deadline
(期限)。cpu_dma_latency
會註冊為0
(這是最低的延遲時間),以儘可能將電源管理服務品質的延遲限制住。 throughput-performance
- 用來進行傳輸量效能微調的伺服器設定檔。若系統未裝載企業級的儲存裝置,建議使用此設定檔。它與
latency-performance
相似,除了:kernel.sched_min_granularity_ns
(排程器的最小先佔精細程度)已設為10
毫秒、kernel.sched_wakeup_granularity_ns
(排程器的甦醒精細程度)已設為15
毫秒、vm.dirty_ratio
(虛擬機器的已變更比例)已設為 40%,並且- 啟用通透式巨型分頁。
enterprise-storage
- 建議將此設定檔用於搭配了企業級儲存裝置(包括含備用電池的控制器快取保護,以及磁碟上的快取管理)的企業級伺服器配備。它與
throughput-performance
設定檔相似,除了:readahead
值已設為4x
,並且- 非 root/boot 的檔案系統會被以
barrier=0
重新掛載。
man tuned-adm
),或是《電源管理指南》,網址為 https://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/?locale=zh-TW。
7.3. 檔案系統
7.3.1. ext4 檔案系統
注意
對於非常大的檔案系統來說,mkfs.ext4
程序會花上大量時間,才能初始化該檔案系統中的所有 inode。使用者能藉由 -E lazy_itable_init=1
選項來遞延這項程序。若使用了此選項,在檔案系統被掛載之後,kernel 程序將會繼續將它初始化。這項初始化發生的頻率可透過 mount
指令的 -o init_itable=n
選項來進行控制,而執行這項背景初始化的所需時間約 1/n。n
的預設值為 10
。
因為並非所有應用程式都能在重新命名、或是截斷和重新寫入一個既有檔案之後,正確進行 fsync()
,因此預設上 ext4 會在進行了「replace-via-rename」(透過更名來取代)和「replace-via-truncate」(透過截斷來取代)作業後,自動同步檔案。此特性與較舊的 ext3 檔案系統特性一致。然而,fsync()
作業可能會很耗時,因此若不需要使用此自動特性的話,請搭配 -o noauto_da_alloc
選項執行 mount
指令,以將它停用。這代表應用程式必須明確地使用 fsync()
,以確保資料的永續性。
就預設值,寫入日誌 I/O 的優先順序,會比一般正常 I/O 要來的高。此優先順序能以 mount
指令的 journal_ioprio=n
選項來控制。預設值為 3
。有效值的範圍為 0 到 7,0 代表優先順序最高的 I/O。
mkfs
和掛載選項上的相關資訊,請參閱 mkfs.ext4(8)
和 mount(8)
man page,以及位於 kernel-doc 套件中的 Documentation/filesystems/ext4.txt
檔案。
7.3.2. XFS 檔案系統
mkfs
進行時所提供的某些微調選項,會隨著 b-tree 的寬度而改變,並且改變不同子系統的擴充性特質。
7.3.2.1. XFS 的基本微調
mkfs.xfs
指令會自動為自己配置正確的等量磁條單位與寬度,好與硬體對應。若您使用的是硬體 RAID,您可能將需要進行手動配置。
inode64
掛載選項,除非檔案系統是透過 NFS 匯出,而傳統 32 位元的 NFS 客戶端需要存取檔案系統。
logbsize
掛載選項。預設值為 MAX
(32 KB,記錄檔等量磁條單位),而最大大小為 256 KB。若檔案系統會大量進行修改,建議使用 256 KB 這個值。
7.3.2.2. XFS 進階微調
XFS 會加入任意的限制,以限制某個檔案系統所能容納的檔案數量。就一般使用上來講,使用者通常不會達到或超過這項限制。若您一開始便知道預設限制過低,可透過 mkfs.xfs
指令來增加 inode 可使用的檔案系統空間百分比。若您在建立了系統後才遇上達到限制值的情況(通常在嘗試建立檔案或目錄時會出現一則 ENOSPC 錯誤,儘管您依然還有可用空間),您可透過 xfs_growfs
指令來調整這項限制。
對於檔案系統來說,其目錄區塊大小永遠會是固定的,並且除非透過 mkfs
重新格式化,否則無法變更。最小目錄區塊為檔案系統的區塊大小,預設值為 MAX
(4 KB,檔案系統區塊大小)。一般來講,您並無任何降低目錄區塊大小的理由。
和其它檔案系統不同,XFS 可同時執行許多類型的分配與解除分配作業(前提是這些作業必須發生在非共享的物件上)。磁區的分配與解除分配能同時發生,前提是並行的作業必須發生在不同的分配群組中。相同的,inode 的分配與解除分配亦可同時發生,前提是並行的作業會影響不同的分配群組。
若 inode 中有足夠的可用空間,XFS 可將小的屬性直接存放在 inode 中。若屬性能容納在 inode 中,它便能在無需透過額外 I/O 截取獨立屬性區塊的情況下,截取和修改。內置與非內置屬性的效能相較之下,非內置屬性的效能將會慢上一個量級。
記錄檔的大小乃判斷持久性 metadata 能進行何種修改程度的主要因素。記錄裝置乃循環性的,因此在尾線能被覆寫之前,記錄檔中的所有變更皆必須寫入磁碟上的真實位置中。這可能需要耗費一段搜尋時間,以將所有需要變更的 metadata 寫回。一般就預設配置,記錄檔的大小會根據檔案系統的總大小設置,因此在大部份情況下您沒有必要微調記錄檔。
mkfs
就預設值會擴充性 MD 和 DM 裝置進行此動作,不過對於硬體 RAID,您可能需要特別指定。正確進行此設置,可避免記錄檔 I/O 在將變更寫入磁碟中的時候,造成非對應的 I/O 和 read-modify-write(讀取 - 修改 - 寫入)作業。
logbsize
)將會增加變更寫入記錄檔中的速度。預設的記錄緩衝區大小為 MAX
(32 KB,記錄等量磁條單位),並且最大大小為 256 KB。一般來講,愈大的值會提供愈高的效能。然而,若 fsync 工作負載較高時,較小的記錄緩衝區的速度,會比對應了大型等量單位的較大緩衝區快上許多。
delaylog
掛載選項也會透過減少更改日誌檔案的次數,來改善持久性的 metadata 變更效能。它會透過在將個別變更寫入日誌之前,先將這些變更彙總至記憶體中:時常修改的 metadata 會週期性地被寫入日誌中,而非僅在每次進行修正時。此選項會增加記憶體使用量,以追蹤需要變更的 metadata,並增加當機時作業遺失的可能性,不過這可改善約一或更多個量級的 metadata 修改速度與擴充性。使用此選項搭配 fsync
、fdatasync
或是 sync
來確認資料和 metadata 是否有寫入磁碟中,便可確保資料或是 metadata 的完整性。
7.4. 叢集
7.4.1. 全域檔案系統 2
- 儘可能使用
fallocate
來預先分配檔案和目錄,以優化分配程序並避免需要鎖定來源分頁。 - 減少共享於多個節點之間的檔案系統區域,以減少跨節點的快取無效判定,並改善效能。比方說,若有多個節點掛載了相同的檔案系統而存取不同的子目錄,將其中一個子目錄移至另一檔案系統上,可能能夠取得較佳的效能。
- 選擇最佳的資源群組大小與數量。這取決於典型的檔案大小和系統上的可用空間,並影響多個節點是否會嘗試同時使用某個資源群組的機率。資源群組若過多,尋找分配空間時可能會使區塊分配變得緩慢。若資源群組過少,則可能會在解除分配時造成鎖定競用。一般建議測試多項不同配置,以判斷何種配置適用於您的工作量。
- 根據來自叢集的預期 I/O 模式,以及檔案系統的效能需求選擇您的儲存裝置硬體。
- 儘可能使用固態儲存裝置,以減少搜尋時間。
- 為您的工作量建立適當大小的檔案系統,並確保檔案系統的使用量絕不會超出 80%。較小的檔案系統的備份時間相對之下也會較短,並且進行檔案系統檢查時所需的時間與記憶體也較少,然而若檔案系統對於其工作量來說過小,則容易發生檔案高度分散的情形。
- 當工作量需要使用到大量 metadata,或是當日誌資料使用中的時候,請設置較大的日誌大小。雖然這會使用到較多的記憶體,卻也會提升效能,因為將會有更多可存放資料的日誌空間。
- 確認 GFS2 節點上的時鐘已同步,以避免網路應用程式發生問題。我們建議使用 NTP(網路時間協定)。
- 除非檔案或是目錄的存取時間對於您的應用程式來說相當重要,否則請以
noatime
和nodiratime
掛載選項來掛載檔案系統。注意
Red Hat 強烈建議您搭配noatime
選項使用 GFS2。 - 若您需要使用配額,請嘗試減少配額同步交易的頻率,或是使用模糊配額同步,以避免持續的配額檔案更新,造成效能上的問題。
注意
模糊配額計量能讓使用者和群組稍微超用其配額限制。為了避免此問題發生,GFS2 會在某個使用者或群組即將超用其配額限制時,動態式地減少同步的時間。
章 8. 網路
8.1. 網路效能提升
8.1.1. 接收封包操控(Receive Packet Steering,RPS)
rx
佇列,使其接收 softirq
的工作量散佈在數個 CPU 之間。這可避免網路流量在單一 NIC 硬體佇列上遇上瓶頸。
/sys/class/net/ethX/queues/rx-N/rps_cpus
中指定目標 CPU 的名稱,請將 ethX
取代為 NIC 的相應裝置名稱(例如 eth1
、eth2
),並將 rx-N
取代為指定的 NIC 接收佇列。這便能讓檔案中指定的 CPU 處理來自於 ethX
上,rx-N
佇列中的資料。當指定 CPU 時,請考量佇列的「快取關聯」(cache affinity) [4]。
8.1.2. 接收流量操控(Receive Flow Steering,RFS)
/proc/sys/net/core/rps_sock_flow_entries
- 這可控制 kernel 能轉至特定 CPU 的最大 socket/流量數。這是系統全域的共享限制。
/sys/class/net/ethX/queues/rx-N/rps_flow_cnt
- 這能控制 kernel 在一張網路卡(
ethX
)上,所能轉至特定接收佇列(rx-N
)的最大插槽/流量數量。請注意,此微調項目所有各佇列的值的加總,在所有網路卡上皆應與/proc/sys/net/core/rps_sock_flow_entries
的值相等或更低。
8.1.3. TCP 精簡串流的 getsockopt 支援
getsockopt
已改善以支援兩項額外選項:
- TCP_THIN_DUPACK
- 此布林值能在進行了一項精簡串流的 dupACK 之後,啟用重新傳輸的動態觸發。
- TCP_THIN_LINEAR_TIMEOUTS
- 此布林值會動態觸發精簡串流的線性逾時。
file:///usr/share/doc/kernel-doc-version/Documentation/networking/ip-sysctl.txt
。欲取得更多有關於精簡串流上的相關資訊,請參閱 file:///usr/share/doc/kernel-doc-version/Documentation/networking/tcp-thin.txt
。
8.1.4. 支援通透式代理
file:///usr/share/doc/kernel-doc-version/Documentation/networking/tproxy.txt
。
8.2. 優化網路設定
- netstat
- 會印出網路連線、路由表、介面卡數據、偽裝連線和 multicast 成員的命令列工具程式。它會由
/proc/net/
檔案系統截取有關於網路子系統的資訊。這些檔案包含了:/proc/net/dev
(裝置資訊)/proc/net/tcp
(TCP socket 資訊)/proc/net/unix
(Unix 區域 socket 資訊)
欲取得更多有關於netstat
及其位於/proc/net/
的參照檔案的相關資訊,請參閱netstat
的 man page,指令為:man netstat
。 - dropwatch
- 這是個用來監控 kernel 所捨棄的封包的監控工具程式。欲取得更多資訊,請參閱
dropwatch
的 man page,指令為:man dropwatch
。 - ip
- 這是個用來管理和監控路由、裝置、政策路由以及通道的工具程式。欲取得更多資訊,請參閱
ip
的 man page,指令為:man ip
。 - ethtool
- 這是個用來顯示和更改 NIC 設定的工具程式。欲取得更多資訊,請參閱
ethtool
的 man page,指令為:man ethtool
。 - /proc/net/snmp
- 這是個顯示了
snmp
代理程式管理 IP、ICMP、TCP 和 UDP 所需要的 ASCII 資料。它亦可顯示即時的 UDP-lite 數據。
/proc/net/snmp
中的 UDP 輸入錯誤若增加的話,即代表當網路堆疊嘗試將新的 frame 排入一個應用程式的 socket 時,一個或更多個 socket 接收佇列已滿。
8.2.1. Socket 接收緩衝區大小
sk_stream_wait_memory.stp
)顯示 socket 佇列的排出率過慢,您可嘗試增加應用程式的 socket 佇列的深度。若要這麼做,請藉由配置下列其中一個值,以增加 socket 所使用的接收緩衝區大小:
- rmem_default
- 這是個用來控制 socket 所使用的接收緩衝區「預設」大小的 kernel 參數。若要進行相關配置,請執行下列指令:
sysctl -w net.core.rmem_default=N
請將N
取代為您希望使用的緩衝區大小(位元組)。欲判定此 kernel 參數的值,請參閱/proc/sys/net/core/rmem_default
。請注意,rmem_default
的值不該超過rmem_max
(/proc/sys/net/core/rmem_max
);若需要超過這個值,請增加rmem_max
的值。 - SO_RCVBUF
- 這是個用來控制 socket 的接收緩衝區「最大」大小的 socket 選項(位元組)。欲取得更多有關於
SO_RCVBUF
的相關資訊,請用以下指令參閱 man page:man 7 socket
。若要配置SO_RCVBUF
,請使用setsockopt
工具程式。您可透過getsockopt
截取目前的SO_RCVBUF
值。欲取得更多有關於使用這兩個工具程式的相關資訊,請參閱setsockopt
的 man page,指令為:man setsockopt
。
8.3. 封包接收總覽

圖形 8.1. 網路接收路徑圖形
- 硬體接收:「網路介面卡」(NIC)會接收到線路上的 frame。根據其驅動程式配置,NIC 會將 frame 傳輸至一個內部硬體緩衝記憶體上,或至一個指定的信號緩衝區(ring buffer)上。
- Hard IRQ:NIC 會藉由插斷 CPU 來判斷網路 frame 是否存在。這會使 NIC 驅動程式被通知插斷,並排程「soft IRQ 作業」。
- Soft IRQ:此階段會實作實際的 frame 接收程序,並且以
softirq
執行。這代表此階段會先佔所有在指定 CPU 上執行的應用程式,但還是允許插入 hard IRQ。在此情況下(在與 hard IRQ 相同的 CPU 上執行,藉此減少鎖定額外負荷),kernel 會實際將 frame 由 NIC 硬體緩衝區上移除,並透過網路堆疊來處理它。在此,frame 會被轉送、丟棄或是傳送至一個目標監聽 socket 上。當傳送至一個 socket 時,frame 會被附加至擁有此 socket 的應用程式。這項程序會反覆進行,直到 NIC 硬體緩衝區的 frame 耗盡,或是直到達到「裝置權重」(dev_weight
)值為止。欲取得更多有關於裝置權重的相關資訊,請參閱〈節 8.4.1, “NIC 硬體緩衝區”〉。 - 應用程式接收:應用程式會透過標準的 POSIX 呼叫(
read
、recv
、recvfrom
),來接收 frame,並清除任何所屬 socket 中的佇列。在此情況下,透過網路接收的資料將不再存在網路堆疊上。
8.3.1. CPU/快取關聯
8.4. 解決常見的佇列/frame 遺失問題
8.4.1. NIC 硬體緩衝區
softirq
排出。若要監控此佇列的狀態,請執行以下指令:
ethtool -S ethX
ethX
取代為 NIC 的相應裝置名稱。這會顯示 ethX
中捨棄了多少 frame。通常,因為佇列耗盡了用來存放 frame 的空間時,便會發生捨棄的情況。
- 輸入流量
- 您可藉由減慢輸入流量的速度,以協助避免佇列發生溢位錯誤。您可透過篩選、減少加入的 multicast 群組數量、減少廣播流量等等的動作來避免溢位。
- 佇列長度
- 此外,您亦可增加佇列的長度。也就是將特定佇列的緩衝區數量增加到驅動程式所能允許的最大值。若要這麼做,請使用以下指令來編輯
ethX
的rx
/tx
信號參數:ethtool --set-ring ethX
附加適當的rx
或是tx
值至先前提到的指令中。欲取得更多相關資訊,請參閱man ethtool
。 - 裝置權重
- 您亦可增加佇列被排出的速率。若要這麼做,請調整 NIC 的相應「裝置權重」。此屬性代表
softirq
必須微調 CPU 並將其重新排程前,NIC 所能接收的最大 frame 數量。這是以/proc/sys/net/core/dev_weight
變數來進行控制的。
8.4.2. socket 佇列
softirq
的網路堆疊。接著應用程式便會排出與它們相應的佇列(透過呼叫 read
、recvfrom
等等)。
netstat
工具程式;Recv-Q
欄位顯示了佇列大小。一般來講,我們會使用相同的管理方式,來處理 socket 佇列中的溢位問題,以及 NIC 硬體緩衝區溢位問題(例如〈節 8.4.1, “NIC 硬體緩衝區”〉):
- 輸入流量
- 第一個選項就是透過配置佇列填滿的速率,以減慢連入流量的速度。若要這麼做,請篩選 frame,或是先佔式地將它們丟棄。您亦可透過降低 NIC 的裝置權重來減慢連入流量的速度[6]。
- 佇列深度
- 您亦可透過增加佇列深度,以避免 socket 佇列溢位。若要這麼做,請增加
rmem_default
kernel 參數或是SO_RCVBUF
socket 選項的值。欲取得有關於這兩者的相關資訊,請參閱〈節 8.2, “優化網路設定”〉。 - 應用程式呼叫頻率
- 請儘可能優化應用程式使其更頻繁地進行系統呼叫。這包含了修改和重新配置網路應用程式,使其更頻繁地進行 POSIX 系統(例如
recv
、read
)。相對的,這能讓應用程式更快速地排出佇列。
8.5. Multicast 考量
softirq
時發生。
softirq
的執行時間。新增監聽程式至一個 multicast 群組,代表每當該群組接收到一個 frame 時,kernel 就必須建立額外的副本。
softirq
執行時間,可能會導致於 frame 同時在網路卡上和 socket 佇列中遺失。softirq
runtime 的增加,亦代表了應用程式在高負載的系統上執行的機會會減少,當監聽高流量 multicast 群組的應用程式數量增加時,multicast frame 遺失的比率也會增加。
/proc/sys/net/core/dev_weight
進行控制。欲取得更多有關於裝置權重與其調整過後之效應的相關資訊,請參閱〈節 8.4.1, “NIC 硬體緩衝區”〉。
附錄 A. 修訂記錄
修訂記錄 | |||||
---|---|---|---|---|---|
修訂 4.0-22.3.400 | 2013-10-31 | Rüdiger Landmann | |||
| |||||
修訂 4.0-22.3 | Sat Jun 8 2013 | Chester Cheng | |||
| |||||
修訂 4.0-22.2 | Tue Jun 4 2013 | Terry Chuang | |||
| |||||
修訂 4.0-22.1 | Thu Apr 18 2013 | Chester Cheng | |||
| |||||
修訂 4.0-22 | Fri Feb 15 2013 | Laura Bailey | |||
| |||||
修訂 4.0-19 | Wed Jan 16 2013 | Laura Bailey | |||
| |||||
修訂 4.0-18 | Tue Nov 27 2012 | Laura Bailey | |||
| |||||
修訂 4.0-17 | Mon Nov 19 2012 | Laura Bailey | |||
| |||||
修訂 4.0-16 | Thu Nov 08 2012 | Laura Bailey | |||
| |||||
修訂 4.0-15 | Wed Oct 17 2012 | Laura Bailey | |||
| |||||
修訂 4.0-13 | Wed Oct 17 2012 | Laura Bailey | |||
| |||||
修訂 4.0-12 | Tue Oct 16 2012 | Laura Bailey | |||
| |||||
修訂 4.0-9 | Tue Oct 9 2012 | Laura Bailey | |||
| |||||
修訂 4.0-6 | Thu Oct 4 2012 | Laura Bailey | |||
| |||||
修訂 4.0-3 | Tue Sep 18 2012 | Laura Bailey | |||
| |||||
修訂 4.0-2 | Mon Sep 10 2012 | Laura Bailey | |||
| |||||
修訂 3.0-15 | Thursday March 22 2012 | Laura Bailey | |||
| |||||
修訂 3.0-10 | Friday March 02 2012 | Laura Bailey | |||
| |||||
修訂 3.0-8 | Thursday February 02 2012 | Laura Bailey | |||
| |||||
修訂 3.0-5 | Tuesday January 17 2012 | Laura Bailey | |||
| |||||
修訂 3.0-3 | Wednesday January 11 2012 | Laura Bailey | |||
| |||||
修訂 1.0-0 | Friday December 02 2011 | Laura Bailey | |||
|