io性能分析篇


=======================io性能分析篇=======================
相關概念:
1.文件系統:本身對存儲設備上的文件,進行組織管理的機制。組織方式不同,就會形成不同的文件系統。
2.為了方便管理,Linux文件系統為每個文件都分配兩個數據結構,索引節點和目錄項。它們主要用來記錄文件的元信息和目錄結構
*索引節點:簡稱inode,用來記錄文件的元數據,比如inode編號、文件大小、訪問權限、修改日期、數據的位置等。索引節點和文件一一對應,它跟文件內容一樣,都會被持久化存儲到磁盤中。
*目錄項:簡稱dentry,用來記錄文件的名字、索引節點指針以及其他目錄項的關聯關系。多個關聯的目錄項,就構成了文件系統的目錄結構。不過,不同於索引節點,目錄項是由內核維護的一個內存數據結構,所以通常也被叫做目錄項緩存。
3.磁盤讀寫的最小單位是扇區,為了提高磁盤的讀寫效率,文件系統又把連續的扇區組成了邏輯塊,每次都以邏輯塊為最小單元來管理數據。常見的邏輯塊大小為4kb,也就是連續的8個扇區。一個扇區512B
4.注意點:
*目錄項本身就是一個內存緩存,而索引節點則是存儲在磁盤中的數據。為了協調慢速磁盤與快速CPU的性能差異,文件內容會緩存在頁緩存cache中。
*磁盤在執行文件系統格式化時,會被分成三個存儲區域:超級快、索引節點區和數據塊區
超級塊:存儲整個文件的狀態
索引節點區:用來存儲索引節點
數據塊區:用來存儲文件數據
5.文件系統的四大要素:目錄項、索引節點、邏輯塊以及超級塊
6.為了支持各種不同的文件系統,Linux內核在用戶進程和文件系統中間,又引入了一個抽象層,也就是虛擬文件系統VFS(virtual file system)
7.VFS定義了一組所有文件系統都支持的數據結構和標准接口。這樣,用戶進程和內核中的其他子系統,只需要跟VFS提供的統一接口進行交互就可以了,不需要關系底層各種文件系統的實現細節。
8.各種文件系統按照層次分類:
第一類:基於磁盤的文件系統,也就是把數據直接存儲到計算機本地掛載的磁盤中。常見的ext4、xfs、overlayfs等。
第二類:基於內存的文件系統,也就是我們常說的虛擬文件系統。這類文件系統,不需要任何磁盤分配存儲空間,但會占用內存。我們經常用到的/proc文件系統,就是一種最常用的文件系統。此外,/sys文件系統也屬於這一類,主要向用戶空間導出層次化的內核對象。
第三類:網絡文件系統,也就是用來訪問其他計算機數據的文件系統,比如NFS、SMB、ISCSI等。
9.把文件系統掛載到掛載點后,就能通過掛載點訪問它管理的文件了。VFS提供了一組標准的文件訪問接口。這些接口以系統調用的方,提供給程序使用。
如:cat命令,它首先調用open()調用,打開一個文件,然后調用read()調用,讀取文件的內容,最后再用write()調用,把文件內容輸出到控制台的標准輸出中。
10.文件讀寫方式的各種差異,導致i/o的分類多種多樣。最常見的有:緩沖與非緩沖io、直接與非直接io、阻塞與非阻塞io、同步與異步io等。
11.各種io類型解釋:
第一種:根據是否利用標准庫緩存,可以把文件 I/O 分為緩沖 I/O 與非緩沖 I/O。
緩沖io:是指利用標准庫緩存來加速文件的訪問,而標准庫內部則通過系統調度訪問文件。
非緩沖io:是指直接通過系統調用來訪問文件,不在經過標准庫緩存。注,這里說的"緩沖",是指標准文件庫內部實現的緩存。比方說,你可能見過,很多程序遇到換行時才真正輸出,而換行前的內容,其實就是被標准庫暫時緩存了起來。
第二種:根據是否利用操作系統的頁緩存,直接跟文件系統交互來訪問文件
直接io(裸io/raw io):是指跳過操作系統的頁緩存,直接跟文件系統交互來訪問文件
非直接io:正好相反,文件讀寫時,先要經過系統的頁緩存,然后再由內核或額外的系統調用,真正寫入磁盤。
注:要想實現直接io,需要你在文件系統調用中,指定O_DIRECT標志,如果沒有設置過,默認是非直接IO
第三種:根據應用程序是否阻塞自身運行,可以把文件io分為阻塞io和非阻塞io
阻塞io:是指應用程序執行io操作后,如果沒有獲得響應,就會阻塞當前線程,自然就不能執行其他任務
非阻塞io:是指應用程序執行io操作后,不會阻塞當前的線程,可以繼續執行其他的任務,隨后再通過輪詢或者事件通知的形式,獲取調用的結果。
如:訪問管道或者網絡套接字時,設置O_NONBLOCK標志,就表示用非阻塞方式訪問;而如果不做任何設置,默認的就是阻塞訪問。
第四種:根據是否等待響應結果,可以把文件io分為同步和異步io
同步io:是指應用程序執行io操作后,要一直等到整個io完成后,才能獲得io響應
異步io:是指應用程序執行io操作后,不用等待完成和完成后的響應,而是繼續執行就可以。等到這次io完成后,響應會用事件通知的方式告訴應用程序。
如1:在操作文件時,如果你設置了 O_SYNC 或者 O_DSYNC 標志,就代表同步 I/O。如果設置了 O_DSYNC,就要等文件數據寫入磁盤后,才能返回;而 O_SYNC,則是在 O_DSYNC 基礎上,要求文件元數據也要寫入磁盤后,才能返回。
如2:在訪問管道或者網絡套接字時,設置了 O_ASYNC 選項后,相應的 I/O 就是異步 I/O。這樣,內核會再通過 SIGIO 或者 SIGPOLL,來通知進程文件是否可讀寫。

