Categories
程式開發

2010 年代的分佈式系統:硬件的進化


上篇文章我們聊了軟件構建方式和演化,今天我們來聊聊硬件吧!

SSD 普及的深遠影響

如果說云的出現是一種商業模式的變化的話,驅動這個商業革命的推手就是最近十年硬件的快速更新。比起 CPU,存儲和網絡設備的進化速度更加迅速。最近五年,SSD 的價格 (包括 PCIe 接口) 的成本持續下降,批量採購的話已經幾乎達到和 HDD 接近的價格。

2010 年代的分佈式系統:硬件的進化 1

(圖 1:近 5 年 SSD 成本曲線)

SSD 的普及,對於存儲軟件廠商的影響是深遠的。

其一,是極大地緩解了 IO 瓶頸。對於數據庫廠商來說,可以將更多的精力花在其他事情,而不是優化存儲引擎上。最近兩年發生了一些更大的變化, NVMe 正在成為主流,我們很早就在Intel Optane 進行實驗和投資,類似這樣的非易失內存的技術,正在模糊內存和存儲的界限,但是同時對開發者帶來挑戰也是存在的。舉一個簡單的例子,對於Optane 這類的非易失內存,如果你希望能夠完全利用它的性能優勢,最好使用類似PMDK 這類基於Page cache Bypass 的SDK 針對你的程序進行開發,這類SDK的核心思想是將NVM 設備真正地當做內存使用。如果僅僅將 Optane 掛載成本地磁盤使用,其實很大程度上的瓶頸不一定出現在硬件本身的 IO 上。

下面這張圖很有意思,來自Intel 對於Optane 的測試,我們可以看見在中間那一列,Storage with Optane SSD,隨機讀取的硬件延遲已經接近操作系統和文件系統帶來的延遲,甚至Linux VFS 本身會變成CPU 瓶頸。其實背後的原因也很簡單,過去由於VFS 本身在CPU 上的開銷(比如鎖)相比過去的IO 來說太小了,但是現在這些新硬件本身的IO 延遲已經低到讓文件系統本身開銷的比例不容忽視了。

2010 年代的分佈式系統:硬件的進化 2

(圖 2:Intel 對於 Optane 的測試)

其二,這個變化影響了操作系統和文件系統本身。例如針對 Persistent Memory 設計新的文件系統,其中來自 UCSD 的 NVSL 實驗室 (名字很厲害, Non-Volatile Systems Laboratory) 的 NovaFS 就是一個很好的例子。簡單來說是大量使用了無鎖數據結構,減低 CPU 開銷,NovaFS 的代碼量很小很好讀,有興趣可以看看。另外 Intel 對 Persistent Memory 編程模型有很好的一篇文章,感興趣的話可以從這裡開始了解這些新變化。

內核開銷的挑戰

說完了存儲設備,我們聊聊網絡設備。我還記得我第一份工作的數據中心裡甚至還有百兆的網卡,但現在,1GbE 已經都快淘汰光了,主流的數據中心基本上開始提供 10GbE 甚至 25GbE 的網絡。為什麼會變成這樣?我們做一個簡單的算術題就知道了。根據 Cisco 的文檔介紹, 一塊千兆網卡的吞吐大概是: (1,000,000,000 b/s / (84 B * 8 b/B)) == 1,488,096 f/s (maximum rate)。

那麼萬兆網卡的吞吐大概是它的十倍,也就是差不多每秒 1488 萬幀,處理一個包的時間在百納秒的級別,基本相當於一個 L2 Cache Miss 的時間。所以如何減小內核協議棧處理帶來的內核-用戶態頻繁內存拷貝的開銷,成為一個很重要的課題,這就是為什麼現在很多高性能網絡程序開始基於 DPDK 進行開發。

對於不了解 DPDK 的朋友,在這裡簡單科普一下:

2010 年代的分佈式系統:硬件的進化 3

(圖 3:DPDK Flow Bifurcation)

從上圖可以看到,數據包直接從網卡到了 DPDK,繞過了操作系統的內核驅動、協議棧和 Socket Library。 DPDK 內部維護了一個叫做UIO Framework 的用戶態驅動(PMD),通過ring queue 等技術實現內核到用戶態的zero-copy 數據交換,避免了Syscall 和內核切換帶來的cache miss,而且在多核架構上通過多線程和綁核,極大提升了報文處理效率。如果你確定你的網絡程序瓶頸在包處理效率上,不妨關註一下 DPDK。

另外RDMA 對未來體系結構的影響也會很大,它會讓一個分佈式集群向一個超級NUMA 的架構演進(它的通信延時/帶寬已經跟現在NUMA 架構中連接不同socket node 的QPI 的延時/帶寬在一個量級),但是目前受限於成本和開發模型的變化,可能還需要等很長一段時間才能普及。

其實不管是DPDK,SPDK,PMDK ,背後的主線都是Bypass kernel,Linux 內核本身帶來的開銷已經很難適應現代硬件的發展,但是生態和兼容性依然是大的挑戰,我對於一言不合就搞個Bypass Kernel SDK 的做法其實是不太贊同的。大量的基礎軟件需要適配,甚至整個開發模型都要變化。

我認為有關內核的問題,內核社區從長期來看一定會解決。一個值得關注的技術是Linux 5.1 內核中引入的io_uring 系列的新系統調用,io_uring 的原理簡單來說就是通過兩個內核/用戶態共享的ring buffer 來實現IO 事件的提交以及收割,避免了syscall 及內核用戶態的內存拷貝,同時提供了poll 的模式, 不用等待硬件中斷,而是不斷輪詢硬件,這極大降低了IO 延遲,提升了整體吞吐。我認為 io_uring 的出現也代表了內核社區在各種 Bypass Kernel 技術湧現的當下,正在奮起直追。

作者介紹:

黃東旭:分佈式系統專家,架構師,開源軟件作者。 PingCAP 聯合創始人兼 CTO,知名開源項目 Codis / TiDB / TiKV 主要作者,曾就職於微軟亞洲研究院,網易有道及豌豆莢。 2015 年創業,成立 PingCAP,致力於下一代開源分佈式數據庫的研發工作,擅長分佈式存儲系統設計與實現,高並發後端架構設計。

相關閱讀:

2010 年代的分佈式系統:存儲之數據庫篇

2010 年代的分佈式系統:軟件構建方式和演化