淺析 Redis 作為 JuiceFS 元資料引擎的優劣勢

語言: CN / TW / HK

元資料管理一直是檔案系統領域的核心話題,JuiceFS 開創性地將檔案系統的元資料引擎「外掛化」,讓使用者可以根據實際的使用場景自由選擇適合的資料庫作為 JuiceFS 的元資料引擎。

今天邀請到 Juicedata 技術專家高昌健,簡要解析使用不同 Redis 架構作為元資料引擎的優劣勢。無論你是社群的新使用者還是進階使用者,想更全面瞭解 Redis 的適用場景,不要錯過這篇文章,後續我們還會針對更多資料庫進行分析,盡請期待。 

概覽

Redis 是誕生於 2009 年的開源記憶體 KV 資料庫,根據 DB-Engines [1] 網站的排名統計,Redis 是目前世界上最流行的 KV 儲存。由於 Redis 具有極高的效能、足夠友好的使用者體驗、活躍的開發者社群以及成熟的生態,JuiceFS 開源之初 [2]   初便將 Redis 作為首個支援的元資料引擎,Redis 也是目前 JuiceFS 社群中使用非常廣泛的元資料引擎之一。

作為一個學習門檻很低的資料庫,Redis 非常適合在快速上手時使用 。但是隨著資料規模的增長,以及將 JuiceFS 部署到生產環境以後對於服務可用性、資料可靠性的要求,傳統 Redis 架構的一些弊端也會逐漸顯現。本文將針對不同 Redis 架構的優劣勢進行分析,力圖幫助讀者更加全面地瞭解 Redis 作為 JuiceFS 元資料引擎時需要知曉的關鍵資訊。

使用 Redis 作為元資料引擎的優勢與限制

由於 Redis 完全使用記憶體來儲存資料,因此在檔案系統元資料請求的響應上是非常快的。同時在某些關鍵的元資料操作上(如 lookup),JuiceFS 還充分利用 Redis 提供的 Lua 指令碼 Lua指令碼 [3] 特性,提升這些關鍵操作的效能。在與 MySQL、TiKV、etcd 的 元資料引擎評測 [4] 中,Redis 的平均元資料請求效能相比其它幾個資料庫快了 2-4 倍。 因此 Redis 非常適合那些對於元資料請求效能有著極致要求的使用場景。

不過同樣是由於使用記憶體來進行資料儲存這一點,造成單個 Redis 服務的儲存容量具有一定的上限。 根據 JuiceFS 的經驗,檔案系統中 1 個 inode 的元資料大約佔用 300 位元組記憶體,因此如果要儲存 1 億個 inode 需要大約 32GiB 記憶體。 在實踐中不推薦使用超過 64GiB 記憶體的例項來部署 Redis,一方面越大的記憶體意味著故障恢復的時間也會越久,另一方面因為 Redis 是單執行緒模型,沒法利用多核,所以大記憶體機器的 CPU 資源也會存在很大的浪費。

Redis 單機架構的問題與挑戰

當僅部署一個 Redis 例項時,這個例項會成為整個檔案系統的單點,一旦元資料引擎服務不可用,將會造成所有操作無法正常進行。 因此在生產環境中,通常建議部署多個 副本 [5] 例項以及  Redis Sentinel [6] 來保證服務的可用性。 多個副本可以確保同時有多個例項存活,並且這些例項之間的資料幾乎一致(為什麼說是「幾乎一致」後面會講到),而 Redis Sentinel 可以定期檢測 Redis master 的健康狀況,如果 Redis master 意外宕機,Redis Sentinel 會立即進行故障切換(切換時間通常在秒級),將某個副本例項晉升為 master 例項,保證 Redis 服務的可用性。

預設情況下,Redis master 與副本之間通過非同步複製的方式來同步資料,這種方式可以在儘量不犧牲 Redis 效能的情況下將資料同步到副本例項。不過當 Redis master 出現故障時,可能因為某些資料還沒來得及同步到副本例項而造成資料丟失。雖然 Redis 也提供同步複製的能力,但是這並不能將 Redis 變成一個 CP系統 [7] ,只是一定程度上降低了資料丟失的概率。

因此如何在保證服務可用性的情況下同時確保資料的可靠性,是使用 Redis 的一個大的挑戰,特別是當這些資料是檔案系統的元資料時。

進階:使用 Redis Cluster 作為元資料引擎

如果你熟悉 Redis 可能會問為什麼不使用 Redis Cluster [8] 作為元資料引擎?

這背後的原因得從 JuiceFS 檔案系統的元資料設計講起。JuiceFS 的元資料有多種型別,如檔案、目錄、屬性、檔案鎖等,這裡每一種型別的元資料在 Redis 中都對應不同的 key。當執行某個元資料操作時可能會同時涉及多種型別的元資料,也就意味著需要同時修改多個 Redis 中的 key。為了保證檔案系統元資料操作的原子性,JuiceFS 使用了 Redis 的 事務 [9] 特性來同時修改多個 key,確保元資料的一致性。

但是事務特性在 Redis Cluster 中有一定限制,Redis Cluster 劃分了很多 hash slot,所有資料會根據雜湊演算法分配到不同的 hash slot 中。Redis Cluster 要求一個事務中所有操作的 key 必須在同一個 hash slot 中,也就是說它並不提供跨 hash slot 的事務支援。因此如果將 Redis Cluster 作為 JuiceFS 的元資料引擎,將無法保證元資料操作的原子性,這對於檔案系統來說是不可以接受的。