=========================================================================================
緩存的相關查看使用:
1.命令df -h查看磁盤使用量,df -i查看inode節點信息
2.free 輸出的 Cache,是頁緩存和可回收 Slab 緩存的和,你可以從 /proc/meminfo:cat /proc/meminfo |grep -E "SReclaimable|Cached"
3.內核使用 Slab 機制,管理目錄項和索引節點的緩存。/proc/meminfo 只給出了 Slab 的整體大小,具體到每一種 Slab 緩存,還要查看 /proc/slabinfo 這個文件。
4.所有目錄項和各種文件系統索引節點的緩存情況:cat /proc/slabinfo |grep -E '^#|dentry|inode'
5.通過命令slabtop來找到占用內存最多的緩存類型,按下 c 按照緩存大小排序,按下 a 按照活躍對象數排序

=========================================================================================
磁盤:
1.機械磁盤與固態磁盤:
第一類,機械磁盤,也稱為硬盤驅動器(Hard Disk Driver),通常縮寫為HDD。機械磁盤主要由盤片和讀寫磁頭組成,數據就存儲在盤片的環狀磁道中。在讀寫數據前,需要移動讀寫磁頭,定位到數據所在的磁道,然后才能訪問數據。顯然,如果I/O請求剛好連續,那就不需要磁道尋址,自然可以獲得最佳性能。這其實就是我們熟悉的,連續I/O的工作原理。與之相對應的,當然就是隨機I/O,它需要不停地移動磁頭,來定位數據位置,所以讀寫速度就會比較慢。

第二類,固態磁盤(SolidStateDisk),通常縮寫為SSD,由固態電子元器件組成。固態磁盤不需要磁道尋址,所以,不管是連續 I/O,還是隨機 I/O的性能,都比機械磁盤要好得多。其實,無論機械磁盤,還是固態磁盤,相同磁盤的隨機 I/O 都要比連續 I/O 慢很多,原因也很明顯。

