CephFS快照幾個特點:
- 寫時復(fù)制
- client端操作時只能針對目錄秸讹,不能針對單獨文件
- 從任意文件夾下開始打快照
快照實現(xiàn)
快照通過SnapRealm
組織成樹形結(jié)構(gòu)啦粹,每個有快照信息的inode節(jié)點都會有對應(yīng)的SnapRealm
,沒有快照信息的inode使用父節(jié)點路徑上最近的SnapRealm
讯嫂,根節(jié)點默認(rèn)有SnapRealm
蝙泼。在client端創(chuàng)建快照時mds會在對應(yīng)的inode節(jié)點新建SnapRealm
(僅首次創(chuàng)建時)宋距,普通文件inode中也會出現(xiàn)SnapRealm
,但都是mds的cow機制創(chuàng)建的埃元,client端無法直接操作涝涤。
要解決的問題
快照究竟是在備份什么?
快照是對當(dāng)前目錄及以下的子樹狀態(tài)進行保存亚情,創(chuàng)建快照相當(dāng)于對目錄樹中(節(jié)點以下的子目錄樹)每個inode進行備份妄痪,因為inode承載了文件系統(tǒng)的全部信息。根據(jù)MDS的元數(shù)據(jù)組織關(guān)系楞件,對于普通文件衫生,實際上是將dentry在dir的items
中新增一份副本,由first
土浸,last
兩個值指明對應(yīng)的snap范圍罪针,并且還會對inode進行備份,備份的inode最終以omap val形式存在黄伊。對于目錄泪酱,并不會在其父目錄items
中新增dentry,而只是在自己的inode中新增一份inode備份还最,最終以meta pool中的RADOS對象形式存在(不是新增對象墓阀,每個目錄只有一個對象)。快照的元數(shù)據(jù)如何存在拓轻?
每個快照都有全局唯一的整數(shù)id標(biāo)識斯撮,通過向MDSTableServer
申請來保證id唯一性。每個元數(shù)據(jù)都有first
扶叉,last
標(biāo)識勿锅,用于標(biāo)識元數(shù)據(jù)對應(yīng)的snap帕膜,last
為CEPH_NOSNAP
時標(biāo)識元數(shù)據(jù)為head數(shù)據(jù)。在目錄樹中的某個節(jié)點打快照后溢十,快照信息如何向上傳遞垮刹?
快照節(jié)點以上的部分和本次快照無關(guān),因此元數(shù)據(jù)不受影響张弛。但如果本節(jié)點是第一次打快照荒典,則snaprealm的組織關(guān)系會發(fā)生變化。-
在目錄樹中的某個節(jié)點打快照后乌庶,快照信息如何向下傳遞种蝶?
當(dāng)父節(jié)點創(chuàng)建快照后,子節(jié)點是需要知道的瞒大,這樣子節(jié)點才會知道去備份dentry和inode螃征。這個通知機制是通過SnapRealm
關(guān)系樹來完成的。父節(jié)點遍歷自己的child snaprealms透敌,逐個清空child snaprealm cached_seq盯滚,并向client端發(fā)送信息。
清空cached_seq可以保證在下次需要讀取snap信息時snaprealm重新進行build_snap_set()
操作酗电,進而讀取到父節(jié)點的最新snap信息魄藕。
向client端發(fā)的信息主要包括三方面:- snaprealm組織關(guān)系的變化。如果是新創(chuàng)建的snaprealm撵术,則涉及繼承關(guān)系調(diào)整背率。
- 面向client的inode cap組織關(guān)系變化。每個inode cap都屬于一個snaprealm管理(通過xlist結(jié)構(gòu))嫩与,如果是新建的snaprealm寝姿,則涉及管理關(guān)系的移動。比如初始狀態(tài)下所有cap都在根節(jié)點snaprealm中划滋,新建snaprealm后饵筑,快照節(jié)點以下的inode cap將被移動到新snaprealm中。
- split信息处坪。如果不是新建snaprealm根资,即在已有快照的節(jié)點上繼續(xù)創(chuàng)建快照。這種情況下快照節(jié)點的子節(jié)點sanprealm需要知道父節(jié)點快照更新的消息同窘,在mds端是通過寫時復(fù)制(Copy On Write)的方式先invalidate cache seq玄帕,再在需要時build seq實現(xiàn),但是對于client端無法這樣做想邦,client端維護的snap信息需要及時更新桨仿,沒有cow,因此這些信息作為split信息傳遞給client案狠。
寫時復(fù)制
創(chuàng)建快照時只更新節(jié)點的snaprealm服傍,并invalidate子節(jié)點的snaprealm cache,同時通知client最新的snap信息骂铁。整個過程并沒有涉及元數(shù)據(jù)的備份吹零,first
,last
的修改以及對于普通文件的數(shù)據(jù)進行的備份拉庵,因為這些修改是在下次對節(jié)點進行修改時才會發(fā)生的事件灿椅,因此叫做寫時復(fù)制。
舉兩個??:
- 創(chuàng)建快照后钞支,在目錄下新建文件茫蛹,這時目錄發(fā)生cow:通過
journal_dirty_inode()
將目錄inode進行復(fù)制(CInode::cow_old_inode()
),但并不會將目錄的dentry在父目錄中進行備份烁挟。 - 創(chuàng)建快照后婴洼,在目錄下truncate一個已有的文件,這時文件發(fā)生cow:通過
journal_dirty_inode()
對文件目錄進行復(fù)制(MDCache::cow_inode()
)撼嗓,且會在目錄的items
中新增一個snaped的dentry柬采,和cow_inode()
new出來的inode關(guān)聯(lián)。對于文件數(shù)據(jù)部分的備份則是通過RADOS層的快照機制完成(mds會將文件之前的快照號傳給Filer
且警,最終傳到pg層的OSDOp中粉捻,這些快照號對應(yīng)的數(shù)據(jù)將被保留)。
快照對stats的影響
由于stats信息都是根據(jù)inode統(tǒng)計得出的斑芜,而從client發(fā)起的請求肩刃,要么是在非快照目錄下,要么是快照目錄下杏头,在非快照目錄下盈包,對于mds就是一次snapid為CEPH_NOSNAP
的請求,在快照目錄下發(fā)起的請求對于mds就是一個有具體snapid的請求大州。因此只能分開統(tǒng)計快照和非快照空間使用量续语。如果計費的話這里會有個問題,就是快照的實際使用空間是無法從client端得到的厦画,除非根據(jù)inode去datapool中遍歷對象計算出快照的實際使用空間疮茄。