JuiceFS 元數據引擎選型指南( 二 )


etcd 是另一個 TKV 類的數據庫 。支持 etcd 的原因是因為它在容器化場景中流行度非常高,基本上 k8s 都是用 etcd 來管理它的配置 。使用 etcd 作為 JuiceFS 的元數據引擎 , 并不是一個特別適配的場景 。一方面是它的性能一般,另一方面是它有容量限制(默認 2G,最大 8G),之后就難以擴容 。但是它的可靠性和可用性都非常高,而且容器化場景中也很容易部署,因此如果用戶只需要一個規模在百萬文件級別的文件系統 , etcd 依然是一個不錯的選擇 。
最后是 SQLite 和 BadgerDB , 它們分別屬于 SQL 類和 TKV 類,但使用起來體驗卻非常類似 , 因為它們都是單機版的嵌入式數據庫 。這類數據庫的特點是性能中等,但擴展性和可用性都比較差,因為其數據其實就存放在本地系統中 。它們的優勢在于非常易用,只需要 JuiceFS 自己的二進制文件,不需要任何額外組件 。用戶在某些特定場景或者進行一些簡單功能測試時,可以使用這兩個數據庫 。
02- 典型引擎的性能測試結果我們做過一些典型引擎的性能測試,并將其結果記錄在這個文檔中 。其中一份從源碼接口處測試的最直接結果大致為:Redis > TiKV(3 副本)> MySQL(本地)~= etcd(3 副本),具體如下:
Redis-AlwaysRedis-EverysecTiKVMySQLetcdmkdir600471 (0.8)1614 (2.7)2121 (3.5)2203 (3.7)mvdir878756 (0.9)1854 (2.1)3372 (3.8)3000 (3.4)rmdir785673 (0.9)2097 (2.7)3065 (3.9)3634 (4.6)readdir_10302303 (1.0)1232 (4.1)1011 (3.3)2171 (7.2)readdir_1k16681838 (1.1)6682 (4.0)16824 (10.1)17470 (10.5)mknod584498 (0.9)1561 (2.7)2117 (3.6)2232 (3.8)create591468 (0.8)1565 (2.6)2120 (3.6)2206 (3.7)rename860736 (0.9)1799 (2.1)3391 (3.9)2941 (3.4)unlink709580 (0.8)1881 (2.7)3052 (4.3)3080 (4.3)lookup9997 (1.0)731 (7.4)423 (4.3)1286 (13.0)getattr9189 (1.0)371 (4.1)343 (3.8)661 (7.3)setattr501357 (0.7)1358 (2.7)1258 (2.5)1480 (3.0)access9089 (1.0)370 (4.1)348 (3.9)646 (7.2)setxattr404270 (0.7)1116 (2.8)1152 (2.9)757 (1.9)getxattr9189 (1.0)365 (4.0)298 (3.3)655 (7.2)removexattr21995 (0.4)1554 (7.1)882 (4.0)1461 (6.7)listxattr_18888 (1.0)374 (4.2)312 (3.5)658 (7.5)listxattr_109491 (1.0)390 (4.1)397 (4.2)694 (7.4)link605461 (0.8)1627 (2.7)2436 (4.0)2237 (3.7)symlink602465 (0.8)1633 (2.7)2394 (4.0)2244 (3.7)write613371 (0.6)1905 (3.1)2565 (4.2)2350 (3.8)read_100 (0.0)0 (0.0)0 (0.0)0 (0.0)read_1000 (0.0)0 (0.0)0 (0.0)0 (0.0)

  • 上表中記錄的是每一個操作的耗時,數值越小越好;括號內數字是該指標對比 Redis-always 的倍數,數值也是越小越好
  • Always 和 Everysec 是 Redis 配置項 appendfsync 的可選值 , 分別表示每個請求都刷盤和每秒刷一次盤
  • 可以看到,Redis 在使用 everysec 的時候,性能更好,但與 always 相差的并不大;這是因為測試用的 AWS 機器上的本地 SSD 盤本身 IOPS 性能就比較高
  • TiKV 和 etcd 都使用了三副本 , 而 MySQL 是單機部署的 。即使這樣,TiKV 的性能表現還是高于 MySQL,而 etcd 與 MySQL 接近 。
值得一提的是 , 上文中的測試使用的都是默認配置,并沒有對各個元數據引擎去做特定的調優 。用戶在使用時可以根據自己的需求和實踐經驗進行配置調整,可能會有不一樣的結果 。
另一份測試是通過 JuiceFS 自帶的 bench 工具跑的,其運行的是操作系統讀寫文件的接口,具體結果如下:
Redis-AlwaysRedis-EverysecTiKVMySQLetcdWrite big file565.07 MiB/s556.92 MiB/s553.58 MiB/s557.93 MiB/s542.93 MiB/sRead big file664.82 MiB/s652.18 MiB/s679.07 MiB/s673.55 MiB/s672.91 MiB/sWrite small file102.30 files/s105.80 files/s95.00 files/s87.20 files/s95.75 files/sRead small file2200.30 files/s1894.45 files/s1394.90 files/s1360.85 files/s1017.30 files/sStat file11607.40 files/s15032.90 files/s3283.20 files/s5470.05 files/s2827.80 files/sFUSE operation0.41 ms/op0.42 ms/op0.45 ms/op0.46 ms/op0.42 ms/opUpdate meta3.63 ms/op3.19 ms/op7.04 ms/op8.91 ms/op4.46 ms/op從上表可以看到,讀寫大文件時使用不同的元數據引擎最后性能是差不多的 。這是因為此時性能瓶頸主要在對象存儲的數據讀寫上,元數據引擎之間雖然時延有點差異,但是放到整個業務讀寫的消耗上,這點差異幾乎可以忽略不計 。當然,如果對象存儲變得非??欤ū热缍加帽镜厝W部署),那么元數據引擎的性能差異可能又會體現出來 。另外,對于一些純元數據操作(比如 ls , 創建空文件等),不同元數據引擎的性能差別也會表現的比較明顯 。
03-引擎選型的考慮要素根據上文介紹的各引擎特點,用戶可以根據自己的情況去選擇合適的引擎 。以下簡單分享下我們在做推薦時會建議用戶考慮的幾個要素 。
評估需求:比如想使用 Redis , 需要先評估能否接受少量的數據丟失,短期的服務中斷等 。如果是存儲一些臨時數據或者中間數據的場景,那么用 Redis 確實是不錯的選擇,因為它性能夠好,即使有少量的數據丟失 , 也不會造成很大的影響 。但如果是要存儲一些關鍵數據,Redis 就不適用了 。另外還得評估預期數據的規模 , 如果在 1 億文件左右,Redis 可以承受;如果預期會有 10 億文件,那么顯然單機 Redis 是難以承載的 。

推薦閱讀