2.按接口進行磁盤介質分類
硬盤分為 IDE(Integrated Drive Electronics)、SCSI(Small Computer SystemInterface) 、SAS(Serial Attached SCSI) 、SATA(Serial ATA) 、FC(FibreChannel) 等。

3.IDE設備會分配一個hd前綴的設備名,SCSI和SATA設備會分配一個sd前綴的設備名。如果是多塊同類型的磁盤,就會按照a、b、c 等的字母順序來編號。

4.磁盤的使用架構
*直接作為獨立磁盤設備來使用,可以根據需求化為不同的分區
*根據容量、性能和可靠性的考量,可以將磁盤組合成不同的raid級別
*把這些磁盤組合成一個網絡存儲集群,在通過NFS、SMB、ISCSI等網絡協議,暴露給服務器使用。

5.通用塊層
a.與虛擬文件系統類似,為了減少不同塊設備的差異帶來的影響,Linux通過一個統一的通用塊層,來管理不同的塊設備
b.第一功能:向上,為文系統和應用程序,提供訪問塊設備的標准接口;向下,把各種異構的磁盤設備抽象為統一的塊設備,並提供統一框架來管理這些設備的驅動程序。
c.第二功能:通用快層還會給文件系統和應用程序發來的io請求排隊,並通過重新排序、請求合並等方式,提高磁盤的讀寫效率。
d.對io請求排序的過程,也就是我們熟悉的io調度。事實上,Linux內核支持四種io調度算法,分別是NONE、NOOP、CFQ以及DeadLine.
e.第一種NONE,更確切的來說,並不能算io調度算法。因為它完全不使用任何io調度器,對文件系統和應用程序的io其實不做任何處理,常用在虛擬機中(此時磁盤io調度完全有物理機負責)
f.第二種NOOP,是最簡單的一種io調度算法,它實際上是一個先入先出的隊列,只做一些最基本的請求合並,常用於SSD
g.第三種CFQ,也被稱為完全公平調度器,是現在很多發行版的默認io調度器,它為每個進程維護一個io調度隊列,並按照時間片來均勻分布每個進程io請求。類似於進程CPU調度,CFQ還支持進程io的優先級調度,所以它適用於運行大量進程的系統,像是桌面環境、多媒體應用等。
h.最后一種DeadLine調度算法,分布為讀、寫請求創建了不同的io隊列,可以提高機械磁盤的吞吐量,並確保達到最終期限deadline的請求被優先處理。deadline調度算法,多用在io壓力比較重的場景,比如數據庫等。

6.io棧
a.我們可以吧Linux存儲系統的io棧,由上到下分為三個層次,分別是文件系統層、通用塊層和設備層。
b.文件系統層,包括虛擬文件系統和其他各種文件系統的具體實現。它為上層的應用程序,提供標准的文件訪問接口;對下會通過通用塊層,來存儲和管理磁盤數據。
c.通用塊層,包括塊設備io隊列和io調度器。它會對文件系統的io請求進行排隊,再通過重新排序和請求合並,然后才發送給下一級的設備層。
d.設備層,包括存儲設備和相應的驅動程序,負責最終物理設備的io操作。
e.存儲系統的io,通常是整個系統中最慢的一環。所以,Linux通過多種緩存機制來優化io效率。
f.為了優化存儲系統訪問文件的性能,會使用頁緩存、索引節點緩存、目錄項緩存等多種緩存機制,以及減少對下層塊設備的直接調用。
g.為了優化塊設備的訪問效率,會使用緩沖區,來緩存塊設備的數據。

=================================================================================
磁盤性能指標:.
1.磁盤性能基本指標
使用率:是指磁盤處理io的時間百分比。過高的使用率(比如超過80%),通常意味着磁盤io存在性能瓶頸。
飽和度:是指磁盤處理io的繁忙程度。過高的飽和度,意味着磁盤存在着嚴重的性能瓶頸。當飽和度為100%時,磁盤無法接受新的io請求。
IOPS:是指每秒的io請求數,適用於大量小文件的情景
吞吐量:是指每秒的io請求大小,適用與大文件的情景
響應時間:是指io請求從發出到收到響應的時間間隔

