性能分析小案例系列,能夠經過下面連接查看哦html
https://www.cnblogs.com/poloyy/category/1814570.htmllinux
前面有學到 Buffer 和 Cache 的概念:https://www.cnblogs.com/poloyy/p/13503848.htmlgit
咱們來簡單複習下github
爲了提高系統的 I/O 性能,它們利用內存,充當起慢速磁盤和快速 CPU 之間的橋樑,能夠加速 I/O 的訪問速度golang
既然 Buffer 和 Cache 對系統性能有很大影響,那咱們在軟件開發的過程當中,能不能利用這 一點,來優化 I/O 性能,提高應用程序的運行效率呢? 答案天然是確定的docker
咱們想利用緩存來提高程序的運行效率,應該怎麼評估這個效果呢?換句話說,有沒有哪一個指標能夠衡量緩存使用的好壞呢?ubuntu
獨立的緩存模塊一般會提供查詢接口,方便咱們隨時查看緩存的命中狀況vim
不過 Linux 系統中並無直接提供這些接口,因此這裏要介紹一下,cachestat 和 cachetop ,它們正是查看系統緩存命中狀況的工具緩存
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD echo "deb https://repo.iovisor.org/apt/xenial xenial main" | sudo tee /etc/apt/sources.list.d/iovisor.list sudo apt-get update sudo apt-get install -y bcc-tools libbcc-examples linux-headers-$(uname -r)
vim /etc/profile # 在文件結尾處添加 export PATH=$PATH:/usr/share/bcc/tools # 保存文件後 source /etc/profile
# 它以 1 秒的時間間隔,輸出了 3 組緩存統計數據 cachestat 1 3
cachetop
可使用 pcstat 這個工具,來查看文件在內存中的緩存大小以及緩存比例併發
# 安裝 go apt install golang-go vim /etc/profile # 在文件結尾處添加 export GOPATH=~/go export PATH=~/go/bin:$PATH # 保存文件後 source /etc/profile go get golang.org/x/sys/unix go get github.com/tobert/pcstat/pcstat
pcstat /bin/ls
Cached 就是 /bin/ls 在緩存中的大小,而 Percent 則是緩存的百分比,看到它們都是 0,這說明 /bin/ls 並不在緩存中
執行 ls 命令,再來查看
ls pcstat /bin/ls
發現都在緩存中了
注意:沒說第幾個終端都是默認第一個終端執行命令哦
# 生成一個 512MB 的臨時文件 dd if=/dev/sda1 of=file bs=1M count=512 # 清理緩存 echo 3 > /proc/sys/vm/drop_caches
pcstat file
確認剛剛生成的文件不在緩存中。若是一切正常, 會看到 Cached 和 Percent 都是 0
# 每隔 1 秒刷新一次數據 cachetop 1
dd if=file of=/dev/null bs=1M
能夠看到 dd 命令並非全部的讀都落到了磁盤上,讀請求的緩存命中率只有 50%
dd if=file of=/dev/null bs=1M
磁盤的讀性能蹭蹭蹭往上漲,去到了 1.6GB/s
能夠發現,此次讀的緩存命中率是 100%
pcstat file
測試文件已經被所有緩存起來了,和剛剛 cachetop 觀察到緩存命中率 100% 是一致的
這兩次結果說明,系統緩存對第二次 dd 操做有明顯的加速效果,能夠大大提升文件讀取的性能。
從這裏能夠看到,每讀取 32 MB 的數據,就須要花 0.9 秒
這個時間合理嗎?這也太慢了吧,那這是否是沒用系統緩存致使的呢?
讀的命中率雖然是 100%,命中次數是 1024,看起來所有的讀請求都通過了系統緩存
全都是緩存 I/O,讀取速度不該該這麼慢
這個案例估計沒有充分利用系統緩存,若是系統調用設置直接 I/O 的標誌,就能夠繞過系統緩存
strace -p $(pgrep app)
它果真用了直接 I/O
刪除 O_DIRECT 選項,讓應用程序使用緩存 I/O ,而不是直接 I/O,就能夠加速磁盤讀取速度
查看新應用的日誌
如今,每次只須要 0.03 秒,就能夠讀取 32MB 數據,明顯比以前的 0.9 秒快多了。因此,此次應該用了系統緩存
爲何優化前,經過 cachetop 只能看到不多一部分數據的所有命中,而沒有觀察到大量數據的未命中狀況呢?
是由於,cachetop 工具並不把直接 I/O 算進來