Ceph 新版本 Reef 上:RBD 性能驗證
背景
Ceph 社區最近凍結了即將發布的 Ceph Reef 版本,今天我們研究一下 Ceph Reef 版本在 10 個節點、60 個 NVMe 磁盤的集群上的 RBD 性能。
在確保硬件沒有問題(NVMe 固件更新)后,Reef 能夠保證約71GB/s的性能讀取和25GB/s的性能寫入(75GB/s 復制速度)。
對于小型隨機 IO,Reef 提供了大約4.4M 隨機讀取 IOPS和800K 隨機寫入 IOPS(2.4M 復制速度)。
對于小型 4K 順序同步寫入,Reef 實現了低于 0.5 毫秒的平均延遲、低于 0.5 毫秒的 99% 延遲和低于 0.8 毫秒的 99.9% 延遲。
即使在商業硬件設備上執行 3 倍的同步復制,它也實現了低于 8 毫秒的最大延遲。
雖然 Reef 要比 Quincy 性能更佳,但我們也發現了一些小問題。
在 Reef 凍結期間,我們將研究這些問題,以幫助 Reef 成為迄今為止最好的 Ceph 版本。
介紹
在過去的幾個 Ceph 版本中,Ceph 社區和 Red Hat 的 perf and scale 團隊都進行了各種性能測試,以將以前的版本與我們新的預發布代碼進行比較。
我們希望看到我們在性能改進的過程中沒有再引入新的其他問題。
Pacific 和 Quincy 的發布對我們來說是一個比較完美的節點。因為我們通過版本的回歸,并最終在發布之前確認了一些可能會有影響的問題。
捕獲細微的性能問題是非常復雜的,并且當我們嘗試將過去測試的結果與新結果進行比較時會變得更加困難。
在這過程中,發生了什么變化?是由于代碼更改、硬件/軟件架構更改還是其他原因造成的?
Performance-CI 在這里可用于嘗試在問題發生時捕獲問題,但它非常耗費資源,并且除非我們非常小心,否則很容易出現差錯。
今天,我們將對 Quincy 和 Reef 進行簡單的對比測試,我們將嘗試以完全相同的方式在完全相同的硬件上進行測試,以使差異盡可能小。
集群設置
Nodes | 10 x Dell PowerEdge R6515 |
CPU | 1 x AMD EPYC 7742 64C/128T |
Memory | 128GiB DDR4 |
Network | 1 x 100GbE Mellanox ConnectX-6 |
NVMe | 6 x 4TB Samsung PM983 |
OS Version | CentOS Stream release 8 |
Ceph Version 1 | Quincy v17.2.5 (built from source) |
Ceph Version 2 | Reef 9d5a260e (built from source) |
所有節點都連接到同一臺 Juniper QFX5200 交換機上,并通過單個 100GbE QSFP28 連接。同時我們部署了 Ceph 并使用 CBT (https://github.com/ceph/cbt/)啟動了 fio 測試。
除非特別說明,否則每個節點都安裝 6 個 OSD,同時 fio 運行 6 個 librbd 類型的進程。
基于英特爾的系統可以配置 "latency-performance" 以及 "network-latency" 來對系統進行調優。
這避免與 CPU C/P 狀態轉換帶來延遲。基于 AMD Rome 的系統在這方面的調優并沒有太大的改變,而且我們還沒有確認 tuned 實際上限制了 C/P 狀態轉換,但是對于這些測試,tuned 配置文件仍然設置為 “network-latency”。
測試設置
CBT 需要針對所部署的 Ceph 集群調整幾個參數。
首先,禁用 rbd 緩存,為每個 OSD 分配 8GB 內存,并在禁用 cephx 的情況下使用 msgr V2。
Fio 配置為首先使用大量寫入預填充 RBD 卷,然后在 iodepth=128 下進行 3 次迭代測試(如下表所示),每次迭代 5 分鐘。每個節點使用 6 個 fio 進程,總共使用 60 個 fio 進程,聚合 iodepth 為 7680。
一些后臺進程,比如 scrub、deep scrub、pg autoscaling 和 pg balancing 會被禁用。
配置靜態 16384 PG(高于通常推薦的數量)和 3x 副本的 RBD 池與每個 fio 進程 1 個 RBD 鏡像一起使用。
IO Size | Read | Write | RandRead | RandWrite |
4096 | X | X | X | X |
131072 | X | X | X | X |
4094304 | X | X | X | X |
最初的誤導性結果
只要是多余單個 OSD 的集群,Ceph 會使用 crush 以偽隨機方式存儲數據。
雖然比較多的 PG 數量以及 PG 均衡可以幫助改善這一點,但總會有差異,一些 OSD 不可避免地需要比其他 OSD 花費更長的時間來完成他們的工作。
因此,在任何給定的時間內,集群性能通常會受到最慢或使用率最高的 OSD 的限制。這是每個 Ceph 運維人員都應該知道的事情。
我們為什么現在提出這個?在 Reef 凍結之后,我們恢復了用于 Quincy 測試的 CBT 配置,并開始運行一組新的測試。初步結果看起來相當不錯。Quincy 的表現略低于預期,但與我們之前看到的相差不遠 (https://ceph.io/en/news/blog/2022/rocksdb-tuning-deep-dive).。
然而,一旦我到達瓶頸,結果開始看起來有點意外。
Reef 正在使用新的 RocksDB 調優配置(https://ceph.io/en/news/blog/2022/rocksdb-tuning-deep-dive),并進行了深度測試。
當這些調優用在 Quincy 版本時,我們獲得了很明顯的性能改進,我們預計 Reef 版本也會有類似的改進。
在這些測試中,Reef 的表現并不比 Quincy 好,實際上也不比 Pacific 好多少。
我們運行了很多次對比測試,并試圖梳理出可能解釋差異的因素。
后來,我們意識到我們可能應該關注一下系統的指標。CBT 為每個測試運行一個 collectl 副本,并記錄大量系統指標數據。
事實上,在運行的 RBD 和 RGW 測試之間,CBT 在長時間的測試過程中記錄了超過 20GB 的指標數據。
我們查看了系統中每個 NVMe 設備的性能指標。我們注意到,當第 10 個集群節點中的 nvme4 在大量寫入測試中顯示出較高的設備隊列等待時間,但在讀取測試中卻沒有。尤其是當在4KB 隨機寫入的時候,效果就更明顯了:
這些是 nvme4 上非常明顯的延遲峰值,我們可以肯定這些與低于預期的性能有關。
這個 NVME 是目前發現的延遲最嚴重的一個,但其他節點中的一些 NVME 也顯示出高于預期的延遲。
為了排除碎片的問題,我們對每個 NVME 進行完全安全擦除。
另外,在 Quincy 發布期間,我們從三星那里獲得到了一個新的 NVME。
當我們將其安裝替換到我們的集群上時,結果很明顯。
固件升級后,設備隊列永遠不會有超過一個 IO 等待,隊列等待時間永遠不會超過 0ms。
看起來固件更新解決了當前的問題,但它能夠永久修復該問題嗎?隨著時間的推移,我們需要觀察硬件的狀態以確保是否永久修復了該問題。
出于本次測試的目的,我們恢復了集群到正常的性能。
另外,性能提升了多少?固件更新主要有助于 4KB 和 128KB 隨機寫入測試。
性能現在大致恢復到去年秋天在 RocksDB 調優測試中觀察到的水平。
更重要的是,小型隨機 IO 測試顯示出非常一致的 NVMe 驅動器行為。
接下來我們將重新運行測試并進行一些對比。
4MB 連續吞吐量
在大吞吐量測試中,Quincy 和 Reef 達到了大致相同的性能水平。
Reef 對于大量寫入可能會快一點,而對于大量讀取可能會慢一點。
在這兩種情況下,底層集群都能夠以大約 70-75GB/s 的速度執行,盡管因為我們正在進行 3X 復制,客戶端可見寫入吞吐量實際上約為 25GB/s。
在這些測試中,每個 OSD 的平均 CPU 消耗為 1-1.5 個核心用于讀取和 3-4 個核心用于寫入。
這種差異非常典型,因為 Ceph 的寫入路徑比讀取路徑更長。
4KB 隨機 IOPS
每個版本對我們來說最重要的測試是小型隨機 IO 測試。
這些測試通過對 OSD 增加壓力,從而確認 IO 的效率。
在這種情況下,我們總體上得到了相對較好的結果,但有幾點需要注意。
在 4K 隨機讀取方面,Reef 僅比 Quincy 慢一點點,但非常接近。
另一方面,我們看到 4K 隨機寫入測試有了一定的改進,這主要是由于引入了新的 RocksDB 調優。
不過,根據去年秋天的結果,我們并沒有看到像預期那樣大的性能提升。在隨機讀取測試中,每個 OSD 的 CPU 使用率略高于 7 個內核,而在隨機寫入測試中,Reef 的每個 OSD 將近 11 個內核。這似乎與 Quincy 的更高性能成正比。
在測試 Ceph 的小的隨機寫入性能的時,加入擁有無限 CPU 資源,那么 kv_sync_thread 則會成為瓶頸,但 CPU 的消耗主要發生在 OSD 工作線程和信使線程中,因 CPU 造成的性能瓶頸場景還是比較少的。
因此,最大化寫入性能是 OSD 數量、NVMe 速度、核心數量和核心速度之間的微妙平衡。
Reef 中的隨機寫入性能高于 Quincy,但沒有我們希望的那么高。這是為什么?
還有兩個額外的測試可能會提供一下原因。
就在我們凍結 Reef 之前,我們升級到最新版本的 RocksDB,因為與我們在 Quincy 中使用的舊版本相比有幾個重大錯誤修復和改進。
我們可以簡單地還原該更改,然后看看 Reef 的表現如何。
我們還可以使用我們現在在 Reef 中作為標準使用的 RocksDB 調優來運行 Quincy,看看它能在多大程度上提高 Quincy 性能。
使用 Reef 調整在 v17.2.5 上運行特別慢之外,但非常接近。
當使用舊的 Quincy 版本的 RocksDB 編譯 Reef 時,似乎確實有一致的性能提升,盡管很小(~2%)。
使用相同版本的 RocksDB 編譯的 Quincy 和 Reef 則保持一致。
在隨機寫入場景中,我們看到兩個非常有趣的結果。
一:當 Quincy 使用新的 RocksDB 調整默認值編譯時,無論它使用哪個版本的 RocksDB,它實際上都比 Reef 快。
二:恢復到舊版本的 RocksDB 確實會帶來性能提升,但同樣非常小(~1-2%)。它不能完全解釋當 Quincy 和 Reef 都使用新的 RocksDB 調優時出現的回歸。
最終結果是 Reef 中很可能會出現小的回歸,從而影響小的隨機寫入。
4KB 順序同步寫入延遲
在過去的一年里,我們收到了很多關于 Ceph 寫入延遲的問題。
Ceph 可以進行 sub-millisecond 寫入嗎?我們看到什么樣的尾延遲?
雖然我們過去對此進行過測試,但我們現在決定也進行一組快速的 4K 同步順序寫入測試。需要注意的是,這是在一個有大量可用空間和幾乎零碎片的新集群上。
只有 1 個客戶端在 io_depth 為 1 的情況下進行寫入。
這幾乎是展示 Ceph低延遲的理想場景。它不一定反映在有業務流量以及數據碎片的集群上的真實尾部延遲。
Metric | O_DSYNC Quincy | O_SYNC Quincy | O_DSYNC Reef | O_SYNC Reef |
Average Latency (ms) | 0.417 | 0.416 | 0.421 | 0.418 |
99% Latency (ms) | 0.465 | 0.461 | 0.465 | 0.469 |
99.9% Latency (ms) | 0.741 | 0.733 | 0.750 | 0.750 |
Max Latency (ms) | 7.404 | 6.554 | 7.568 | 6.950 |
在這兩種情況下,Quincy 和 Reef 都能夠以低于 0.5 毫秒的延遲寫入絕大多數 IO。
CBT 會為每次運行保存 fio 延遲圖,因此我們也可以查看這些圖:
總體而言,結果非常一致,只有幾個異常值。
這里需要注意的是,在 fio 中測試 librbd 時,使用 O_SYNC 和 O_DSYNC 標志可能沒有太大區別。
我們聯系了 Ilya Dryomov(Ceph 的 RBD 負責人)。他表示 librbd 或內核 RBD 都不需要關心,因為這些是在 VFS 層處理的。我們應該只在這些寫入在所有參與的 OSD 上完全持久化后才尋求 OSD 的確認。無論如何,所有運行的性能似乎都相當。
在進行這些單客戶端、io_depth=1 測試時,同時也需要關注一下網絡的延遲。我們在集群中的不同節點之間進行了一些 ping 測試。
注意:ping 是 ICMP 而不是 TCP,而且 ping 也是往返的。
從 mako01 ping mako10(100GbE 接口):
icmp_seq | Latency (ms) |
1 | 0.039 ms |
2 | 0.025 ms |
3 | 0.032 ms |
4 | 0.029 ms |
5 | 0.034 ms |
6 | 0.027 ms |
7 | 0.026 ms |
8 | 0.026 ms |
9 | 0.028 ms |
10 | 0.032 ms |
在讀取的情況下,使用復制和使用 RBD 進行測試時,Ceph 僅有從客戶端到主 OSD 的往返。
在寫入情況下,Ceph 必須進行多次往返。1 個在客戶端和主節點之間,1 個在主節點和并行的每個輔助節點之間。
在寫測試中,我們應該可以看到有負載的節點的 2 次往返的平均網絡延遲要更差。
因此,網絡延遲很可能在這些小型同步寫入測試中發揮重要作用(可能不是主導作用)。
Ceph 本身仍有改進同步寫入延遲的空間,但是網絡延遲在這一點上是一個有效的問題,并且隨著 Ceph 本身的改進將成為一個更大的因素。
結論
這篇文章也是非常關注底層硬件性能和固件更新對 Reef 的影響。在進行基準測試時,了解底層硬件至關重要,如果我們沒有升級所有 SSD 驅動器上的固件,我們會忽略掉很多東西(更高的寫入 IOPS!)。
確保我們使用的固件是最新的,并且我們的硬件運行狀態良好,然后再花一天時間運行測試。
一旦硬件處于良好的狀態,Quincy 和 Reef 就會表現出差不多的性能。
兩者都實現了大約 71GB/s 的大型讀取和 25GB/s 的大型寫入以及 3X 復制。兩者還以大約 4.4-4.5M IOPS 實現了類似的 4KB 隨機讀取性能。
Reef 在小型隨機寫入方面比 Quincy 快 6-7%,這主要是由于新的 RocksDB 調整,但我們預計它會更快一些。
同時,可能還存在限制 Reef 實現更高性能的因素,我們后續將研究 Reef 凍結期間的潛在回歸,并繼續努力使 Reef 成為迄今為止最好的 Ceph 版本!