2.測試工具 fio ,來測試磁盤的 IOPS、吞吐量以及響應時間等核心指標

3.磁盤io觀測:iostat是最常用的磁盤I/O性能觀測工具,它提供了每個磁盤的使用率、IOPS、吞吐量等各種常見的性能指標,當然,這些指標實際上來自 /proc/diskstats。

4.iostat -d -x 1 #-d -x 表示顯示所有磁盤io的操作
%util ,就是我們前面提到的磁盤 I/O 使用率;
r/s+ w/s ,就是 IOPS;
rkB/s+wkB/s ,就是吞吐量;
r_await+w_await ,就是響應時間。

5.pidstat -d 1 #查看具體進程的io情況
用戶 ID(UID)和進程 ID(PID) 。
每秒讀取的數據大小(kB_rd/s) ,單位是 KB。
每秒發出的寫請求數據大小(kB_wr/s) ,單位是 KB。
每秒取消的寫請求數據大小(kB_ccwr/s) ,單位是 KB。
塊 I/O 延遲(iodelay),包括等待同步塊 I/O 和換入塊 I/O 結束的時間,單位是時鍾周期。

6.iotop命令可以io大小對進程進行排序

==================================================================================
案例一:io問題分析案例
top---iostat -x -d 1---pidstat -d 1/iotop---strace -p 進程號---lsof -p 進程號---修復---測試

查看buffer/cache占用,建議使用pcstat或者hcache,hcache是基於pcstat的,pcstat可以查看某個文件是否被緩存和根據進程pid來查看都緩存了哪些文件。hcache在其基礎上增加了查看整個操作系統Cache和根據使用Cache大小排序的特性。

Buffers 是內核緩沖區用到的內存,對應的是 /proc/meminfo 中的 Buffers 值。
Cache 是內核頁緩存和 Slab 用到的內存,對應的是 /proc/meminfo 中的 Cached 與SReclaimable 之和。

Buffers是對原始磁盤塊的臨時存儲,也就是用來緩存磁盤的數據,通常不會特別大(20MB左右)。這樣,內核就可以把分散的寫集中起來,統一優化磁盤的寫入,比如可以把多次小的寫合並成單次大的寫等等。

Cached是從磁盤讀取文件的頁緩存,也就是用來緩存從文件讀取的數據。這樣,下次訪問這些文件數據時,就可以直接從內存中快速獲取,而不需要再次訪問緩慢的磁盤

==================================================================================
案例二:io問題分析案例
top--iostat -x -d 1---pidstat -d 1/iotop---strace -p 進程號---無法定位到進程正在調用磁盤io---動態追蹤工具filetop命令---查看到進程創建了大量文件---opensnoop命令定位創建文件的位置---查看目錄發現沒有文件---在觀察一段時間opensnoop發現文件變了---說明文件是動態生成的---查看之前異常的進程源碼---確認問題根因

由於進程創建的文件為臨時文件,strace命令沒法動態查看到文件的創建刪除,所以無法定位問題。此時,借助工具filetop/opensnoop動態跟蹤命令追蹤進程的執行情況。
注:使用filetop/opensnoop命令需要安裝bcc軟件包,opensnoop 。它同屬於 bcc 軟件包,可以動態跟蹤內核中的
open 系統調用

在strace -p PID后加上-f,多進程和多線程都可以跟蹤
==================================================================================
案例三:數據庫io問題案例
top---iostat -d -x 1---pidstat -d 1/iotop---strace -f -p 進程號,追蹤線程級別的調用。可以去掉-f追蹤進程級別---lsof -p 進程號,沒有內容輸出,並且echo $?顯示為1,這是由於前面strace命令輸出的線程號,lsof是指定進程號---通過線程號ps查看進程號---pstree -f -a -p 進程號,可以看出線程與進程的對應關系---lsof -p 進程號---查看到對應的文件為數據庫表結構文件---查看數據庫數據文件show global variables like "%datadir%";---排除數據庫儲存文件位置不一樣的問題---進入數據庫查看進程show full processlist;---確認具體執行的慢語句---explain 執行的語句---查看具體sql語句是什么問題---沒有走索引---show create table 表---查看創表語句---定位到問題---范圍查詢導致慢查詢

