作為一個分布式數(shù)據(jù)系統(tǒng)的開發(fā)者,對硬件需要有一些基本的常識胖喳。對這些東西的了解程度泡躯,決定了你能在多大程度上預(yù)測系統(tǒng)的整體性能,而這屬于一個架構(gòu)師最核心的能力丽焊。今天我們來談一談硬盤较剃,這個數(shù)據(jù)庫系統(tǒng)最底層的元件的一些基本概念,以及如何評估它的性能技健。
1. 硬盤類型
硬盤的類型主要分為兩類写穴,SSD(固態(tài)硬盤)和 HDD(機(jī)械硬盤)。很多現(xiàn)代數(shù)據(jù)庫對 SSD 都有很好的優(yōu)化雌贱,在絕大多數(shù)情況下啊送,一個需要考慮隨機(jī)訪問的系統(tǒng),使用 SSD 是最好的選擇欣孤。只有在使用類似 Kafka 這樣的馋没,純順序讀寫的系統(tǒng)時,我們才優(yōu)先選擇單價更低的 HDD导街。
1.1 機(jī)械硬盤
傳統(tǒng)磁盤本質(zhì)上一種機(jī)械裝置披泪,如FC, SAS, SATA磁盤痢站,轉(zhuǎn)速通常為5400/7200/10K/15K rpm不等蚂四。影響磁盤的關(guān)鍵因素是磁盤服務(wù)時間,即磁盤完成一個I/O請求所花費(fèi)的時間枷颊,它由尋道時間泽论、旋轉(zhuǎn)延遲和數(shù)據(jù)傳輸時間三部分構(gòu)成艾少。
尋道時間
尋道時間 (Tseek) 是指將讀寫磁頭移動至正確的磁道上所需要的時間。尋道時間越短翼悴,I/O操作越快缚够,目前磁盤的平均尋道時間一般在3-15ms幔妨。
旋轉(zhuǎn)延遲
旋轉(zhuǎn)延遲 (Trotation) 是指盤片旋轉(zhuǎn)將請求數(shù)據(jù)所在扇區(qū)移至讀寫磁頭下方所需要的時間。顯然谍椅,這是一個只有機(jī)械硬盤才有的參數(shù)误堡。旋轉(zhuǎn)延遲取決于磁盤轉(zhuǎn)速,通常使用磁盤旋轉(zhuǎn)一周所需時間的1/2表示雏吭。比如锁施,7200 rpm的磁盤平均旋轉(zhuǎn)延遲大約為60*1000/7200/2 = 4.17ms,而轉(zhuǎn)速為15000 rpm的磁盤其平均旋轉(zhuǎn)延遲為2ms杖们。
數(shù)據(jù)傳輸時間
數(shù)據(jù)傳輸時間(Ttransfer)是指完成傳輸所請求的數(shù)據(jù)所需要的時間悉抵,它取決于數(shù)據(jù)傳輸率,其值等于數(shù)據(jù)大小除以數(shù)據(jù)傳輸率摘完。 IDE/ATA 理論上能達(dá)到133MB/s姥饰,SATA II 可達(dá)到300MB/s的接口數(shù)據(jù)傳輸率。在實(shí)際的數(shù)據(jù)庫 transaction 中孝治,數(shù)據(jù)傳輸時間往往遠(yuǎn)小于前兩部分消耗時間列粪。
一些簡單計算
上面的幾個數(shù)字,并不是互相獨(dú)立的荆秦。首先篱竭,尋道時間和轉(zhuǎn)速的關(guān)系非常密切力图。磁盤是旋轉(zhuǎn)的步绸,讀寫頭是固定的。當(dāng)我們需要讀寫磁盤某個扇區(qū)某個磁道的數(shù)據(jù)吃媒,我們需要把對應(yīng)的扇區(qū)轉(zhuǎn)到讀寫頭處瓤介。平均來說,這個過程就是磁盤轉(zhuǎn)半圈所需的時間赘那,這個時間就是旋轉(zhuǎn)延遲時間刑桑。比如,7200 rpm的磁盤平均旋轉(zhuǎn)延遲大約為60*1000/7200/2 = 4.17ms募舟。
常見硬盤的旋轉(zhuǎn)延遲時間為:
- 7200 rpm的磁盤平均旋轉(zhuǎn)延遲大約為60*1000/7200/2 = 4.17ms
- 10000 rpm的磁盤平均旋轉(zhuǎn)延遲大約為60*1000/10000/2 = 3ms祠斧,
- 15000 rpm的磁盤其平均旋轉(zhuǎn)延遲約為60*1000/15000/2 = 2ms。
而尋找數(shù)據(jù)的過程拱礁,除了磁盤的轉(zhuǎn)動琢锋,磁頭也需要在軸上進(jìn)行平移,這兩個時間綜合起來呢灶,就是尋道時間吴超。這個時間和磁頭移動速度,磁碟的存儲密度都有關(guān)系鸯乃。我們可以對比上文的旋轉(zhuǎn)延遲和下面的常見磁盤平均物理尋道時間鲸阻,從而得到一個感性的認(rèn)識:
- 7200轉(zhuǎn)/分的STAT硬盤平均物理尋道時間是9ms
- 10000轉(zhuǎn)/分的STAT硬盤平均物理尋道時間是6ms
- 15000轉(zhuǎn)/分的SAS硬盤平均物理尋道時間是4ms
通過上面的數(shù)據(jù),我們還可以計算理論的 IOPS 數(shù)據(jù)(IO per second,每秒訪問次數(shù)): IOPS = 1000 ms/ (尋道時間 + 旋轉(zhuǎn)延遲)鸟悴,可以忽略數(shù)據(jù)傳輸時間陈辱。
- 7200 rpm的磁盤IOPS = 1000 / (9 + 4.17) = 76 IOPS
- 10000 rpm的磁盤IOPS = 1000 / (6+ 3) = 111 IOPS
- 15000 rpm的磁盤IOPS = 1000 / (4 + 2) = 166 IOPS
這個指標(biāo),反映了磁盤處理隨機(jī)讀寫請求的能力细诸,對于大多數(shù)數(shù)據(jù)庫系統(tǒng)來說性置,這是一個至關(guān)重要的參數(shù)。
1.2 固態(tài)硬盤
SSD(solid state drive)本質(zhì)上和 U盤比較類似揍堰,它沒有活動的機(jī)械部件鹏浅,靠的是一塊塊的閃存顆粒來存儲數(shù)據(jù)。由于這些閃存彼此之間并無干擾屏歹,因此可以以類似 RAID0 的方式來提高訪問速度隐砸。它的讀寫尋址不涉及磁頭移動和磁盤轉(zhuǎn)動,因此可以提供很高的 IOPS蝙眶。
下面是根據(jù)我的經(jīng)驗季希,一些常見的 SSD 系統(tǒng)的性能指標(biāo):
- 讀 IOPS: 大概在 2,3w到10w 不等幽纷。
- 寫 IOPS: 從幾千到幾萬不等式塌,一般要低于讀的 IOPS。
- 吞吐量:我用過的比較老的機(jī)器友浸,通常讀吞吐量在 200-400多 MB/s峰尝,寫吞吐量在100-200 MB/s 之間。比較新的系統(tǒng)上收恢,讀寫吞吐量能達(dá)到 1000/900 MB/s
- IO latency:各大云服務(wù)商提供的 SSD 云盤武学,大概是 300 μs 左右。我自己使用過的公司機(jī)房服務(wù)器伦意,有些比較老的會低一點(diǎn)火窒,總體大概在1.6ms 到300μs 間浮動。較新的 SSD驮肉,比如 MacBook Pro 上面熏矿,這個指標(biāo)能到 20μs 左右。
需要注意的是离钝,很多云服務(wù)商票编,如 Amazon,AliYun奈辰,它們提供的 SSD 的 IOPS 是和容量掛鉤的栏妖。這個也很好理解,因為大容量的 SSD 背后是更多的 NAND Flash奖恰,相當(dāng)于更多的磁盤組成了 Raid0吊趾,速度自然更快宛裕。
2 測試工具和方法
硬盤的測試工具有很多,我們一般推薦用的是兩個工具:ioping 和 fio论泛。也有不少其他的工具可以選用揩尸,如 dd,hdparm 等屁奏,但這些工具或多或少都存在著問題岩榆。
以 dd 為例,它只能測單線程坟瓢,順序?qū)懙男阅苡卤撸抑荒軠y少量數(shù)據(jù),這就使得它的結(jié)果會被緩存影響折联。hdparm 這個老古董只能用在 ATA 硬盤上粒褒,現(xiàn)在基本上也被淘汰了。因此我們主要介紹 ioping 和 fio诚镰。
2.1 fio
fio 是個比較現(xiàn)代化的測試工具奕坟,可以利用多線程/多進(jìn)程來進(jìn)行并發(fā) IO 測試,支持混合讀寫清笨,支持自定義載荷的大小月杉。
在 Ubuntu 下面,可以用 apt-get 來安裝這個工具:
sudo apt-get install libaio1
sudo apt-get install libaio-dev
fio 的命令行用法如下:
$ fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=randwrite -size=4G -filename=/dev/vdb -name="EBS 4K randwrite test" -iodepth=64 -runtime=60
$fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=randread -size=4G -filename=/ssd/test -name="EBS 4K randwrite test" -iodepth=64 -runtime=60
$fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=randrw –rwmixread=75-size=4G -filename=/ssd/test -name="EBS 4K randwrite test" -iodepth=64 -runtime=60
上面的三條命令抠艾,是使用4k 的塊大小苛萎,4g 的文件大小,多線程模式跌帐,io 隊列深度64首懈,分別測試隨機(jī)讀,隨機(jī)寫谨敛,以及讀寫混合(讀占75%,寫占25%)的性能滤否。
下面是 fio 的主要參數(shù):
- ioengine: IO引擎脸狸,我們一般使用libaio,發(fā)起異步IO請求藐俺,MacOS 下用 posixaio炊甲。
- bs: IO大小
- direct: 直寫,繞過操作系統(tǒng)Cache欲芹。因為我們測試的是硬盤卿啡,而不是操作系統(tǒng)的Cache,所以設(shè)置為1菱父。
- rw: 讀寫模式颈娜,有順序?qū)憌rite剑逃、順序讀read、隨機(jī)寫randwrite官辽、隨機(jī)讀randread等蛹磺。
- size: 表示測試數(shù)據(jù)的大小
- filename: 測試對象
- iodepth: 隊列深度,只有使用libaio時才有意義同仆。這是一個可以影響IOPS的參數(shù)萤捆。在測試時,隊列深度為1是主要指標(biāo)俗批,大多數(shù)時候都參考1就可以俗或。實(shí)際運(yùn)行時隊列深度也一般不會超過4。
- runtime: 測試時長
- randrepeat:以同一個 rand seed 來產(chǎn)生隨機(jī)數(shù)岁忘,使多次運(yùn)行的結(jié)果更加一致
- rwmixread:如果用讀寫混合模式測試的話蕴侣,該參數(shù)指定混合中讀的百分比,一般設(shè)為75
fio 是主流磁盤測試工具中最簡明好用的一個臭觉,強(qiáng)烈推薦昆雀。
2.2 ioping
ioping 這個工具主要用來測試 io 的 latency。使用方法如下:
# 測延遲
ioping -c 100 /dev/sdc1
# 測尋道速度蝠筑,這個命令能夠更好的反映硬件性能狞膘,不受 ioengine 的影響
ioping -R /dev/sdc1
# 測順序讀的速度,這個能夠反映吞吐量大小
ioping -RL /dev/rdisk1
ioping 主要參數(shù)如下:
- -A use asynchronous I/O
- -C use cached I/O (no cache flush/drop)
- -D use direct I/O (O_DIRECT)
- -W 測寫性能
- -G 測讀寫 ping pong
- -Y 使用 O_SYNC 模式
- -y 使用 O_DSYNC 模式
這些參數(shù)在某些時候會較大的影響測試結(jié)果什乙。比如我們公司的一臺機(jī)器上挽封,打開 direct IO 會導(dǎo)致順序讀的速度從 350mb/s -> 450 mb/s。 但是 ioping 最主要的用途臣镣,還是測試 io 延遲辅愿。
2.3 dstat
傳統(tǒng)上在磁盤使用過程中,我們可以用 iostat 來監(jiān)控磁盤使用情況忆某。但 iostat 很多人不明白怎么用点待,常見錯誤用法,是直接跑: iostat 10
弃舒,這個命令返回的結(jié)果第一條癞埠,是從開機(jī)以來的總體統(tǒng)計結(jié)果,如果你在運(yùn)行一些 heavy task聋呢,這個結(jié)果會讓你非常驚訝苗踪。你可以用 -y
參數(shù)來忽略這條輸出,但更好的辦法削锰,則是換用 dstat 這樣的工具通铲,如圖。
命令行:
# 指定監(jiān)控 sdb 和 sdc 兩個塊設(shè)備
dstat -D sdb,sdc
參考文獻(xiàn)
- https://wiki.mikejung.biz/Benchmarking#How_to_break_in_SSDs_before_benchmarking
- https://www.linux.com/learn/tutorials/442451-inspecting-disk-io-performance-with-fio
- https://www.binarylane.com.au/support/solutions/articles/1000055889-how-to-benchmark-disk-i-o
- https://linux.die.net/man/1/fio
- https://malcont.net/2017/07/apfs-and-hfsplus-benchmarks-on-2017-macbook-pro-with-macos-high-sierra/
- https://bartsjerps.wordpress.com/2011/03/04/io-bottleneck-linux/