㈠ Ceph分布式存儲是怎麼防止腦裂的
解決腦裂問題,通常採用隔離(Fencing)機制,包括三個方面:
共享存儲fencing:確保只有一個Master往共享存儲中寫數據。
客戶端fencing:確保只有一個Master可以響應客戶端的請求。
Slave fencing:確保只有一個Master可以向Slave下發命令。
Hadoop公共庫中對外提供了兩種fenching實現,分別是sshfence和shellfence(預設實現),其中sshfence是指通過ssh登陸目標Master節點上,使用命令fuser將進程殺死(通過tcp埠號定位進程pid,該方法比jps命令更准確),shellfence是指執行一個用戶事先定義的shell命令(腳本)完成隔離。
切換對外透明:為了保證整個切換是對外透明的,Hadoop應保證所有客戶端和Slave能自動重定向到新的active master上,這通常是通過若干次嘗試連接舊master不成功後,再重新嘗試鏈接新master完成的,整個過程有一定延遲。在新版本的Hadoop RPC中,用戶可自行設置RPC客戶端嘗試機制、嘗試次數和嘗試超時時間等參數。
在「雙機熱備」高可用(HA)系統中,當聯系2個節點的「心跳線」斷開時,本來為一整體、動作協調的HA系統,就分裂成為2個獨立的個體。由於相互失去了聯系,都以為是對方出了故障,2個節點上的HA軟體像「裂腦人」一樣,「本能」地爭搶「共享資源」、爭起「應用服務」,就會發生嚴重後果:或者共享資源被瓜分、2邊「服務」都起不來了;或者2邊「服務」都起來了,但同時讀寫「共享存儲」,導致數據損壞(常見如資料庫輪詢著的聯機日誌出錯)。
運行於備用主機上的Heartbeat可以通過乙太網連接檢測主伺服器的運行狀態,一旦其無法檢測到主伺服器的「心跳」則自動接管主伺服器的資源。通常情況下,主、備伺服器間的心跳連接是一個獨立的物理連接,這個連接可以是串列線纜、一個由「交叉線」實現的乙太網連接。Heartbeat甚至可同時通過多個物理連接檢測主伺服器的工作狀態,而其只要能通過其中一個連接收到主伺服器處於活動狀態的信息,就會認為主伺服器處於正常狀態。從實踐經驗的角度來說,建議為Heartbeat配置多條獨立的物理連接,以避免Heartbeat通信線路本身存在單點故障。
1、串列電纜:被認為是比乙太網連接安全性稍好些的連接方式,因為hacker無法通過串列連接運行諸如telnet、ssh或rsh類的程序,從而可以降低其通過已劫持的伺服器再次侵入備份伺服器的幾率。但串列線纜受限於可用長度,因此主、備伺服器的距離必須非常短。
2、乙太網連接:使用此方式可以消除串列線纜的在長度方面限制,並且可以通過此連接在主備伺服器間同步文件系統,從而減少了從正常通信連接帶寬的佔用。
基於冗餘的角度考慮,應該在主、備伺服器使用兩個物理連接傳輸heartbeat的控制信息;這樣可以避免在一個網路或線纜故障時導致兩個節點同時認為自已是唯一處於活動狀態的伺服器從而出現爭用資源的情況,這種爭用資源的場景即是所謂的「腦裂」(split-brain)或「partitioned cluster」。在兩個節點共享同一個物理設備資源的情況下,腦裂會產生相當可怕的後果。
為了避免出現腦裂,可採用下面的預防措施:
添加冗餘的心跳線,例如雙線條線。盡量減少「裂腦」發生機會。
啟用磁碟鎖。正在服務一方鎖住共享磁碟,「裂腦」發生時,讓對方完全「搶不走」共享磁碟資源。但使用鎖磁碟也會有一個不小的問題,如果佔用共享盤的一方不主動「解鎖」,另一方就永遠得不到共享磁碟。現實中假如服務節點突然死機或崩潰,就不可能執行解鎖命令。後備節點也就接管不了共享資源和應用服務。於是有人在HA中設計了「智能」鎖。即,正在服務的一方只在發現心跳線全部斷開(察覺不到對端)時才啟用磁碟鎖。平時就不上鎖了。
設置仲裁機制。例如設置參考IP(如網關IP),當心跳線完全斷開時,2個節點都各自ping一下 參考IP,不通則表明斷點就出在本端,不僅「心跳」、還兼對外「服務」的本端網路鏈路斷了,即使啟動(或繼續)應用服務也沒有用了,那就主動放棄競爭,讓能夠ping通參考IP的一端去起服務。更保險一些,ping不通參考IP的一方乾脆就自我重啟,以徹底釋放有可能還佔用著的那些共享資源。
㈡ Ceph:一個 Linux PB 級分布式文件系統
Ceph 最初是一項關於存儲系統的 PhD 研究項目,由 Sage Weil 在 University of California, Santa Cruz(UCSC)實施。但是到了 2010 年 3 月底,您可以在主線 Linux 內核(從 2.6.34 版開始)中找到 Ceph 的身影。雖然 Ceph 可能還不適用於生產環境,但它對測試目的還是非常有用的。本文探討了 Ceph 文件系統及其獨有的功能,這些功能讓它成為可擴展分布式存儲的最有吸引力的備選。
「Ceph」 對一個文件系統來說是個奇怪的名字,它打破了大多數人遵循的典型縮寫趨勢。這個名字和 UCSC(Ceph 的誕生地)的吉祥物有關,這個吉祥物是 「Sammy」,一個香蕉色的蛞蝓,就是頭足類中無殼的軟體動物。這些有多觸角的頭足類動物,提供了一個分布式文件系統的最形象比喻。
開發一個分布式文件系統需要多方努力,但是如果能准確地解決問題,它就是無價的。Ceph 的目標簡單地定義為:
不幸的是,這些目標之間會互相競爭(例如,可擴展性會降低或者抑制性能或者影響可靠性)。Ceph 開發了一些非常有趣的概念(例如,動態元數據分區,數據分布和復制),這些概念在本文中只進行簡短地探討。Ceph 的設計還包括保護單一點故障的容錯功能,它假設大規模(PB 級存儲)存儲故障是常見現象而不是例外情況。最後,它的設計並沒有假設某種特殊工作負載,但是包括適應變化的工作負載,提供最佳性能的能力。它利用 POSIX 的兼容性完成所有這些任務,允許它對當前依賴 POSIX 語義(通過以 Ceph 為目標的改進)的應用進行透明的部署。最後,Ceph 是開源分布式存儲,也是主線 Linux 內核(2.6.34)的一部分。
現在,讓我們探討一下 Ceph 的架構以及高端的核心要素。然後我會拓展到另一層次,說明 Ceph 中一些關鍵的方面,提供更詳細的探討。
Ceph 生態系統可以大致劃分為四部分(見圖 1):客戶端(數據用戶),元數據伺服器(緩存和同步分布式元數據),一個對象存儲集群(將數據和元數據作為對象存儲,執行其他關鍵職能),以及最後的集群監視器(執行監視功能)。
如圖 1 所示,客戶使用元數據伺服器,執行元數據操作(來確定數據位置)。元數據伺服器管理數據位置,以及在何處存儲新數據。值得注意的是,元數據存儲在一個存儲集群(標為 「元數據 I/O」)。實際的文件 I/O 發生在客戶和對象存儲集群之間。這樣一來,更高層次的 POSIX 功能(例如,打開、關閉、重命名)就由元數據伺服器管理,不過 POSIX 功能(例如讀和寫)則直接由對象存儲集群管理。
另一個架構視圖由圖 2 提供。一系列伺服器通過一個客戶界面訪問 Ceph 生態系統,這就明白了元數據伺服器和對象級存儲器之間的關系。分布式存儲系統可以在一些層中查看,包括一個存儲設備的格式(Extent and B-tree-based Object File System [EBOFS] 或者一個備選),還有一個設計用於管理數據復制,故障檢測,恢復,以及隨後的數據遷移的覆蓋管理層,叫做 Reliable Autonomic Distributed Object Storage (RADOS)。最後,監視器用於識別組件故障,包括隨後的通知。
了解了 Ceph 的概念架構之後,您可以挖掘到另一個層次,了解在 Ceph 中實現的主要組件。Ceph 和傳統的文件系統之間的重要差異之一就是,它將智能都用在了生態環境而不是文件系統本身。
圖 3 顯示了一個簡單的 Ceph 生態系統。Ceph Client 是 Ceph 文件系統的用戶。Ceph Metadata Daemon 提供了元數據伺服器,而 Ceph Object Storage Daemon 提供了實際存儲(對數據和元數據兩者)。最後,Ceph Monitor 提供了集群管理。要注意的是,Ceph 客戶,對象存儲端點,元數據伺服器(根據文件系統的容量)可以有許多,而且至少有一對冗餘的監視器。那麼,這個文件系統是如何分布的呢?
早期版本的 Ceph 利用在 User SpacE(FUSE)的 Filesystems,它把文件系統推入到用戶空間,還可以很大程度上簡化其開發。但是今天,Ceph 已經被集成到主線內核,使其更快速,因為用戶空間上下文交換機對文件系統 I/O 已經不再需要。
因為 Linux 顯示文件系統的一個公共界面(通過虛擬文件系統交換機 [VFS]),Ceph 的用戶透視圖就是透明的。管理員的透視圖肯定是不同的,考慮到很多伺服器會包含存儲系統這一潛在因素(要查看更多創建 Ceph 集群的信息,見 參考資料 部分)。從用戶的角度看,他們訪問大容量的存儲系統,卻不知道下面聚合成一個大容量的存儲池的元數據伺服器,監視器,還有獨立的對象存儲設備。用戶只是簡單地看到一個安裝點,在這點上可以執行標准文件 I/O。
Ceph 文件系統 — 或者至少是客戶端介面 — 在 Linux 內核中實現。值得注意的是,在大多數文件系統中,所有的控制和智能在內核的文件系統源本身中執行。但是,在 Ceph 中,文件系統的智能分布在節點上,這簡化了客戶端介面,並為 Ceph 提供了大規模(甚至動態)擴展能力。
Ceph 使用一個有趣的備選,而不是依賴分配列表(將磁碟上的塊映射到指定文件的元數據)。Linux 透視圖中的一個文件會分配到一個來自元數據伺服器的 inode number(INO),對於文件這是一個唯一的標識符。然後文件被推入一些對象中(根據文件的大小)。使用 INO 和 object number(ONO),每個對象都分配到一個對象 ID(OID)。在 OID 上使用一個簡單的哈希,每個對象都被分配到一個放置組。 放置組 (標識為 PGID)是一個對象的概念容器。最後,放置組到對象存儲設備的映射是一個偽隨機映射,使用一個叫做 Controlled Replication Under Scalable Hashing (CRUSH)的演算法。這樣一來,放置組(以及副本)到存儲設備的映射就不用依賴任何元數據,而是依賴一個偽隨機的映射函數。這種操作是理想的,因為它把存儲的開銷最小化,簡化了分配和數據查詢。
分配的最後組件是集群映射。 集群映射 是設備的有效表示,顯示了存儲集群。有了 PGID 和集群映射,您就可以定位任何對象。
元數據伺服器(cmds)的工作就是管理文件系統的名稱空間。雖然元數據和數據兩者都存儲在對象存儲集群,但兩者分別管理,支持可擴展性。事實上,元數據在一個元數據伺服器集群上被進一步拆分,元數據伺服器能夠自適應地復制和分配名稱空間,避免出現熱點。如圖 4 所示,元數據伺服器管理名稱空間部分,可以(為冗餘和性能)進行重疊。元數據伺服器到名稱空間的映射在 Ceph 中使用動態子樹邏輯分區執行,它允許 Ceph 對變化的工作負載進行調整(在元數據伺服器之間遷移名稱空間)同時保留性能的位置。
但是因為每個元數據伺服器只是簡單地管理客戶端人口的名稱空間,它的主要應用就是一個智能元數據緩存(因為實際的元數據最終存儲在對象存儲集群中)。進行寫操作的元數據被緩存在一個短期的日誌中,它最終還是被推入物理存儲器中。這個動作允許元數據伺服器將最近的元數據回饋給客戶(這在元數據操作中很常見)。這個日誌對故障恢復也很有用:如果元數據伺服器發生故障,它的日誌就會被重放,保證元數據安全存儲在磁碟上。
元數據伺服器管理 inode 空間,將文件名轉變為元數據。元數據伺服器將文件名轉變為索引節點,文件大小,和 Ceph 客戶端用於文件 I/O 的分段數據(布局)。
Ceph 包含實施集群映射管理的監視器,但是故障管理的一些要素是在對象存儲本身中執行的。當對象存儲設備發生故障或者新設備添加時,監視器就檢測和維護一個有效的集群映射。這個功能按一種分布的方式執行,這種方式中映射升級可以和當前的流量通信。Ceph 使用 Paxos,它是一系列分布式共識演算法。
和傳統的對象存儲類似,Ceph 存儲節點不僅包括存儲,還包括智能。傳統的驅動是只響應來自啟動者的命令的簡單目標。但是對象存儲設備是智能設備,它能作為目標和啟動者,支持與其他對象存儲設備的通信和合作。
從存儲角度來看,Ceph 對象存儲設備執行從對象到塊的映射(在客戶端的文件系統層中常常執行的任務)。這個動作允許本地實體以最佳方式決定怎樣存儲一個對象。Ceph 的早期版本在一個名為 EBOFS 的本地存儲器上實現一個自定義低級文件系統。這個系統實現一個到底層存儲的非標准介面,這個底層存儲已針對對象語義和其他特性(例如對磁碟提交的非同步通知)調優。今天,B-tree 文件系統(BTRFS)可以被用於存儲節點,它已經實現了部分必要功能(例如嵌入式完整性)。
因為 Ceph 客戶實現 CRUSH,而且對磁碟上的文件映射塊一無所知,下面的存儲設備就能安全地管理對象到塊的映射。這允許存儲節點復制數據(當發現一個設備出現故障時)。分配故障恢復也允許存儲系統擴展,因為故障檢測和恢復跨生態系統分配。Ceph 稱其為 RADOS(見 圖 3 )。
如果文件系統的動態和自適應特性不夠,Ceph 還執行一些用戶可視的有趣功能。用戶可以創建快照,例如,在 Ceph 的任何子目錄上(包括所有內容)。文件和容量計算可以在子目錄級別上執行,它報告一個給定子目錄(以及其包含的內容)的存儲大小和文件數量。
雖然 Ceph 現在被集成在主線 Linux 內核中,但只是標識為實驗性的。在這種狀態下的文件系統對測試是有用的,但是對生產環境沒有做好准備。但是考慮到 Ceph 加入到 Linux 內核的行列,還有其創建人想繼續研發的動機,不久之後它應該就能用於解決您的海量存儲需要了。
Ceph 在分布式文件系統空間中並不是唯一的,但它在管理大容量存儲生態環境的方法上是獨一無二的。分布式文件系統的其他例子包括 Google File System(GFS),General Parallel File System(GPFS),還有 Lustre,這只提到了一部分。Ceph 背後的想法為分布式文件系統提供了一個有趣的未來,因為海量級別存儲導致了海量存儲問題的唯一挑戰。
㈢ ceph:rados淺析
在傳統分布式存儲架構中,存儲節點往往僅作為被動查詢對象來使用,隨著存儲規模的增加,數據一致性的管理會出現很多問題。
而新型的存儲架構傾向於將基本的塊分配決策和安全保證等操作交給存儲節點來做,然後通過提倡客戶端和存儲節點直接交互來簡化數據布局並減小io瓶頸。
RADOS就是這樣一個可用於PB級規模數據存儲集群的可伸縮的、可靠的對象存儲服務。它包含兩類節點:存儲節點、管理節點。它通過利用存儲設備的智能性,將諸如一致性數據訪問、冗餘存儲、錯誤檢測、錯誤恢復分布到包含了上千存儲節點的集群中,而不是僅僅依靠少數管理節點來處理。
RADOS中的存儲節點被稱為OSD(object storage device),它可以僅由很普通的組件來構成,只需要包含CPU、網卡、本地緩存和一個磁碟或者RAID,並將傳統的塊存儲方式替換成面向對象的存儲。
在PB級的存儲規模下,存儲系統一定是動態的:系統會隨著新設備的部署和舊設備的淘汰而增長或收縮,系統內的設備會持續地崩潰和恢復,大量的數據被創建或者刪除。RADOS通過 cluster map來實現這些,cluster map會被復制到集群中的所有部分(存儲節點、控制節點,甚至是客戶端),並且通過怠惰地傳播小增量更新而更新。cluster map中存儲了整個集群的數據的分布以及成員。
通過在每個存儲節點存儲完整的cluster map,存儲設備可以表現的半自動化,通過peer-to-peer的方式(比如定義協議)來進行數據備份、更新,錯誤檢測、數據遷移等等操作。這無疑減輕了佔少數的monitor cluster(管理節點組成的集群)的負擔。
一個RADOS系統包含大量的OSDs 和 很少的用於管理OSD集群成員的monitors。OSD的組成如簡介所說。而monitor是一些獨立的進程,以及少量的本地存儲,monitor之間通過一致性演算法保證數據的一致性。
存儲節點集群通過monitor集群操作cluster map來實現成員的管理。cluster map 描述了哪些OSD被包含進存儲集群以及所有數據在存儲集群中的分布。
cluster map不僅存儲在monitor節點,它被復制到集群中的每一個存儲節點,以及和集群交互的client。
當因為一些原因,比如設備崩潰、數據遷移等,cluster map的內容需要改變時,cluster map的版本號被增加,map的版本號可以使通信的雙方確認自己的map是否是最新的,版本舊的一方會先將map更新成對方的map,然後才會進行後續操作。
首先,如下圖,總體說下RADOS的存儲層次,RADOS中基本的存儲單位是對象,一般為2MB或4MB,當一個文件要存入RADOS時,首先會被切分成大小固定的對象(最後一個對象大小可能不同),然後將對象分配到一個PG(Placement Group)中,然後PG會復制幾份,偽隨機地派給不同的存儲節點。當新的存儲節點被加入集群,會在已有數據中隨機抽取一部分數據遷移到新節點。這種概率平衡的分布方式可以保證設備在潛在的高負載下正常工作。更重要的是,數據的分布過程僅需要做幾次隨機映射,不需要大型的集中式分配表。
對於每個層次的詳細說明:
2.Object—— RADOS的基本存儲單元。Object與上面提到的file的區別是,object的最大size由RADOS限定(通常為2MB或4MB),以便實現底層存儲的組織管理。因此,當上層應用向RADOS存入size很大的file時,需要將file切分成統一大小的一系列object(最後一個的大小可以不同)進行存儲。
各層次之間的映射關系:
前面的介紹中已經提到,由若干個monitor共同負責整個RADOS集群中所有OSD狀態的發現與記錄,並且共同形成cluster map的master版本,然後擴散至全體OSD以及client。OSD使用cluster map進行數據的維護,而client使用cluster map進行數據的定址。
monitor並不主動輪詢各個OSD的當前狀態。相反,OSD需要向monitor上報狀態信息。常見的上報有兩種情況:一是新的OSD被加入集群,二是某個OSD發現自身或者其他OSD發生異常。在收到這些上報信息後,monitor將更新cluster map信息並加以擴散。其細節將在下文中加以介紹。
Cluster map的實際內容包括:
(1) Epoch,即版本號。cluster map的epoch是一個單調遞增序列。epoch越大,則cluster map版本越新。因此,持有不同版本cluster map的OSD或client可以簡單地通過比較epoch決定應該遵從誰手中的版本。而monitor手中必定有epoch最大、版本最新的cluster map。當任意兩方在通信時發現彼此epoch值不同時,將默認先將cluster map同步至高版本一方的狀態,再進行後續操作。
(2)各個OSD的網路地址。
(3)各個OSD的狀態。OSD狀態的描述分為兩個維度:up或者down(表明OSD是否正常工作),in或者out(表明OSD是否在至少一個PG中)。因此,對於任意一個OSD,共有四種可能的狀態:
(4)CRUSH演算法配置參數。表明了Ceph集群的物理層級關系(cluster hierarchy),位置映射規則(placement rules)。
根據cluster map的定義可以看出,其版本變化通常只會由(3)和(4)兩項信息的變化觸發。而這兩者相比,(3)發生變化的概率更高一些。這可以通過下面對OSD工作狀態變化過程的介紹加以反映。
一個新的OSD上線後,首先根據配置信息與monitor通信。Monitor將其加入cluster map,並設置為up且out狀態,再將最新版本的cluster map發給這個新OSD。
收到monitor發來的cluster map之後,這個新OSD計算出自己所承載的PG(為簡化討論,此處我們假定這個新的OSD開始只承載一個PG),以及和自己承載同一個PG的其他OSD。然後,新OSD將與這些OSD取得聯系。如果這個PG目前處於降級狀態(即承載該PG的OSD個數少於正常值,如正常應該是3個,此時只有2個或1個。這種情況通常是OSD故障所致),則其他OSD將把這個PG內的所有對象和元數據復制給新OSD。數據復制完成後,新OSD被置為up且in狀態。而cluster map內容也將據此更新。這事實上是一個自動化的failure recovery過程。當然,即便沒有新的OSD加入,降級的PG也將計算出其他OSD實現failure recovery。
如果該PG目前一切正常,則這個新OSD將替換掉現有OSD中的一個(PG內將重新選出Primary OSD),並承擔其數據。在數據復制完成後,新OSD被置為up且in狀態,而被替換的OSD將退出該PG(但狀態通常仍然為up且in,因為還要承載其他PG)。而cluster map內容也將據此更新。這事實上是一個自動化的數據re-balancing過程。
如果一個OSD發現和自己共同承載一個PG的另一個OSD無法聯通,則會將這一情況上報monitor。此外,如果一個OSD deamon發現自身工作狀態異常,也將把異常情況主動上報給monitor。在上述情況下,monitor將把出現問題的OSD的狀態設為down且in。如果超過某一預訂時間期限,該OSD仍然無法恢復正常,則其狀態將被設置為down且out。反之,如果該OSD能夠恢復正常,則其狀態會恢復為up且in。在上述這些狀態變化發生之後,monitor都將更新cluster map並進行擴散。這事實上是自動化的failure detection過程。
對於一個RADOS集群而言,即便由數千個甚至更多OSD組成,cluster map的數據結構大小也並不驚人。同時,cluster map的狀態更新並不會頻繁發生。即便如此,Ceph依然對cluster map信息的擴散機制進行了優化,以便減輕相關計算和通信壓力:
基於上述機制,Ceph避免了由於cluster map版本更新而引起的廣播風暴。這雖然是一種非同步且lazy的機制,但根據論文中的結論,對於一個由n個OSD組成的Ceph集群,任何一次版本更新能夠在O(log(n))時間復雜度內擴散到集群中的任何一個OSD上。
一個可能被問到的問題是:既然這是一種非同步和lazy的擴散機制,則在版本擴散過程中,系統必定出現各個OSD看到的cluster map不一致的情況,這是否會導致問題?答案是:不會。事實上,如果一個client和它要訪問的PG內部的各個OSD看到的cluster map狀態一致,則訪問操作就可以正確進行。而如果這個client或者PG中的某個OSD和其他幾方的cluster map不一致,則根據Ceph的機制設計,這幾方將首先同步cluster map至最新狀態,並進行必要的數據re-balancing操作,然後即可繼續正常訪問。
㈣ ceph分布式存儲-常見 PG 故障處理
創建一個新集群後,PG 的狀態一直處於 active , active + remapped 或 active + degraded 狀態, 而無法達到 active + clean 狀態 ,那很可能是你的配置有問題。
你可能需要檢查下集群中有關 Pool 、 PG 和 CRUSH 的配置項,做以適當的調整。
一般來說,你的集群中需要多於 1 個 OSD,並且存儲池的 size 要大於 1 副本。
有時候,我們需要搭建一個單節點的 Ceph 實驗環境。此時,在開始創建 monitor 和 OSD 之前,你需要把 Ceph 配置文件中的 osd crush chooseleaf type 選項從默認值 1 (表示 host 或 node )修改為 0 (表示 osd )。這樣做是告訴 Ceph 允許把數據的不同副本分布到同一 host 的 OSDs 上。
如果你已經啟動了 2 個 OSD,它們都處於 up 和 in 的狀態,但 PG 仍未達到 active + clean 狀態,那可能是給 osd pool default size 設置了一個大於 2 的值。
如果你想要在 active + degraded 狀態( 2 副本)操作你的集群,可以設置 osd pool default min size 為 2 ,這樣你就可以對處於 active + degraded 的對象寫入數據。然後你還可以把 osd pool default size 的值改為 2 ,這樣集群就可以達到 active + clean 狀態了。
另外,修改參數 osd pool default size/min_size 後,只會對後面新建的 pool 起作用。如果想修改已存在的 pool 的 size/min_size ,可用下面的命令:
注意: 你可以在運行時修改參數值。如果是在 Ceph 配置文件中進行的修改,你可能需要重啟集群。
如果你設置了 osd pool default size 的值為 1 ,那你就僅有對象的單份拷貝。OSD 依賴於其他 OSD 告訴自己應該保存哪些對象。如果第一個 OSD 持有對象的拷貝,並且沒有第二份拷貝,那麼也就沒有第二個 OSD 去告訴第一個 OSD 它應該保管那份拷貝。對於每一個映射到第一個 OSD 上的 PG (參考 ceph pg mp 的輸出),你可以強制第一個 OSD 關注它應該保存的 PGs :
PG 達不到 clean 狀態的另一個可能的原因就是集群的 CRUSH Map 有錯誤,導致 PG 不能映射到正確的地方。
有失敗發生後,PG 會進入「degraded」(降級)或「peering」(連接建立中)狀態,這種情況時有發生。通常這些狀態意味著正常的失敗恢復正在進行。然而,如果一個 PG 長時間處於這些狀態中的某個,就意味著有更大的問題。因此 monitor 在 PG 卡 ( stuck ) 在非最優狀態時會告警。我們具體檢查:
你可以用下列命令顯式地列出卡住的 PGs:
卡在 stale 狀態的 PG 通過重啟 ceph-osd 進程通常可以修復;卡在 inactive 狀態的 PG 通常是互聯問題(參見 PG 掛了 —— 互聯失敗 );卡在 unclean 狀態的 PG 通常是由於某些原因阻止了恢復的完成,像未找到的對象(參見 未找到的對象 )。
在某些情況下, ceph-osd 互聯 進程會遇到問題,阻值 PG 達到活躍、可用的狀態。例如, ceph health 也許顯示:
可以查詢到 PG 為何被標記為 down :
recovery_state 段告訴我們互聯過程因 ceph-osd 進程掛了而被阻塞,本例是 osd.1 掛了,啟動這個進程應該就可以恢復。
或者,如果 osd.1 發生了災難性的失敗(如硬碟損壞),我們可以告訴集群它丟失( lost )了,讓集群盡力完成副本拷貝。
重要: 集群不能保證其它數據副本是一致且最新的,就會很危險!
讓 Ceph 無論如何都繼續:
恢復將繼續進行。
某幾種失敗相組合,可能導致 Ceph 抱怨有找不到( unfound )的對象:
這意味著存儲集群知道一些對象(或者存在對象的較新副本)存在,卻沒有找到它們的副本。下例展示了這種情況是如何發生的,一個 PG 的數據存儲在 ceph-osd 1 和 2 上:
這時, 1 知道這些對象存在,但是活著的 ceph-osd 都沒有這些副本。這種情況下,讀寫這些對象的 IO 就會被阻塞,集群只能指望 down 掉的節點盡早恢復。這樣處理是假設比直接給用戶返回一個 IO 錯誤要好一些。
首先,你應該確認哪些對象找不到了:
如果在一次查詢里列出的對象太多, more 這個欄位將為 true ,你就可以查詢更多。
其次,你可以找出哪些 OSD 上探測到、或可能包含數據:
本例中,集群知道 osd.1 可能有數據,但它掛了( down )。所有可能的狀態有:
有時候集群要花一些時間來查詢可能的位置。
還有一種可能性,對象存在於其它位置卻未被列出。例如,集群里的一個 ceph-osd 停止且被剔出集群,然後集群完全恢復了;後來一系列的失敗導致了未找到的對象,它也不會覺得早已死亡的 ceph-osd 上仍可能包含這些對象。(這種情況幾乎不太可能發生)。
如果所有可能的位置都查詢過了但仍有對象丟失,那就得放棄丟失的對象了。這仍可能是罕見的失敗組合導致的,集群在寫操作恢復後,未能得知寫入是否已執行。以下命令把未找到的( unfound )對象標記為丟失( lost )。
上述最後一個參數告訴集群應如何處理丟失的對象。
擁有 PG 拷貝的 OSD 可能會全部失敗,這種情況下,那一部分的對象存儲不可用, monitor 也就不會收到那些 PG 的狀態更新了。為檢測這種情況,monitor 會把任何主 OSD 失敗的 PG 標記為 stale (不新鮮),例如:
可以找出哪些 PG 是 stale 狀態,和存儲這些歸置組的最新 OSD ,命令如下:
如果想使 PG 2.5 重新上線,例如,上面的輸出告訴我們它最後由 osd.0 和 osd.2 管理,重啟這些 ceph-osd 將恢復之(可以假定還有其它的很多 PG 也會進行恢復 )。
如果你的集群有很多節點,但只有其中幾個接收數據, 檢查 下存儲池裡的 PG 數量。因為 PG 是映射到多個 OSD 的,較少的 PG 將不能均衡地分布於整個集群。試著創建個新存儲池,設置 PG 數量是 OSD 數量的若干倍。更詳細的信息可以參考 Ceph 官方文檔 —— Placement Groups 。
如果你的集群已啟動,但一些 OSD 沒起來,導致不能寫入數據,確認下運行的 OSD 數量滿足 PG 要求的最低 OSD 數。如果不能滿足, Ceph 就不會允許你寫入數據,因為 Ceph 不能保證復制能如願進行。這個最低 OSD 個數是由參數 osd pool default min size 限定的。
如果收到 active + clean + inconsistent 這樣的狀態,很可能是由於在對 PG 做擦洗( scrubbing )時發生了錯誤。如果是由於磁碟錯誤導致的不一致,請檢查磁碟,如果磁碟有損壞,可能需要將這個磁碟對應的 OSD 踢出集群,然後進行更換。生產環境中遇到過不一致的問題,就是由於磁碟壞道導致的。
當集群中出現 PG 不一致的問題時,執行 ceph -s 命令會出現下面的信息:
1、查找處於 inconsistent 狀態的問題 PG :
這個有問題的 PG 分布在 osd.1 、 osd.2 和 osd.0 上,其中 osd.1 是主 OSD。
2、去主 OSD( osd.1 )的日誌中查找不一致的具體對象 。
從日誌中可以知道,是 rbd_data.1349f035c101d9.0000000000000001 這個對象的屬性 _ 丟失了,所以在 scrub 的過程中產生了 error 。
3、執行 ceph pg repair 命令修復問題 PG 。
4、檢查 Ceph 集群是否恢復到 HEALTH_OK 狀態。
osd.1 的日誌里也提示修復成功:
如果經過前面的步驟,Ceph 仍沒有達到 HEALTH_OK 狀態,可以嘗試用下面這種方式進行修復。
1、停掉不一致的 object 所屬的 osd 。
2、刷新該 osd 的日誌。
3、將不一致的 object 移除。
4、重新啟動該 osd 。
5、重新執行修復命令。
6、檢查 Ceph 集群是否恢復到 HEALTH_OK 狀態。
有時候,我們在 ceph -s 的輸出中可以看到如下的告警信息:
這是因為集群 OSD 數量較少,測試過程中建立了多個存儲池,每個存儲池都要建立一些 PGs 。而目前 Ceph 配置的默認值是每 OSD 上最多有 300 個 PGs 。在測試環境中,為了快速解決這個問題,可以調大集群的關於此選項的告警閥值。方法如下:
在 monitor 節點的 ceph.conf 配置文件中添加:
然後重啟 monitor 進程。
或者直接用 tell 命令在運行時更改參數的值而不用重啟服務:
而另一種情況, too few PGs per OSD (16 < min 20) 這樣的告警信息則往往出現在集群剛剛建立起來,除了默認的 rbd 存儲池,還沒建立自己的存儲池,再加上 OSD 個數較多,就會出現這個提示信息。這通常不是什麼問題,也無需修改配置項,在建立了自己的存儲池後,這個告警信息就會消失。
㈤ 如何基於 Ceph 構建高性能塊存儲服務
Ceph是一個分布式存儲系統,支持對象文件快介面,設計目標是:
• 所有組件橫向擴展
• 沒有單點故障
• 可以在普通廠商硬體使用
• 所有機制都能自我管理
• 開源
分布式存儲的應用場景相對於其存儲介面,現在流行分為三種:
1.對象存儲: 也就是通常意義的鍵值存儲,其介面就是簡單的GET,PUT,DEL和其他擴展,如七牛、又拍,Swift,S3等。
2.塊存儲: 這種介面通常以QEMUDriver或者KernelMole的方式存在,這種介面需要實現Linux的Block Device的介面或者QEMU提供的Block Driver介面,如Sheepdog,AWS的EBS,青雲的雲硬碟和阿里雲的盤古系統,還有Ceph的RDB(RDB是Ceph面向塊存儲的介面)。
3、文件存儲: 通常意義是支持POSIX介面,它跟傳統的文件系統如Ext4是一個類型的,但區別在於分布式存儲提供了並行化的能力,如Ceph的CephFS(CephFS是Ceph面向文件存儲的介面),但是有時候又會把GFS,HDFS這種非POSIX介面的類文件存儲介面歸入此類。
提到存儲的種類就不得不提到另外一個話題:存儲不能做統一化嗎?因為必須要有多個不同的軟體棧去管理不同的存儲設備:SSD,SATA等。
Ceph就此提出了不同觀點,RADOS提供了基礎的存儲設備的管理、數據控制流訪問的管理,提供的是一個可靠持久的數據存儲平台,基於其上,我們可以實現多個不同的介面戶來實現面向不同需求的對接,比如對象存儲我們有一個單獨的庫實現去滿足不同的存儲需要,比如我們塊存儲是通過RDP來實現。
統一存儲並不意味著所有存儲都的同一個介面,同一個實現,同一個軟體棧,它其實只是使用了同一個設備管理的生命周期和數據訪問的有效控制,它提供了一個相對合理,非常適合運維的,利於成本,利於軟體可靠性控制的的機制去保證我們的存儲的可靠。
舉一個例子,大部分存儲廠商甚至網路廠商都有一個自己的核心軟體棧,如文件系內核。基於其上演化出各種不同的產品線。如果廠商要追求各個產品線的極致是不是就應該每個產品完全獨立來追求極致,但事實上一個核心的底層技術棧需要高質量的代碼、完備的測試和長期的使用。在Ceph這里,一個分布式系統的並發IO、分布式恢復、數據端到端校驗等等關鍵實現是唯一實現,成熟的系統系統在這些實現上需要經過一定量級和時間的考驗,這才是Ceph所謂的統一存儲,而不是其他的介面堆疊式開發。
【Ceph和其他開源分布式存儲、其他商用存儲的區別之處在哪?】
眾所周知,很多傳統廠商如日立、富士通等存儲大廠也採用了Ceph作為它們存儲硬體的載體,Ceph能提供企業級的存儲服務一定有它的優勢,才能讓傳統的存儲廠商棄而採用開源的存儲方案。
1、中心化系統我們認為它在數據控制系統方面做的較好,在遷移運維方面提供較好的實現,但卻有元數據的瓶頸。在訪問數據時需要經過元數據伺服器的查詢再去尋找相應的數據伺服器會在大規模擴展時遇到性能瓶頸問題。
2、全分布式系統雖然提供較好的數據訪問能力,能高效處理客戶端的LO請求,但是卻沒有提供一個非常好的數據控制的實現,比如故障處理能力不足,數據恢復的困難,如果跳出中心化的元數據存儲系統它沒辦法做到強一致性的數據恢復。
彈性的數據分布策略和物理拓撲輸入實現了高可用性和高持久性,Ceph的高性能重構還體現在利用CRush演算法對數進行約束,避免數據分布到所有的集群的一個節點上,利用Ceph設計並提供的一個由CRush演算法來支持一個高自由化的存儲集群的設計,實現高可靠性,高持久性,高性能。