注:echo 1>/proc/sys/vm/drop_caches表示釋放pagecache,也就是文件緩存,而mysql讀書的數據就是文件緩存,dataservice不停的釋放文件緩存,就導致MySQL都無法利用磁盤緩存

=================================================================================
案例四:數據庫redis io問題案例
top---iostat -d -x 1---pidstat -d 1---strace/lsof--nsenter
安裝nsenter命令:
docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
nsenter命令可以指定進程執行命令:
容器中使用nsenter命令:
# 由於這兩個容器共享同一個網絡命名空間,所以我們只需要進入 app 的網絡命名空間即可
$ PID=$(docker inspect --format {{.State.Pid}} app)
# -i 表示顯示網絡套接字信息
$ nsenter --target $PID --net -- lsof -i

docker環境設置redis配置:
docker exec -it redis redis-cli config set appendfsync everysec

=================================================================================
磁盤的性能指標:
容量、使用量、剩余量、索引節點
頁緩存、目錄項緩存、索引節點緩存以及各文件系統緩存、
IOPS(包括 r/s 和 w/s)、響應時間(延遲)以及吞吐量(B/s)等

******性能工具分析總結:
第一,在文件系統的原理中,我介紹了查看文件系統容量的工具 df。它既可以查看文件系統數據的空間容量,也可以查看索引節點的容量。至於文件系統緩存,我們通過 /proc/meminfo、/proc/slabinfo 以及 slabtop 等各種來源,觀察頁緩存、目錄項緩存、索引節點緩存以及具體文件系統的緩存情況。

第二,在磁盤 I/O 的原理中,我們分別用 iostat 和 pidstat 觀察了磁盤和進程的 I/O 情況。它們都是最常用的 I/O 性能分析工具。通過 iostat ,我們可以得到磁盤的 I/O 使用率、吞吐量、響應時間以及 IOPS 等性能指標;而通過 pidstat ,則可以觀察到進程的 I/O 吞吐量以及塊設備 I/O 的延遲等。

第三,在狂打日志的案例中,我們先用 top 查看系統的 CPU 使用情況,發現 iowait 比較高;然后,又用 iostat 發現了磁盤的 I/O 使用率瓶頸,並用 pidstat 找出了大量 I/O 的進程;最后,通過 strace 和 lsof,我們找出了問題進程正在讀寫的文件,並最終鎖定性能問題的來源——原來是進程在狂打日志。

第四,在磁盤 I/O 延遲的單詞熱度案例中,我們同樣先用 top、iostat ,發現磁盤有 I/O 瓶頸,並用 pidstat 找出了大量 I/O 的進程。可接下來,想要照搬上次操作的我們失敗了。在隨后的 strace 命令中,我們居然沒看到 write 系統調用。於是,我們換了一個思路,用新工具 filetop 和 opensnoop ,從內核中跟蹤系統調用,最終找出瓶頸的來源。

最后,在 MySQL 和 Redis 的案例中,同樣的思路,我們先用 top、iostat 以及 pidstat ,確定並找出 I/O 性能問題的瓶頸來源,它們正是 mysqld 和 redis-server。隨后,我們又用 strace+lsof 找出了它們正在讀寫的文件。

==================================================================================
*****文件系統和磁盤io分析方式:
1.先用 iostat 發現磁盤 I/O 性能瓶頸;

2.再借助 pidstat ,定位出導致瓶頸的進程;

3.隨后分析進程的 I/O 行為;

4.最后,結合應用程序的原理,分析這些 I/O 的來源。