幸運的是,通過在 key 中顯式指定  hash tag [10]  可以使得 Redis Cluster 將具有相同 hash tag 的 key 分配到相同的 hash slot 中。JuiceFS 正是使用了這個特性確保一個檔案系統的所有 key 都儲存到同一個 hash slot 中,從而保證元資料操作的原子性,這個功能目前已經在  JuiceFS v1.0.0 Beta3 [11]  中正式釋出。Redis Cluster 在 JuiceFS 中的使用方式與單機 Redis 沒有區別,可以直接沿用以前的命令。 相比單機 Redis,使用 Redis Cluster 可以將不同 JuiceFS 檔案系統的元資料儲存到一個叢集中,而不用單獨維護多個 Redis 例項,大大降低了運維成本。但當各個檔案系統的大小不同時,Redis Cluster 的資料分佈可能會不均衡,如果存在單個特別大的檔案系統,只能通過 scale up 的方式來擴容。

雖然解決了 Redis Cluster 的事務限制問題,但是上一小節提到的資料可靠性問題依然存在,Redis Cluster 仍舊無法提供 強一致性保證 [12] ,本質上是由於 Redis Cluster 沿用了單機架構中的非同步資料複製機制。因此使用 Redis Cluster 還是存在資料丟失的可能性。

再次進階!  使用具有強一致性保證的 Redis 作為元資料引擎

不管是 Redis 還是 Redis Cluster 由於缺乏對於資料的強一致性保證,因此總是存在資料丟失的風險。Redis 公司(前 Redis Labs [13] )其實也在嘗試解決這個問題,於是有了 RedisRaft [14] 開源專案,試圖補齊 Redis 的這個短板(當然可能會犧牲掉一部分效能)。但是 RedisRaft 專案遲遲沒有 GA,目前仍處於開發階段。

嘗試解決這個問題的不僅僅是開源社群,各個公有云服務商也在積極推動。 2021 年 8 月,AWS 釋出了 Amazon MemoryDB for Redis(以下簡稱 MemoryDB)服務,這是繼 Amazon ElastiCache for Redis 之後又一個相容 Redis 協議的全託管儲存服務。正如這個服務的名字所描述的,MemoryDB 可以作為一個主資料庫,而不僅僅是一個快取層。它具有微秒級的讀取效能以及毫秒級的寫入效能, 最重要的是,MemoryDB 提供強一致性保證,這是通過將寫操作持久化到一個分散式事務日誌系統來實現的,以確保成功寫入的資料不會丟失。 同時 MemoryDB 保留了 Amazon ElastiCache for Redis 的諸多有用特性,如自動故障切換、自動資料備份(基於事務日誌實現)等。

如果你使用的是其它公有云,通常也會有著類似 MemoryDB 的相容 Redis 協議的雲服務,例如阿里雲的雲資料庫 Redis 企業版(持久記憶體型)、華為雲的雲資料庫 GaussDB(for Redis)。最重要的是這些雲服務能夠提供資料的強一致性保證,極大地提高了 JuiceFS 元資料的資料可靠性。

本文作者:

高昌健,Juicedata 技術專家,參與建設 JuiceFS 開源社群的主力隊員。 十年網際網路行業從業經歷,曾在知乎、即刻、小紅書多個團隊擔任架構師職位,專注於分散式系統、大資料、AI 領域的技術研究。

引用連結

[1]  DB-Engines:http://db-engines.com/en/ranking/key-value+store

[2]  開源之初:http://juicefs.com/blog/cn/posts/juicefs-open-source/

[3]  Lua 指令碼:http://redis.io/docs/manual/programmability/eval-intro/

[4]  元資料引擎效能評測:http://juicefs.com/docs/zh/community/metadata_engines_benchmark/

[5]  副本:http://redis.io/docs/manual/replication/

[6]  Redis Sentinel:http://redis.io/docs/manual/sentinel/

[7]  CP 系統:http://en.wikipedia.org/wiki/CAP_theorem

[8]  Redis Cluster:http://redis.io/docs/manual/scaling/

[9]  事務:http://redis.io/docs/manual/transactions/

[10]  hash tag:http://redis.io/docs/manual/scaling/#redis-cluster-data-sharding

[11]  JuiceFS v1.0.0 Beta3:http://github.com/juicedata/juicefs/releases/tag/v1.0.0-beta3

[12]  強一致性保證:http://redis.io/docs/manual/scaling/#redis-cluster-consistency-guarantees

[13]  Redis Labs: http://redis.com/press/redis-labs-becomes-simply-redis/

[14]  RedisRaft: http://github.com/RedisLabs/redisraft

插播活動 

理想汽車大資料平臺改造實踐

就在本週六 !

關於 Redis 的使用

還有問題? 

進群一起討論吧

我們的合夥人

兼社群助手

蘇銳全天線上

使用者案例

AI for Science-深勢科技       AI-雲知聲     

理想汽車     知乎     線上設計平臺:稿定科技   

大搜車    環球易購     趣頭條      Shopee

最佳實踐

關於Juicedata

Juicedata,杭州果汁資料科技有限公司是一家企業級儲存服務供應商,開發了雲原生分散式檔案系統 JuiceFS,致力於在大資料時代下,為客戶打造安全、高效能、自主可控的儲存基礎設施及服務。

2021年,JuiceFS 正式在GitHub上開源,已經獲得 5.6 K star,歡迎開發者加入我們。  (github.com/juicedata/juicefs)

點選下方“閱讀原文”訪問官網