Ceph存儲系統使用的 CRUSH算法在一緻性 Hash 算法的基礎上充分考慮了多副本、故障域隔離等限制,盡量減少叢集在故障場景下的資料遷移量,實作這一目标的關鍵舉措 即為 PG邏輯概念的引入。
前文提到 Ceph可以了解為對 RADOS 對象存儲系統的二次封裝,Ceph中所有的使用者資料都被抽象成多個Object,如果 Ceph存儲系統以 Object 為追蹤目标,那麼要追蹤的單元個體數量就太多了,不僅會消耗大量的計算資源,而且在一個有數以億計對象(EB級存儲叢集)的系統中直接追蹤對象的位置及其中繼資料資訊也是完全不現實的。Ceph引進 PG邏輯概念,将一系列的Object聚合到 PG裡,并将 PG 映射到一系列的OSD 上去。系統中PG數量遠遠小于 Object 數量,存儲系統以PG 為存儲單元個體,直接追蹤PG 狀态,比較好地處理了性能和可擴充性的界限。
PG的引入也會增加一些系統資源開銷,如 PG 邏輯的處理會直接消耗存儲節點的部分CPU和記憶體,增大 PG的數量會增加存儲系統 Peering狀态處理的數量。
2.3.1 PG 數量的選擇
上述分析可以看出,PG 是使用者資料切片(Object)與真實提供存儲空間的存儲媒體
(OSD守護程序)之間的紐帶。Ceph存儲系統需要設定較為合理的 PG數量,過少的PG數量會導緻叢集 peer過程太慢,資料遷移效率過低;過多的PG 數量則會增加叢集存儲節點的計算資源負擔。PG的數量在 Ceph的存儲池(Pool)建立時指定,通常推薦每個OSD守護程序承載 100個 PG較為合适,考慮到叢集資料的副本政策,對于單存儲池的簡單場景,可以通過如下公式進行PG數量确定。
TotalPGs=(OSDs×100)/Replicas
在上述資料尋址計算中,可以看到要對Hash計算結果進行取模運算,存儲池的 PG數量建議取值為 2的n次方,這樣可以加速資料尋址的計算過程,即對上述公式計算結果,向上或向下靠近2的n次方數值進行存儲池的PG總數選取。
對于多存儲池的複雜場景,可以參考 Ceph官方推薦的電腦。
2.3.2 PG 的狀态機
PG狀态的遷移通過狀态機來驅動,我們先看一下PG狀态機的主要事件定義,見表2-2。
表2-2 PG狀态機
Activating | Peering 已經完成,PG 正在等待所有 PG 執行個體同步并固化 Peering 的結果(Info、log等) |
Active | 活躍态。PG 可以正常處理來自用戶端的讀寫請求 |
Backfilling | 正在背景填充态。Backfill是 Recovery的一種特殊場景,指 peering 完成後,如果基于目前權威日志無法對 UpSet 當中的某些 PG 執行個體實施增量同步(例如承載這些 PG 執行個體的 OSD 離線太久, 或者是新的 OSD 加入叢集導緻的 PG 執行個體整體遷移), 則通過完全複制目前Primary所有對象的方式進行全量同步 |
Backfill-toofull | 某個需要被 Backfill 的 PG執行個體,其所在的 OSD 可用空間不足,Backfill流程目前被挂起 |
Backfill-wait | 等待 Backfill 資源預留 |
Clean | 幹淨态。PG 目前不存在待修複的對象,Acting Set 和Up Set 内容一緻,并且大小等于存儲池的副本數 |
Creating | PG 正在被建立 |
Deep | PG 正在或者即将進行對象一緻性掃描清洗 |
Degraded | 降級狀态,Peering 完成後,PG 檢測到任意一個PG執行個體存在不一緻(需要被同步/修複)的對象,或者目前Acting Set 小于存儲池副本數 |
Down | Peering 過程中,PG 檢測到某個不能被跳過的 Interval 中(例如該 Interval 期間,PG 完成了 Peering,并且成功切換至 Active 狀态,進而有可能正常處理了來自用戶端的讀寫請求),目前剩餘線上的 OSD 不足以完成資料修複 |
Incomplete | Peering 過程中,由于 a. 無法選出權威日志;b. 通過 choose_acting 選出的 ActingSet 後續不足以完成資料修複,導緻 Peering 無法正常完成 |
Inconsistent | 不一緻态,叢集清理和深度清理後檢測到PG 中的對象副本存在不一緻,例如對象的檔案大小不一緻或Recovery結束後一個對象的副本丢失 |
Peered | Peering 已經完成,但是 PG目前Acting Set規模小于存儲池規定的最小副本數(min_size) |
Peering | 正在同步态。PG 正在執行同步處理 |
Recovering | 正在恢複态。叢集正在執行遷移或同步對象和它們的副本 |
Recovering-wait | 等待Recovery資源預留 |
續表
Remapped | 重新映射态。PG 活動集任何的一個改變,資料發生從老活動集到新活動集的遷移。在遷移期間還是用老的活動集中的主OSD 處理用戶端請求,一旦遷移完成,新活動集中的主 OSD開始處理 |
Repair | PG 在執行Scrub 過程中,如果發現存在不一緻的對象,并且能夠修複,則自動進入修複狀态 |
Scrubbing | PG 正在或者即将進行對象一緻性掃描 |
Inactive | 非活躍态。PG不能處理讀寫請求 |
Unclean | 非幹淨态。PG不能從上一個失敗中恢複 |
Stale | 未重新整理态。PG狀态沒有被任何 OSD 更新,這說明所有存儲這個PG 的 OSD 可能挂掉,或者Mon沒有檢測到 Primary統計資訊(網絡抖動) |
Undersized | PG 目前的ActingSet 小于存儲池副本數 |
需要注意的是,這些狀态并不是互斥的,某些時刻PG可能處于多個狀态的疊加中,例如 Active+ Clean 表示一切正常,Active+ Degraded+ Recovering表明 PG存在降級對象并且正在執行修複等。叢集拓撲或者狀态的變化,例如 OSD加入和删除、OSD宕掉或恢複、存儲池建立和删除等,最終都會轉化為狀态機中的事件,這些事件會驅動狀态機 在不同狀态之間進行跳轉。
以下幾個狀态在叢集日常運作及運維中較為常見,簡要介紹一下。
◆ Peering
Peering指的是 PG包含的備援組中的所有對象達到一緻性的過程,Peering時間的長短并不可控,主要是在于請求的OSD是否能夠及時響應;如果這個階段某個 OSD宕掉,很可能導緻部分 PG一直處在 Peering 狀态,即所有分布到這個 PG上的 I/O 都會阻塞。
◆ Degraded
降級狀态,如在副本模式下(size參數配置為3),每個PG有3個副本,分别儲存在不同的 OSD守護程序中。在非故障情況下,這個PG是 Active+clean狀态,一旦出現OSD守護程序離線,PG的副本數就會小于3,PG就轉變為了 Degraded降級狀态。
◆ Peered
Peering已經完成,PG等待其他副本(OSD守護程序)上線狀态,此狀态下 PG不可對外提供服務。
結合上述 Degraded狀态,PG目前存活副本數大于或等于存儲池規定的最小副本數(min_size,通常設定為2),PG為Active+Undersized+Degraded狀态,仍可對外提供I/O服務;PG目前存活副本數小于存儲池規定的最小副本數(min_size),PG為Undersized+Degraded+Peered狀态,不可對外提供 I/O服務。
◆ Remapped
Peering 已經完成,PG目前的 ActingSet與 UpSet 不一緻就會出現 Remapped 狀态,此狀态下的 PG 正在進行資料的自我修複。該狀态下,PG 可以進行正常的 I/O 讀寫。
上述讨論 Peered狀态時,如果 PG内的另外兩個 OSD 守護程序對應的存儲媒體損壞,将其移出存儲叢集後,Ceph會将PG 内的資料從僅存的OSD 上向叢集内其他的OSD進行遷移(PG的重映射),丢失的資料是要從僅存的OSD上回填到新的OSD上的,處于回填狀态的PG就會被标記為 Backfilling。
◆ Recovery
Ceph基于 PG 級别的日志保證副本之間的資料一緻性,Recovery指對應副本能夠通過日志(PGLog1)進行恢複,即隻需要修複該副本上與權威日志不同步的那部分對象,即可完成存儲系統内資料的整體恢複。
Recovery 有兩種恢複方式。
(1) Pull:指 Primary自身存在降級的對象,由 Primary按照 missing_loc選擇合适的副本去拉取降級對象的權威日志到本地,然後完成修複。
(2) Push:指Primary 感覺到一個或者多個副本目前存在降級對象,主動推送每個降級對象的權威版本至相應的副本,然後再由副本本地完成修複。
為了修複副本,Primary必須先完成自我修複,即通常情況下,總是先執行Pull操作,再執行 Push的操作(但是如果用戶端正好需要改寫某個隻在從副本上處于降級狀态的對象,那麼此時 PG會強制通過Push 的方式優先修複對象,以避免長時間阻塞用戶端的相關請求)。另一個必須這樣處理的原因在于,用戶端的請求,都是由 Primary統一處理的, 為了及時響應用戶端的請求, 也必須優先恢複 Primary的本地資料。完成自我修複後,Primary可以着手修複各個副本中的降級對象。因為在此前的 Peering過程中,Primary已經為每個副本生成了完整的missing清單, 可以據此逐個副本完成修複。
用戶端發起讀請求,待通路的對象在一個或者多個副本上處于降級狀态,對應的讀請求可以直接在 Primary上完成,對象僅僅在副本上降級,無任何影響。如果 Primary上也處于降級狀态,需要等 Primary完成修複,才能繼續。
1記錄的 PGLog在osd_max_pg_log_entries=10000條以内,這個時候通過 PGLog就能增量恢複數