==================================================================================
***fio命令對磁盤的測試:
# 隨機讀
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 隨機寫
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 順序讀
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 順序寫
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

***參數:
direct,表示是否跳過系統緩存。上面示例中,我設置的 1 ,就表示跳過系統緩存。

iodepth,表示使用異步 I/O(asynchronous I/O,簡稱 AIO)時,同時發出的 I/O 請求上限。在上面的示例中,我設置的是 64。

rw,表示 I/O 模式。我的示例中, read/write 分別表示順序讀 / 寫,而 randread/randwrite 則分別表示隨機讀 / 寫。

ioengine,表示 I/O 引擎,它支持同步(sync)、異步(libaio)、內存映射(mmap)、網絡(net)等各種 I/O 引擎。上面示例中,我設置的 libaio 表示使用異步 I/O。

bs,表示 I/O 的大小。示例中,我設置成了 4K(這也是默認值)。

filename,表示文件路徑,當然,它可以是磁盤路徑(測試磁盤性能),也可以是文件路徑(測試文件系統性能)。示例中,我把它設置成了磁盤 /dev/sdb。不過注意,用磁盤路徑測試寫,會破壞這個磁盤中的文件系統,所以在使用前,你一定要事先做好數據備份。

報告指標:
slat ,是指從 I/O 提交到實際執行 I/O 的時長(Submission latency);

clat ,是指從 I/O 提交到 I/O 完成的時長(Completion latency);

而 lat ,指的是從 fio 創建 I/O 到 I/O 完成的總時長。

======================================================================================
*****blktrace命令記錄磁盤的io訪問情況在通過fio重放:
# 使用 blktrace 跟蹤磁盤 I/O,注意指定應用程序正在操作的磁盤
$ blktrace /dev/sdb

# 查看 blktrace 記錄的結果
# ls
sdb.blktrace.0 sdb.blktrace.1

# 將結果轉化為二進制文件
$ blkparse sdb -d sdb.bin

# 使用 fio 重放日志
$ fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.bin

這樣,我們就通過 blktrace+fio 的組合使用,得到了應用程序 I/O 模式的基准測試報告

=====================================================================================
******應用程序io性能優化:
第一,可以用追加寫代替隨機寫,減少尋址開銷,加快 I/O 寫的速度。

第二,可以借助緩存 I/O ,充分利用系統緩存,降低實際 I/O 的次數。

第三,可以在應用程序內部構建自己的緩存,或者用 Redis 這類外部緩存系統。這樣,一方面,能在應用程序內部,控制緩存的數據和生命周期;另一方面,也能降低其他應用程序使用緩存對自身的影響。

第四,在需要頻繁讀寫同一塊磁盤空間時,可以用 mmap 代替 read/write,減少內存的拷貝次數。

第五,在需要同步寫的場景中,盡量將寫請求合並,而不是讓每個請求都同步寫入磁盤,即可以用 fsync() 取代 O_SYNC。

第六,在多個應用程序共享相同磁盤時,為了保證 I/O 不被某個應用完全占用,推薦你使用 cgroups 的 I/O 子系統,來限制進程 / 進程組的 IOPS 以及吞吐量。

最后,在使用 CFQ 調度器時,可以用 ionice 來調整進程的 I/O 調度優先級,特別是提高核心應用的 I/O 優先級。ionice 支持三個優先級類:Idle、Best-effort 和 Realtime。其中, Best-effort 和 Realtime 還分別支持 0-7 的級別,數值越小,則表示優先級別越高。

=====================================================================================
******文件系統優化:
第一,你可以根據實際負載場景的不同,選擇最適合的文件系統。比如 Ubuntu 默認使用 ext4 文件系統,而 CentOS 7 默認使用 xfs 文件系統。

相比於 ext4 ,xfs 支持更大的磁盤分區和更大的文件數量,如 xfs 支持大於 16TB 的磁盤。但是 xfs 文件系統的缺點在於無法收縮,而 ext4 則可以。

