分布式存儲 Ceph 的演進(jìn)經(jīng)驗(yàn) · SOSP 2019
『看看論文』是一系列分析計(jì)算機(jī)和軟件工程領(lǐng)域論文的文章,我們在這個(gè)系列的每一篇文章中都會閱讀一篇來自 OSDI、SOSP 等頂會中的論文,這里不會事無巨細(xì)地介紹所有的細(xì)節(jié),而是會篩選論文中的關(guān)鍵內(nèi)容,如果你對相關(guān)的論文非常感興趣,可以直接點(diǎn)擊鏈接閱讀原文。
本文要介紹的是 2019 年 SOSP 期刊中的論文 —— File Systems Unfit as Distributed Storage Backends: Lesson Effis from 10 Years of Ceph Evolution[^1],該論文介紹了分布式存儲系統(tǒng) Ceph 在過去 10 多年演進(jìn)過程中遇到的一些問題,我們作為文件系統(tǒng)的使用者也能從中可以借鑒到很多經(jīng)驗(yàn)與教訓(xùn),在遇到相似問題時(shí)避免犯相同的錯(cuò)誤。
圖 1 - Ceph
從 2004 年到今天,Ceph 的存儲后端一直都在演變,從最開始基于 B 樹的 EBOFS 演變到今天的 BlueStore,存儲后端已經(jīng)變得非常成熟,新的存儲系統(tǒng)不僅能夠提供良好的性能,還有著優(yōu)異的兼容性。我們在這篇文章中將要簡單介紹分布式存儲 Ceph 的架構(gòu)以及演進(jìn)過程中遇到的挑戰(zhàn)。
Ceph 架構(gòu)
分布式文件系統(tǒng)能夠聚合多個(gè)物理機(jī)上的存儲空間并對外提供具有大帶寬、并行 I/O、水平擴(kuò)展、容錯(cuò)以及強(qiáng)一致性的數(shù)據(jù)存儲系統(tǒng)。不同的分布式系統(tǒng)可能在設(shè)計(jì)上稍有不同并且使用不同的術(shù)語描述物理機(jī)上用于管理存儲資源的模塊,但是存儲后端(Storage backend)一般都被定義為直接管理物理機(jī)上存儲設(shè)備的軟件模塊;而在 Ceph 中這一模塊就是對象存儲設(shè)備(Object Storage Devices、OSDs):
圖 2 - Ceph 架構(gòu)
Ceph 使用如上圖所示的架構(gòu),它的核心是可靠自主分布式對象存儲(Reliable Autonomic Distributed Object Store、RADOS),該模塊可以水平擴(kuò)展出成千上萬個(gè) OSDs 提供自愈、自管理并且強(qiáng)一致的副本對象存儲服務(wù)。
我們可以使用 Ceph 提供的 librados 操作 RADOS 中存儲的對象和對象集合,該庫提供了易于操作的事務(wù)接口,在該接口之上我們可以構(gòu)建出:
- RADOS 網(wǎng)關(guān)(RGW):類似于 Amazon S3 的對象存儲;
- RADOS 塊設(shè)備(RBD):類似于 Amazon EBS 的虛擬塊設(shè)備;
- CephFS:提供 POSIX 語義的分布式文件系統(tǒng);
RADOS 中的對象會被存儲在邏輯分區(qū)中,也就是池(Pool);對象會在池中分片,每個(gè)分片單位被稱作放置組(Placement Groups、PGs),放置組中的數(shù)據(jù)會根據(jù)配置好的副本數(shù)同步到多個(gè) OSD 上,這樣可以在單個(gè) OSD 宕機(jī)時(shí)保證數(shù)據(jù)的正確性。
RADOS 集群中的每個(gè)節(jié)點(diǎn)都會為每個(gè)本地存儲設(shè)備運(yùn)行獨(dú)立的 OSD 守護(hù)進(jìn)程,這些進(jìn)程會處理來自 librados 的請求并配合其他 OSD 節(jié)點(diǎn)完成數(shù)據(jù)的拷貝、遷移以及錯(cuò)誤恢復(fù)等操作,所有的數(shù)據(jù)都會通過內(nèi)部的 ObjectStore 接口持久化到本地,我們可以為硬件設(shè)備實(shí)現(xiàn)不同的接口以滿足兼容性的需求。
演進(jìn)挑戰(zhàn)
與其他的分布式文件系統(tǒng)不同,今天 Ceph 的存儲后端 BlueStore 繞過了本地的文件系統(tǒng),直接管理本地的裸設(shè)備,這是因?yàn)?Ceph 團(tuán)隊(duì)的經(jīng)驗(yàn)說明在本地的文件系統(tǒng)上構(gòu)建存儲后端是一件非常麻煩的事情:
圖 3 - 存儲后端的挑戰(zhàn)
- 在本地文件系統(tǒng)上直接構(gòu)建無額外開銷的事務(wù)機(jī)制是非常復(fù)雜的;
- 本地文件系統(tǒng)的元數(shù)據(jù)性能對分布式文件系統(tǒng)的性能有很嚴(yán)重的影響;
- 成熟的文件系統(tǒng)有著非常嚴(yán)格的接口,適配新的存儲硬件很困難;
高效事務(wù)
事務(wù)可以通過將一系列操作封裝到獨(dú)立的原子單元來簡化應(yīng)用程序的開發(fā),這一系列操作要么全部執(zhí)行、要么全不執(zhí)行,對數(shù)據(jù)庫稍有了解的工程師應(yīng)該都很了解事務(wù)的四個(gè)特性,也就是原子性、一致性、隔離性和持久性,我們這里就不展開討論了。
雖然事務(wù)能夠極大地簡化應(yīng)用程序開發(fā)者的工作并減輕負(fù)擔(dān),但是想要在本地的文件系統(tǒng)之上支持高效地事務(wù)機(jī)制是非常有挑戰(zhàn)的任務(wù),這篇論文給出了三種實(shí)現(xiàn)事務(wù)的方法:
圖 4 - 三種實(shí)現(xiàn)事務(wù)的方式
1.基于文件系統(tǒng)內(nèi)部的事務(wù)機(jī)制 — 很多文件系統(tǒng)都在內(nèi)部實(shí)現(xiàn)了事務(wù),這樣能夠原子地執(zhí)行一些內(nèi)部的復(fù)合操作,然而因?yàn)檫@些事務(wù)機(jī)制僅用于內(nèi)部,所以功能非常受限、甚至不可用,所以也就很難利用文件系統(tǒng)的內(nèi)部事務(wù);
2.在用戶空間實(shí)現(xiàn)邏輯預(yù)寫式日志(Write-Ahead Log、WAL)— 雖然這種實(shí)現(xiàn)方式可以工作,但是它卻會遇到三個(gè)比較嚴(yán)重的問題;
- 讀-修改-寫操作緩慢(Slow Read-Modify-Write)— 基于 WAL 的日志機(jī)制會為每個(gè)事務(wù)執(zhí)行如下所示的步驟:序列化事務(wù)并寫入日志、調(diào)用 fsync 提交事務(wù)、事務(wù)操作提交到文件系統(tǒng),因?yàn)槊總€(gè)事務(wù)在執(zhí)行前都需要讀取前一個(gè)事務(wù)執(zhí)行的結(jié)果,即等待三個(gè)步驟執(zhí)行完成,所以這種實(shí)現(xiàn)比較低效;
- 非冪等操作(Non-Idempotent Operations)— 部分文件的操作可能不是冪等的,錯(cuò)誤恢復(fù)重放日志時(shí)會導(dǎo)致數(shù)據(jù)發(fā)生錯(cuò)誤的結(jié)果甚至數(shù)據(jù)損壞;
- 雙寫(Double Writes)— 所有數(shù)據(jù)都會被先寫入 WAL 并隨后寫入文件系統(tǒng),同時(shí)向兩個(gè)地方寫入相同的數(shù)據(jù)會降低一半的磁盤帶寬;
3.使用支持事務(wù)的鍵值數(shù)據(jù)庫 — 元數(shù)據(jù)存儲在 RocksDB 中,而對象仍然使用文件系統(tǒng)存儲,因?yàn)樵诖鎯χ袑懭雽ο笮枰謩e將對象寫入文件、將元數(shù)據(jù)寫入 RocksDB 并調(diào)用兩次 fsync,而部分文件系統(tǒng)(JFS)對每個(gè) fsync 都會觸發(fā)兩次昂貴的 FLUSH CACHE,這也就是一致性帶來的高額外開銷;
快速元數(shù)據(jù)操作
本地文件系統(tǒng)中低效地元數(shù)據(jù)操作對分布式文件系統(tǒng)的影響非常大,當(dāng)我們使用readdir 操作在 Ceph 中遍歷大的文件目錄時(shí),就可以體會到元數(shù)據(jù)操作對整體性能的影響。
RADOS 集群中的對象會根據(jù)文件名的哈希映射到某一個(gè)放置組中,這些對象在遍歷時(shí)也會遵循哈希順序,當(dāng)我們在系統(tǒng)中遇到很長的對象名時(shí),可能需要使用擴(kuò)展屬性突破本地文件系統(tǒng)的文件名長度限制,查找這些文件時(shí)也需要調(diào)用 stat 獲取文件的真實(shí)文件名進(jìn)行比對。為了解決系統(tǒng)的緩慢遍歷問題,我們使用如下所示的層級結(jié)構(gòu)來存儲文件對象:
圖 5 - 文件夾和對象
查找或者遍歷文件時(shí),我們會先選擇合適的文件夾,再遍歷文件夾中的對象,而為了減少stat 函數(shù)的調(diào)用,存儲后端需要保證每個(gè)文件夾中的文件盡可能少;當(dāng)文件夾中的內(nèi)容逐漸增加時(shí),我們也需要將其中的內(nèi)容拆分到多個(gè)文件夾中,不過這個(gè)內(nèi)容分割的過程卻是極其耗時(shí)的。
支持新硬件設(shè)備因?yàn)榉植际降奈募到y(tǒng)的運(yùn)行基于本地的文件系統(tǒng),而存儲硬件的高速發(fā)展會為分布式文件系統(tǒng)帶來更多的挑戰(zhàn)。為了提高存儲設(shè)備的容量與性能,HDD、SSD 的提供商通過引入主機(jī)管理的 SMR 以及 ZNS 技術(shù)對現(xiàn)有的硬件進(jìn)行改進(jìn),這些技術(shù)對提高分布式文件系統(tǒng)的性能異常重要,而存儲設(shè)備的開發(fā)商也在開發(fā)新的硬件,這也增加了文件系統(tǒng)的適配成本。
總結(jié)傳統(tǒng)的分布式文件系統(tǒng)開發(fā)者一般都會將本地的文件系統(tǒng)作為它們的存儲后端,然后嘗試基于本地的文件系統(tǒng)構(gòu)建更加通用的文件系統(tǒng),然而因?yàn)榈讓拥墓ぞ卟⒉荒芡耆嫒?,所以這會為項(xiàng)目帶來極大的復(fù)雜性,這是因?yàn)楹芏嚅_發(fā)者認(rèn)為開發(fā)新的文件系統(tǒng)可能需要 10 年的時(shí)間才能成熟,然而基于 Ceph 團(tuán)隊(duì)的經(jīng)驗(yàn),從零開始開發(fā)成熟的存儲后端并不要那么長的周期。
從作者的角度來看,Ceph 的演進(jìn)過程其實(shí)是合理的,我們在剛開始構(gòu)建系統(tǒng)時(shí)希望盡可能利用現(xiàn)有的工具減少我們的工作量,只有當(dāng)現(xiàn)有的工具不再趁手時(shí),才應(yīng)該考慮從零構(gòu)建復(fù)雜的系統(tǒng),如果 Ceph 從立項(xiàng)開始就從零構(gòu)建存儲后端,可能 Ceph 也不會占領(lǐng)市場并得到今天這樣的地位。
本文轉(zhuǎn)載自微信公眾號「真沒什么邏輯」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系真沒什么邏輯公眾號。