Ceph是一個可靠地、自動重均衡、自動恢復的分佈式存儲系統,根據場景劃分能夠將Ceph分爲三大塊,分別是對象存儲、塊設備存儲和文件系統服務。在虛擬化領域裏,比較經常使用到的是Ceph的塊設備存儲,好比在OpenStack項目裏,Ceph的塊設備存儲能夠對接OpenStack的cinder後端存儲、Glance的鏡像存儲和虛擬機的數據存儲,比較直觀的是Ceph集羣能夠提供一個raw格式的塊存儲來做爲虛擬機實例的硬盤。算法
Ceph相比其它存儲的優點點在於它不僅僅是存儲,同時還充分利用了存儲節點上的計算能力,在存儲每個數據時,都會經過計算得出該數據存儲的位置,儘可能將數據分佈均衡,同時因爲Ceph的良好設計,採用了CRUSH算法、HASH環等方法,使得它不存在傳統的單點故障的問題,且隨着規模的擴大性能並不會受到影響。編程
2 Ceph的核心組件後端
Ceph的核心組件包括Ceph OSD、Ceph Monitor和Ceph MDS。數組
Ceph OSD:OSD的英文全稱是Object Storage Device,它的主要功能是存儲數據、複製數據、平衡數據、恢復數據等,與其它OSD間進行心跳檢查等,並將一些變化狀況上報給Ceph Monitor。通常狀況下一塊硬盤對應一個OSD,由OSD來對硬盤存儲進行管理,固然一個分區也能夠成爲一個OSD。服務器
Ceph OSD的架構實現由物理磁盤驅動器、Linux文件系統和Ceph OSD服務組成,對於Ceph OSD Deamon而言,Linux文件系統顯性的支持了其拓展性,通常Linux文件系統有好幾種,好比有BTRFS、XFS、Ext4等,BTRFS雖然有不少優勢特性,但如今還沒達到生產環境所需的穩定性,通常比較推薦使用XFS。數據結構
伴隨OSD的還有一個概念叫作Journal盤,通常寫數據到Ceph集羣時,都是先將數據寫入到Journal盤中,而後每隔一段時間好比5秒再將Journal盤中的數據刷新到文件系統中。通常爲了使讀寫時延更小,Journal盤都是採用SSD,通常分配10G以上,固然分配多點那是更好,Ceph中引入Journal盤的概念是由於Journal容許Ceph OSD功能很快作小的寫操做;一個隨機寫入首先寫入在上一個連續類型的journal,而後刷新到文件系統,這給了文件系統足夠的時間來合併寫入磁盤,通常狀況下使用SSD做爲OSD的journal能夠有效緩衝突發負載。架構
Ceph Monitor:由該英文名字咱們能夠知道它是一個監視器,負責監視Ceph集羣,維護Ceph集羣的健康狀態,同時維護着Ceph集羣中的各類Map圖,好比OSD Map、Monitor Map、PG Map和CRUSH Map,這些Map統稱爲Cluster Map,Cluster Map是RADOS的關鍵數據結構,管理集羣中的全部成員、關係、屬性等信息以及數據的分發,好比當用戶須要存儲數據到Ceph集羣時,OSD須要先經過Monitor獲取最新的Map圖,而後根據Map圖和object id等計算出數據最終存儲的位置。編程語言
Ceph MDS:全稱是Ceph MetaData Server,主要保存的文件系統服務的元數據,但對象存儲和塊存儲設備是不須要使用該服務的。分佈式
查看各類Map的信息能夠經過以下命令:ceph osd(mon、pg) dumppost
3 Ceph基礎架構組件
從架構圖中能夠看到最底層的是RADOS,RADOS自身是一個完整的分佈式對象存儲系統,它具備可靠、智能、分佈式等特性,Ceph的高可靠、高可拓展、高性能、高自動化都是由這一層來提供的,用戶數據的存儲最終也都是經過這一層來進行存儲的,RADOS能夠說就是Ceph的核心。
RADOS系統主要由兩部分組成,分別是OSD和Monitor。
基於RADOS層的上一層是LIBRADOS,LIBRADOS是一個庫,它容許應用程序經過訪問該庫來與RADOS系統進行交互,支持多種編程語言,好比C、C++、Python等。
基於LIBRADOS層開發的又能夠看到有三層,分別是RADOSGW、RBD和CEPH FS。
RADOSGW:RADOSGW是一套基於當前流行的RESTFUL協議的網關,而且兼容S3和Swift。
RBD:RBD經過Linux內核客戶端和QEMU/KVM驅動來提供一個分佈式的塊設備。
CEPH FS:CEPH FS經過Linux內核客戶端和FUSE來提供一個兼容POSIX的文件系統。
4 Ceph數據分佈算法
在分佈式存儲系統中比較關注的一點是如何使得數據可以分佈得更加均衡,常見的數據分佈算法有一致性Hash和Ceph的Crush算法。Crush是一種僞隨機的控制數據分佈、複製的算法,Ceph是爲大規模分佈式存儲而設計的,數據分佈算法必須可以知足在大規模的集羣下數據依然可以快速的準確的計算存放位置,同時可以在硬件故障或擴展硬件設備時作到儘量小的數據遷移,Ceph的CRUSH算法就是精心爲這些特性設計的,能夠說CRUSH算法也是Ceph的核心之一。
在說明CRUSH算法的基本原理以前,先介紹幾個概念和它們之間的關係。
存儲數據與object的關係:當用戶要將數據存儲到Ceph集羣時,存儲數據都會被分割成多個object,每一個object都有一個object id,每一個object的大小是能夠設置的,默認是4MB,object能夠當作是Ceph存儲的最小存儲單元。
object與pg的關係:因爲object的數量不少,因此Ceph引入了pg的概念用於管理object,每一個object最後都會經過CRUSH計算映射到某個pg中,一個pg能夠包含多個object。
pg與osd的關係:pg也須要經過CRUSH計算映射到osd中去存儲,若是是二副本的,則每一個pg都會映射到二個osd,好比[osd.1,osd.2],那麼osd.1是存放該pg的主副本,osd.2是存放該pg的從副本,保證了數據的冗餘。
pg和pgp的關係:pg是用來存放object的,pgp至關因而pg存放osd的一種排列組合,我舉個例子,好比有3個osd,osd.一、osd.2和osd.3,副本數是2,若是pgp的數目爲1,那麼pg存放的osd組合就只有一種,多是[osd.1,osd.2],那麼全部的pg主從副本分別存放到osd.1和osd.2,若是pgp設爲2,那麼其osd組合能夠兩種,多是[osd.1,osd.2]和[osd.1,osd.3],是否是很像咱們高中數學學過的排列組合,pgp就是表明這個意思。通常來講應該將pg和pgp的數量設置爲相等。這樣說可能不夠明顯,咱們經過一組實驗來體會下:
先建立一個名爲testpool包含6個PG和6個PGP的存儲池
ceph osd pool create testpool 6 6
經過寫數據後咱們查看下pg的分佈狀況,使用如下命令:
ceph pg dump pgs | grep ^1 | awk '{print $1,$2,$15}'
dumped pgs in format plain
1.1 75 [3,6,0]
1.0 83 [7,0,6]
1.3 144 [4,1,2]
1.2 146 [7,4,1]
1.5 86 [4,6,3]
1.4 80 [3,0,4]
第1列爲pg的id,第2列爲該pg所存儲的對象數目,第3列爲該pg所在的osd
咱們擴大PG再看看
ceph osd pool set testpool pg_num 12
再次用上面的命令查詢分佈狀況:
1.1 37 [3,6,0]
1.9 38 [3,6,0]
1.0 41 [7,0,6]
1.8 42 [7,0,6]
1.3 48 [4,1,2]
1.b 48 [4,1,2]
1.7 48 [4,1,2]
1.2 48 [7,4,1]
1.6 49 [7,4,1]
1.a 49 [7,4,1]
1.5 86 [4,6,3]
1.4 80 [3,0,4]
咱們能夠看到pg的數量增長到12個了,pg1.1的對象數量原本是75的,如今是37個,能夠看到它把對象數分給新增的pg1.9了,恰好是38,加起來是75,並且能夠看到pg1.1和pg1.9的osd盤是同樣的。
並且能夠看到osd盤的組合仍是那6種。
咱們增長pgp的數量來看下,使用命令:
ceph osd pool set testpool pgp_num 12
再看下
1.a 49 [1,2,6]
1.b 48 [1,6,2]
1.1 37 [3,6,0]
1.0 41 [7,0,6]
1.3 48 [4,1,2]
1.2 48 [7,4,1]
1.5 86 [4,6,3]
1.4 80 [3,0,4]
1.7 48 [1,6,0]
1.6 49 [3,6,7]
1.9 38 [1,4,2]
1.8 42 [1,2,3]
再看pg1.1和pg1.9,能夠看到pg1.9不在[3,6,0]上,而在[1,4,2]上了,該組合是新加的,能夠知道增長pgp_num實際上是增長了osd盤的組合。
經過實驗總結:
(1)PG是指定存儲池存儲對象的目錄有多少個,PGP是存儲池PG的OSD分佈組合個數
(2)PG的增長會引發PG內的數據進行分裂,分裂相同的OSD上新生成的PG當中
(3)PGP的增長會引發部分PG的分佈進行變化,可是不會引發PG內對象的變更
pg和pool的關係:pool也是一個邏輯存儲概念,咱們建立存儲池pool的時候,都須要指定pg和pgp的數量,邏輯上來講pg是屬於某個存儲池的,就有點像object是屬於某個pg的。
如下這個圖代表了存儲數據,object、pg、pool、osd、存儲磁盤的關係
本質上CRUSH算法是根據存儲設備的權重來計算數據對象的分佈的,權重的設計能夠根據該磁盤的容量和讀寫速度來設置,好比根據容量大小能夠將1T的硬盤設備權重設爲1,2T的就設爲2,在計算過程當中,CRUSH是根據Cluster Map、數據分佈策略和一個隨機數共同決定數組最終的存儲位置的。
Cluster Map裏的內容信息包括存儲集羣中可用的存儲資源及其相互之間的空間層次關係,好比集羣中有多少個支架,每一個支架中有多少個服務器,每一個服務器有多少塊磁盤用以OSD等。
數據分佈策略是指能夠經過Ceph管理者經過配置信息指定數據分佈的一些特色,好比管理者配置的故障域是Host,也就意味着當有一臺Host起不來時,數據可以不丟失,CRUSH能夠經過將每一個pg的主從副本分別存放在不一樣Host的OSD上便可達到,不僅僅能夠指定Host,還能夠指定機架等故障域,除了故障域,還有選擇數據冗餘的方式,好比副本數或糾刪碼。
下面這個式子簡單的代表CRUSH的計算表達式:
CRUSH(X) -> (osd.1,osd.2.....osd.n)
式子中的X就是一個隨機數。
下面經過一個計算PG ID的示例來看CRUSH的一個計算過程:
(1)Client輸入Pool ID和對象ID;
(2)CRUSH得到對象ID並對其進行Hash運算;
(3)CRUSH計算OSD的個數,Hash取模得到PG的ID,好比0x48;
(4)CRUSH取得該Pool的ID,好比是1;
(5)CRUSH預先考慮到Pool ID相同的PG ID,好比1.48。