第二,在選好文件系統后,還可以進一步優化文件系統的配置選項,包括文件系統的特性(如 ext_attr、dir_index)、日志模式(如 journal、ordered、writeback)、掛載選項(如 noatime)等等。

比如, 使用 tune2fs 這個工具,可以調整文件系統的特性(tune2fs 也常用來查看文件系統超級塊的內容)。 而通過 /etc/fstab ,或者 mount 命令行參數,我們可以調整文件系統的日志模式和掛載選項等。

第三,可以優化文件系統的緩存。

比如,你可以優化 pdflush 臟頁的刷新頻率(比如設置 dirty_expire_centisecs 和 dirty_writeback_centisecs)以及臟頁的限額(比如調整 dirty_background_ratio 和 dirty_ratio 等)。

再如,你還可以優化內核回收目錄項緩存和索引節點緩存的傾向,即調整 vfs_cache_pressure(/proc/sys/vm/vfs_cache_pressure,默認值 100),數值越大,就表示越容易回收。

最后,在不需要持久化時,你還可以用內存文件系統 tmpfs,以獲得更好的 I/O 性能 。tmpfs 把數據直接保存在內存中,而不是磁盤中。比如 /dev/shm/ ,就是大多數 Linux 默認配置的一個內存文件系統,它的大小默認為總內存的一半。

=======================================================================================
磁盤優化:
第一,最簡單有效的優化方法,就是換用性能更好的磁盤,比如用 SSD 替代 HDD。

第二,我們可以使用 RAID ,把多塊磁盤組合成一個邏輯磁盤,構成冗余獨立磁盤陣列。這樣做既可以提高數據的可靠性,又可以提升數據的訪問性能。

第三,針對磁盤和應用程序 I/O 模式的特征,我們可以選擇最適合的 I/O 調度算法。比方說,SSD 和虛擬機中的磁盤,通常用的是 noop 調度算法。而數據庫應用,我更推薦使用 deadline 算法。

第四,我們可以對應用程序的數據,進行磁盤級別的隔離。比如,我們可以為日志、數據庫等 I/O 壓力比較重的應用,配置單獨的磁盤。

第五,在順序讀比較多的場景中,我們可以增大磁盤的預讀數據,比如,你可以通過下面兩種方法,調整 /dev/sdb 的預讀大小。

調整內核選項 /sys/block/sdb/queue/read_ahead_kb,默認大小是 128 KB,單位為 KB。

使用 blockdev 工具設置,比如 blockdev --setra 8192 /dev/sdb,注意這里的單位是 512B(0.5KB),所以它的數值總是 read_ahead_kb 的兩倍。

第六,我們可以優化內核塊設備 I/O 的選項。比如,可以調整磁盤隊列的長度 /sys/block/sdb/queue/nr_requests,適當增大隊列長度,可以提升磁盤的吞吐量(當然也會導致 I/O 延遲增大)。

最后,要注意,磁盤本身出現硬件錯誤,也會導致 I/O 性能急劇下降,所以發現磁盤性能急劇下降時,你還需要確認,磁盤本身是不是出現了硬件錯誤。

比如,你可以查看 dmesg 中是否有硬件 I/O 故障的日志。 還可以使用 badblocks、smartctl 等工具,檢測磁盤的硬件問題,或用 e2fsck 等來檢測文件系統的錯誤。如果發現問題,你可以使用 fsck 等工具來修復。


=====================================================================================
阻塞、非阻塞 I/O 與同步、異步 I/O 的區別:
阻塞 / 非阻塞和同步 / 異步,其實就是兩個不同角度的 I/O 划分方式。它們描述的對象也不同,阻塞 / 非阻塞針對的是 I/O 調用者(即應用程序),而同步 / 異步針對的是 I/O 執行者(即系統)。

當應用程序請求系統調用時,系統調用完就結束了,處理其他事務去了,而程序要阻塞在哪等待返回結果。對於應用程序來說就是阻塞io,對於系統調用來說就是異步io

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM