硬盤性能的幾大誤解- 從共識算法開談
三週前,我開源了自己寫的共識庫Dragonboat ,在反饋裡發現一些用戶對硬盤性能有不少基礎性誤解,但仔細想來這些坑自己一樣踏過。本文從一個軟件工程師角度,分享一路走來踏過的幾個硬盤性能誤解,方便大家繞坑而行。
SATA 對NVME
故事首先是從使用Google雲提供的本地NVME盤開始的。“本地NVME盤“,顧名思義,應該是高性能的吧?它IOPS數據靚麗,帶著Google招牌的光環,一定不會水啊。跑了一下Dragonboat的跑分模式,得分慘不忍堵,NVME盤跑出的性能比7年前的SATA SSD都爛。
諸如共識算法,各類以及各類需要WAL的軟件都需要確保數據確實被保存到硬盤上了,確保比如掉電重啟後,數據依舊完好可用。fsync()就是起到這個作用,它確保操作系統緩存內的寫數據以及磁盤上緩存的寫數據,被確實保存能挺過掉電重啟。數據庫裡一個寫數據的transaction和共識算法裡一個Proposal的完成,都需要確保數據已落盤,共識算法更需要數據在多數機器上完成落盤。fsync()的延遲性能對上述系統的吞吐均有最直接影響。Google雲本地NVME盤的蝸牛速度,是不是fsync()特別慢引起的呢?
祖傳工具pg_test_fsync該登場了。
正確測試fsync()相關的各項性能,一大圈工具使用下來加上自己擼的,發現還是PostgreSQL數據庫自帶的這個pg_test_fsync工具最直觀好用。下圖是pg_test_fsync在Google雲提供的本地NVME盤的跑分結果,Google雲本地NVME盤的靚麗IOPS數據下,fsync()每次近需要4.4毫秒,和高速的機械盤一個量級。其他用戶也發現了這一奇葩問題。
作為對比,Intel S3700/S3710,Intel 320和鎂光500DC等等常見SATA固態硬盤的測試結果顯示它們的fsync()延遲是0.15-0.2毫秒左右,比Goole雲本地NVME盤足足低幾十倍。Intel S3700的pg_test_fsync結果是這樣的:
而NVME的Intel P3700的結果如下,差別是客觀的,但並不是上述那種幾十倍的差距:
以共識算法來說,其理論延遲極限是一次fsync()的延遲加上一次網絡RTT延遲。簡單計算可知,上述Google雲的NVME的fsync()延遲決定了其單client的共識吞吐不可能超過每秒230次,而如果換用SATA的S3700,得益於其0.2毫秒的fsync(),單client共識吞吐理論上限即刻提升為5000次。SATA的S3700秒殺Google雲上的奇葩NVME盤。
容量、吞吐、IOPS數甚至壽命都可以通過多盤來堆疊,而這個fsync()延遲,沒有任何取巧近路。上述NVME和SATA的對比可見NVME與否並不是最核心的關鍵因素。SATA與NVME的差異,是幾十微秒量級的,而具體差異產生的原因,網絡上的介紹文章鋪天蓋地,這裡不復述。上述NVME比SATA慢幾十倍的實例,客觀顯示真正性能差異不在SATA/NVME這一點。
消費級對企業級SSD盤
另一常見大坑就是在、測試環境上使用消費級SSD,比如三星的NVME M.2固態硬盤價低量足,IOPS數據比肩企業級產品,在非生產環境使用,初一聽似乎有一定道理。Dragonboat開發之初,就曾傻傻的拿這樣的家用NVME盤去跑測試,結果各種龜速各種悲劇。其實,這種誤解用FreeBSD開發人員貼出的數據來對比說明最直接。同樣是寫盤以後fsync()落盤,比較的是古董級的Intel 710企業級SATA硬盤和高端家用級的Samsung 950 PRO這款NVME盤,家用級是絕對不應該用的,哪怕是開發測試環境:
上述第三方數據也再次驗證SATA/NVME的差異不是核心關鍵,NVME的家用盤的落盤寫延遲是古董級Intel 710這款SATA盤的11倍,完全絕對不適用於共識算法、數據庫等領域。如果開發測試環境單機吞吐是生產環境的1/10,而這樣的差異僅僅是為了幾百人民幣的固態盤差價,顯然是很得不償失的。
具有掉電保護的緩存
傳統的企業級硬盤都帶有掉電保護功能,初聽起來是一個為數據完整性設計的東西,目的是讓硬盤在掉電的時候不丟失其緩存內尚未寫入到磁盤的數據。其實有無掉電保護下的緩存恰恰正是上述fsync()性能巨大差異的原因。
Intel P3700拆開後,卡的正面左上角用於掉電保護兩顆突起的電容清晰可見
在具有掉電保護企業盤裡,當fsync()的時候,數據只要成功寫入SSD卡上的內存緩存裡就可以回复主機報告落盤完成,因為即使系統突然掉電,電容內的電量足夠確保維持供電直到緩存內的數據安全落盤寫入NAND。而不具備掉電保護的奇葩級企業盤,比如上述Google雲的本地NVME盤,以及NVME的Samsung 950 PRO這款家用盤,每次均必須把數據實打實寫到NAND存儲芯片裡。寫NAND的物理延遲就是平均毫秒級別的,這和SATA與NVME均無關。
下圖是AnandTech對幾種常見NAND芯片性能的比較。以Intel P3700為例,它是最典型MLC NAND的固態盤,所用的NAND的寫延遲就是1ms,之所以可以在100微秒內完成落盤,就是因為數據是被在掉電保護機構配合下可靠寫入緩存,而非寫入了MLC NAND。
此處的一大坑就是過度片面追求SLC/MLC/TLC這類NAND類型帶來的性能差異,最好服務器都用SLC/MLC顆粒。這首先不是產品趨勢,其次上述的分析已經清楚展示了最直接的吞吐相關的因素是掉電保護系統,恰恰就是通過它完全規避了NAND寫延遲,才有良好的落盤寫性能。NAND類型真的不必苛求,選大廠比如Intel的企業盤,確保掉電保護的完好性自檢沒有問題,選寫入壽命扛得住的,這才是關鍵。
Intel傲騰
Optane從原理上避免了對基於內存的緩存的需求,沒有了這個內存緩存,自然就不需要掉電保護這一東西。它讀寫延遲均更低,不用緩存不用掉電保護,落盤寫就是在20-30微秒。它除了價格貴,包括壽命在那的各項指標沒有一樣不出彩的。特別指出這一最新發展,但不做具體展開。
共識算法不需要大量的高速低fsync()延遲存儲空間
成熟的共識算法庫以及數據庫系統,一般均支持指定一個WAL存儲位置,將它指向Optane或者帶掉電保護的低fsync()延遲的固態盤,對系統性能幫助極大。此類WAL數據一般不大,在不少測試過的場景一般100G左右就足夠,這也正是Intel P4801X這樣固態盤只有100G大的原因。切勿錯誤理解為用了共識算法那所有數據都必須放低落盤寫延遲的固態盤上。
結論
- 落盤寫延遲是共識算法、數據庫等應用最核心硬盤指標
- SATA和NVME的落盤寫延遲差異,遠小於掉電保護的有無帶來的延遲差異
- 家用級與企業級的最根本區別在於是否具有掉電保護,以及掉電保護帶來的落盤寫延遲差異
- PostgreSQL自帶的_pg_test_fsync_工具能方便檢測落盤寫性能,200微秒以上的固態盤建議直接走報廢流程或調換至於共識算法、數據庫不相關領域。
最後,您試用Dragonboat這款開源共識庫了嗎?歡迎試用,並點Star支持!