【Ceph淺析筆記】Ceph的工作原理
本章主要對Ceph的工作原理進行介紹。
尋址過程
如果Client來了一個請求,不管個請求是讀還是寫都需要先尋址,才能找到數據應該放哪裏或者說需要從哪裏去。
之前我們說過Ceph的尋址方式是基於計算的,這樣就避免的查表,也避免了使用一個單獨的元數據服務器。
概述
對於Client傳來的一個File,為了方便處理,我們可以將其分割為若幹大小相同的小塊Object。
然後可以將這些Object映射到OSD上,如果使用一種固定的映射算法,則一個Object每次都會固定的映射到一組OSD上,那麽如果這個OSD壞了呢?則無法遷移到其他的OSD上。
同時一個Object可以給會映射到若幹的OSD上,所以這個OSD會定期與其他的OSD進行信息的交互,而每個OSD上承載的Object可能達數百萬個,那麽如果OSD要進行的信息交互將暴漲至數千萬次,維護成本較高。
那麽為了實現Object與OSD之間的動態映射,以及降低OSD與Object之間的信息維護開銷,則可以引入一個中間層PG(Placement Group)
PG首先會對Object進行組織。一個Object只能映射到一個PG裏面。而一個PG可以組織多個Object。也就是說PG與Object是“一對多”的映射關系
另外PG還會與OSD進行映射。每個PG一般會復制成3副本放到3個OSD上。而每個OSD上也會承載多個PG。
映射過程
那麽file——Object——PG——OSD之間的映射是如何完成的呢?
首先是file —— Object的映射
這個比較簡單,就是按照一定的大小對file進行切割即可,相當於RAID中的條帶化處理
切割以後,我們可以對object進行編號,也即oid(Object ID)
每個file都有一個唯一的元數據ino,然後再把file切分後產生的序號連綴在一起,即可構成oid
比如元數據為fileName的文件成分為三個Object,oid即為fileName0,fileName1,fileName2。
需要註意的是ino必須唯一
然後是Object—— PG
每個Object都要獨立的映射到一個PG裏面。
我們之前提供,數據塊最好能均勻在底層,這樣即可以充分利用底層硬件,有可以平攤風險。那麽怎麽均勻分布呢?
首先可以將oid進行哈希,這樣會得到一個近似均勻分布的偽隨機值,然後我們要考慮的是把Object放到PG裏面去了。假設PG數為m,那麽最簡單的就是在m個PG中隨機的選一個,那麽可以設定一個長度為m-1的掩碼,然後將HASH得到的偽隨機值於mask按位相與,最終得到PG序號(pgid)
現在我們保證了Object與PG之間近似均勻的映射,然後Object的size相同,這樣就可以保證PG中存儲的Object的總數據量近似均勻。
不過需要註意的是Object與PG的數量較多的時候,這種偽隨機關系才近似均勻性才能成立。
最後是PG——OSD映射
之前講的Object與PG的映射其實是靜態的,也就是一個Object通過這個運算一定會映射到某個PG裏面。
但是我們加上PG層的目的是可以實現動態遷移,也就是說"Object——PG"的結構不是絕對不變的,而是受到其他因素的影響,比如當前系統的狀態,也就是Cluster Map。當系統中的OSD狀態、數量發生變化的時候,ClusterMap可能發生變化。因此映射關系也會變化。
預先配置的存儲策略。
最開始的時候管理員可以配置一些策略,比如說一個PG分到的3個OSD需要位於不同的服務器或者說機架上,這樣就算一個服務器宕掉了,還有其他的副本可用。
所以說這一層的映射公式需要滿足動態特性,可以讓PG根據需要動態遷移到不同的OSD組合上。
此次映射中使用的算法就叫CRUSH算法
寫數據的流程
Ceph的寫與讀的流程大體相同,本章主要介紹寫過程。
當Client要向Ceph集群寫入一個file時,首先要在Client本地將file映射為若幹Object,然後使用HASH和CRUSH算法映射成3個OSD。序號最靠前的OSD就是Primary OSD,後兩個為Secondary OSD和Tertiary OSD。
現在Client已經知道數據要寫到哪些OSD裏面了,首先向Primary OSD發起寫請求,然後由Primary OSD同步復制兩個副本到其余的OSD中。
當Secondary 和Tertiary完成寫入了以後,返回ACK給 Primary,最後由Primary向Client確認Object的寫入。
很顯然這種做法延遲比較長,必須等所有的OSD都落到磁盤上了以後才會真正返回ACK。可以進行一些優化。當各個OSD將數據寫入內存緩沖區後,先向Client發送 一次確認,當各個OSD都將數據落到磁盤後,再向Client發送一個最終的ACK。
總之,不需要依賴其他的系統模塊,只需要Client即可完成OSD的尋址。所以Client可以與OSD進行並行操作,這樣工作壓力可以盡可能均勻分擔,從而避免單個OSD成為性能瓶頸。
如何同步信息
下面兩章我們介紹了如何尋址,如何寫入,他們都需要使用到cluster map這個元數據,那麽如何在所有節點上同步cluster map呢?
由若幹monitor共同監控所有OSD的狀態,然後會形成cluster map的master版本。再將這個版本同步到其他的OSD和client中。
不過monitor不是主動詢問所有OSD的狀態的,而是由OSD主動上報自己的狀態信息,比如說OSD加入或者異常的時候,都需要主動通知到monitor
那麽Cluster Map需要包含哪幾個方面的信息呢?
首先是OSD的網絡地址,這樣才可以找到OSD在那裏。
然後當然是OSD的狀態,也就是OSD是否正常工作,是否在至少一個PG裏面。
另外還需要包含CRUSH算法的一些配置參數。
還有個問題,Cluster Map在所有的OSD之間進行同步,極有可能兩個OSD持有的Cluster Map的版本不同,那麽怎麽進行區分了?可以使用 版本號,時間越靠後的版本號越大,所以monitor手上的版本號一定最大。當任意兩方在通信的時候發現彼此的版本號不相同,則需要將高版本的同步到另外的節點上。
OSD上線
當一個新的OSD上線後,首先會根據配置信息主動向monitor進行報告。
然後Monitor會把它加入Cluster Map中,然後更新狀態,最後把最新版的Cluster Map發給這個OSD。
接下來,這個OSD會計算出自己對應的PG,以及這個PG還會放到哪些其他的OSD。然後這個新的OSD會與這些OSD取得聯系,如果
此時發現這個PG只放了2個副本,而預先配置的副本數應該是3。說明之前肯定有OSD出現了故障,所以其他OSD把這個PG的內容復制給新的OSD,最後再更新一次狀態,說明OSD已經可以承載PG了。
這就是一個failure recovery的過程
如果此時發現OSD一切正常,則用新的OSD替換到現在的一個OSD,並承擔數據,重新更新cluster map的內容。這就是一個re-balancing的過程。
那麽failture detection的過程又是什麽呢?如果一個OSD發現自己與共同承載一個PG的另一個OSD無法通信,它會上報給monitor。或者說,OSD的守護進程發現自己的狀態異常,同樣會上報給monitor。如果在一段時間以後,OSD仍然無法恢復正常,則狀態會設置為down and out,更新cluster map並擴散。
更新cluster map會不會有廣播風暴
之前我們了解了cluster map數據結構並不大,也就是說即使這個集群中有上千個OSD,cluster map的擴散也不會占用太大的帶寬。
而且cluster map也不會頻繁的更新。
最關鍵的是cluster map是以增量的形式擴散,只會把兩個版本的差異發送給另一方。
同時monitor不是map的版本一更新就廣播給大家。它只會在有OSD上報信息的時候才會同步一次,所以這種方式是異步且lazy的。
所以因為map更新而導致廣播防暴的幾率並不高。
【Ceph淺析筆記】Ceph的工作原理