1、Ceph是什么?
Ceph是一個開源的分布式存儲系統,同時支持對象存儲、塊設備、文件系統
可同事提供三種接口:
對象存儲:也稱為基於對象的存儲,其中的文件被拆分成多個部分並散布在多個存儲服務器,在對象存儲中,數據會被分解為稱為“對象”的離散單元,並保存在單個存儲庫中,而不是作為文件夾中的文件或服務器上的塊來保存,對象存儲需要一個簡單的 HTTP 應用編程接口 (API),以供大多數客戶端(各種語言)使用
塊存儲:需要格式化,將文件直接保存到磁盤上。
文件存儲:提供數據存儲的接口,是由操作系統針對塊存儲的應用,即由操作系統提供存儲接口,應用程序通過調用操作系統將文件保存到塊存儲進行持久化
數據分為元數據和數據:
元數據即是文件的屬性信息(文件名、權限(屬主、屬組)、大小、時間戳等),在分布式存儲中當客戶端或者應用程序產生的客戶端數據被寫入到分布式存儲系統的時候,會有一個服務(Name Node)提供文件元數據的路由功能,即告訴應用程序去哪個服務器去請求文件內容,然后再有(Data Node)提供數據的讀寫請求及數據的高可用功能
塊存儲:這種接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,這種接口需要實現 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青雲的雲硬盤和阿里雲的盤古系統,還有 Ceph 的 RBD(RBD是Ceph面向塊存儲的接口)。在常見的存儲中 DAS、SAN 提供的也是塊存儲。
3、ceph的特點
高性能:
(1)摒棄了傳統的集中式存儲元數據尋址的⽅案,采⽤CRUSH算法,數據分布均衡,並⾏度⾼。 (2)考慮了容災域的隔離,能夠實現各類負載的副本放置規則,例如跨主機、跨機房、機架感知等。 (3)能夠⽀持上千個存儲節點的規模,⽀持TB到PB級的數據。
⾼可⽤性:
(1)副本數可以靈活控制。 (2)⽀持故障域分隔,數據強⼀致性。 (3)多種故障場景⾃動進⾏修復⾃愈。 (4)沒有單點故障,⾃動管理。
⾼可擴展性:
(1)去中⼼化。 (2)擴展靈活。 (3)隨着節點增加⽽線性增⻓。
特性豐富:
(1)⽀持三種存儲接⼝:塊存儲、⽂件存儲、對象存儲。 (2)⽀持⾃定義接⼝,⽀持多種語⾔驅動。
4、ceph組織架構
ceph 是一個對象(object)式存儲系統,它把每一個待管理的數據流(文件等數據)切分為一到多個固定大小(默認4 兆)的對象數據,並以其為原子單元(原子是構成元素的最小單元)完成數據的讀寫。
對象數據的底層存儲服務是由多個存儲主機(host)組成的存儲集群,該集群也被稱之為RADOS(reliable automatic distributed object store)存儲集群,即可靠的、自動化的、分布式的對象存儲系統。
librados 是RADOS 存儲集群的API,支持C/C++/JAVA/python/ruby/php/go等編程語言客戶端。
ceph的邏輯架構圖:
librados:librados庫,為應用程度提供訪問接口。同時也為塊存儲、對象存儲、文件系統提供原生的接口。
RADOSGW:網關接口,提供對象存儲服務。它使用librgw和librados來實現允許應用程序與Ceph對象存儲建立連接。並且提供S3 和 Swift 兼容的RESTful API接口。
RBD:塊設備,它能夠自動精簡配置並可調整大小,而且將數據分散存儲在多個OSD上。
5.2、Ceph的核心組件
Monitor(ceph-mon)ceph監視器:
在一個主機上運行的一個守護進程,用於維護集群狀態映射(maintains maps of the cluster state),比如ceph 集群中有多少存儲池、每個存儲池有多少PG 以及存儲池和PG的映射關系等, monitor map, manager map, the OSD map, the MDS map,and the CRUSH map,這些映射是Ceph 守護程序相互協調所需的關鍵群集狀態,此外監視器還負責管理守護程序和客戶端之間的身份驗證(認證使用cephX 協議)。通常至少需要三個監視器才能實現冗余和高可用性。
監視器,維護集群狀態的多種映射,同時提供認證和日志記錄服務,包括有關monitor 節點端到端的信息,其中包括 Ceph 集群ID,監控主機名和IP以及端口。並且存儲當前版本信息以及最新更改信息,通過 "ceph mon dump"查看 monitor map。
Managers(ceph-mgr)的功能:
在一個主機上運行的一個守護進程,Ceph Manager 守護程序(ceph-mgr)負責跟蹤運行時指標和Ceph 集群的當前狀態,包括存儲利用率,當前性能指標和系統負載。Ceph Manager 守護程序還托管基於python 的模塊來管理和公開Ceph 集群信息,包括基於Web的Ceph 儀表板和REST API。高可用性通常至少需要兩個管理器。
Ceph OSDs(對象存儲守護程序ceph-osd):
即對象存儲守護程序,但是它並非針對對象存儲。提供存儲數據,操作系統上的一個磁盤就是一個OSD 守護程序。是物理磁盤驅動器,將數據以對象的形式存儲到集群中的每個節點的物理磁盤上。OSD負責存儲數據、處理數據復制、恢復、重新平衡。完成存儲數據的工作絕大多數是由 OSD daemon 進程實現。在構建 Ceph OSD的時候,建議采用SSD 磁盤以及xfs文件系統來格式化分區。此外OSD還對其它OSD進行心跳檢測,檢測結果匯報給Monitor。通常至少需要3 個Ceph OSD 才能實現冗余和高可用性。
MDS(ceph 元數據服務器ceph-mds):Ceph 元數據,主要保存的是Ceph文件系統(NFS/CIFS)的元數據。注意:ceph的塊存儲和ceph對象存儲都不需要MDS。
Object:Ceph最底層的存儲單元是Object對象,每個Object包含元數據和原始數據
pool:存儲池、分區,存儲池的大小取決於底層的存儲空間
PG(placement group):
PG是一個邏輯概念,我們linux系統中可以直接看到對象,但是無法直接看到PG。它在數據尋址時類似於數據庫中的索引:每個對象都會固定映射進一個PG中,所以當我們要尋找一個對象時,只需要先找到對象所屬的PG,然后遍歷這個PG就可以了,無需遍歷所有對象。而且在數據遷移時,也是以PG作為基本單位進行遷移,ceph不會直接操作對象
一個pool 內部可以有多個PG 存在,pool 和PG 都是抽象的邏輯概念,一個pool 中有多少個PG 可以通過公式計算。引入PG這一層其實是為了更好的分配數據和定位數據。
OSD(Object Storage Daemon,對象存儲設備):每一塊磁盤都是一個 osd,一個主機由一個或多個 osd 組成
RADOS:RADOS全稱Reliable Autonomic Distributed Object Store,是Ceph集群的精華,用戶實現數據分配、Failover等集群操作
Libradio:Librados是Rados提供庫,因為RADOS是協議很難直接訪問,因此上層的RBD、RGW和CephFS都是通過librados訪問的,目前提供PHP、Ruby、Java、Python、C和C++支持。
CRUSH:CRUSH是Ceph使用的數據分布算法,類似一致性哈希,讓數據分配到預期的地方
RBD:RBD全稱RADOS block device,是Ceph對外提供的塊設備服務
RGW:RGW全稱RADOS gateway,是Ceph對外提供的對象存儲服務,接口與S3和Swift兼容
CephFS:CephFS全稱Ceph File System,是Ceph對外提供的文件系統服務
Ceph 的管理節點:
1.ceph 的常用管理接口是一組命令行工具程序,例如rados、ceph、rbd 等命令,ceph 管理員可以從某個特定的ceph-mon 節點執行管理操作
2.推薦使用部署專用的管理節點對ceph 進行配置管理、升級與后期維護,方便后期權限管理,管理節點的權限只對管理人員開放,可以避免一些不必要的誤操作的發生。
5.2、一個ceph集群的組成部分
若干的Ceph OSD(對象存儲守護程序) 至少需要一個Ceph Monitors 監視器(1,3,5,7...) 兩個或以上的Ceph 管理器managers,運行Ceph 文件系統客戶端時 還需要高可用的Ceph Metadata Server(文件系統元數據服務器)。 RADOS cluster:由多台host 存儲服務器組成的ceph 集群 OSD(Object Storage Daemon):每台存儲服務器的磁盤組成的存儲空間 Mon(Monitor):ceph 的監視器,維護OSD 和PG 的集群狀態,一個ceph 集群至少要有一個mon,可以是一三五七等等這樣的奇數個。 Mgr(Manager):負責跟蹤運行時指標和Ceph 集群的當前狀態,包括存儲利用率,當前性 能指標和系統負載等。
6、Ceph數據寫入流程
在說明ceph數據寫入流程之前之前,先介紹幾個概念和它們之間的關系。
存儲數據與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.1、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],一般來說應該將pg和pgp的數量設置為相等。
pg和pool的關系:pool也是一個邏輯存儲概念,我們創建存儲池pool的時候,都需要指定pg和pgp的數量,邏輯上來說pg是屬於某個存儲池的,就有點像object是屬於某個pg的
(1)PG是指定存儲池存儲對象的目錄有多少個,PGP是存儲池PG的OSD分布組合個數
(2)PG的增加會引起PG內的數據進行分裂,分裂相同的OSD上新生成的PG當中
(3)PGP的增加會引起部分PG的分布進行變化,但是不會引起PG內對象的變動
以下這個圖表明了存儲數據,object、pg、pool、osd、存儲磁盤的關系
ceph 集群部署好之后,要先創建存儲池才能向ceph 寫入數據,文件在向ceph 保存之前要先進行一致性hash 計算,計算后會把文件保存在某個對應的PG 的,此文件一定屬於某個pool 的一個PG,在通過PG 保存在OSD 上。數據對象在寫到主OSD 之后再同步對從OSD 以實現數據的高可用。
第一步: 計算文件到對象的映射:
假如file 為客戶端要讀寫的文件, 文件會被切分成若干個對象(object),默認為4M,每個對象都會有一個唯一的oid(object id),OID由ino + ono組成
ino:inode number (INO),File 的元數據序列號,File 的唯一id。
ono:object number (ONO),File 切分產生的某個object 的序號,默認以4M 切分一個塊大小。
比如:一個文件FileID為A,它被切成了兩個對象,一個對象編號0,另一個編號1,那么這兩個對象的oid則為A0與A1。Oid的好處是可以唯一標示每個不同的對象,並且存儲了對象與文件的從屬關系。
第二步:通過hash 算法計算出文件對應的pool 中的PG:
對象時如何映射進PG的?還記得OID么?首先使用靜態hash函數對OID做hash取出特征碼,用特征碼與mask取模,得到的序號則是PGID
mask=PG數量-1 hash(oid) & mask -> pgid
第三步: 通過CRUSH 把對象映射到PG 中的OSD: 通過CRUSH 算法得到OSD列表,PG -> OSD 映射:CRUSH(pgid) -> (osd1,osd2,osd3)
第四步:PG 中的主OSD 將對象寫入到硬盤。
第五步: 主OSD 將數據同步給備份OSD,並等待備份OSD 返回確認。
第六步: 備份OSD返回確認后,主OSD 將寫入完成返回給客戶端。
Ceph中數據寫入,會有三次映射
(1)File -> object映射 (2)Object -> PG映射,hash(oid) & mask -> pgid (3)PG -> OSD映射,CRUSH算法
7、CRUSH算法簡介
Controllers replication under scalable hashing #可控的、可復制的、可伸縮的一致性 hash算法。
Ceph 使用 CURSH 算法來存放和管理數據,它是 Ceph 的智能數據分發機制。Ceph 使用CRUSH 算法來准確計算數據應該被保存到哪里,以及應該從哪里讀取,和保存元數據不同的是,CRUSH 按需計算出元數據,因此它就消除了對中心式的服務器/網關的需求,它使得Ceph 客戶端能夠計算出元數據,該過程也稱為 CRUSH 查找,然后和 OSD 直接通信。
1.如果是把對象直接映射到 OSD 之上會導致對象與 OSD 的對應關系過於緊密和耦合,當OSD 由於故障發生變更時將會對整個 ceph 集群產生影響。
2.於是 ceph 將一個對象映射到 RADOS 集群的時候分為兩步走:
首先使用一致性 hash 算法將對象名稱映射到 PG 2.7
然后將 PG ID 基於 CRUSH 算法映射到 OSD 即可查到對象
3.以上兩個過程都是以”實時計算”的方式完成,而沒有使用傳統的查詢數據與塊設備的對應表的方式,這樣有效避免了組件的”中心化”問題,也解決了查詢性能和冗余問題。使得 ceph集群擴展不再受查詢的性能限制。
4.這個實時計算操作使用的就是 CRUSH 算法
Controllers replication under scalable hashing #可控的、可復制的、可伸縮的一致性 hash算法。
CRUSH 是一種分布式算法,類似於一致性 hash 算法,用於為 RADOS 存儲集群控制數據的分配。
8、Ceph元數據保存方式
Ceph 對象數據的元數據信息放在哪里呢? 對象數據的元數據以 key-value 的形式存在,在RADOS 中有兩種實現:xattrs 和 omap
8.1、xattrs(擴展屬性)
是將元數據保存在對象對應文件的擴展屬性中並保存到系統磁盤上,這要求支持對象存儲的本地文件系統(一般是 XFS)支持擴展屬性
8.2、omap(object map對象映射):
omap:是 object map 的簡稱,是將元數據保存在本地文件系統之外的獨立 key-value 存儲系統中,在使用 filestore 時是 leveldb,在使用 bluestore 時是 rocksdb,由於 filestore存在功能問題(需要將磁盤格式化為XFS格式)及元數據高可用問題等問題,因此在目前ceph主要使用 bluestore
8.2.1、blustore和rocksdb:
由於 levelDB 依然需要需要磁盤文件系統的支持,后期 facebok 對 levelDB 進行改進為RocksDB https://github.com/facebook/rocksdb,RocksDB 將對象數據的元數據保存在RocksDB,但是 RocksDB 的數據又放在哪里呢?放在內存怕丟失,放在本地磁盤但是解決不了高可用,ceph 對象數據放在了每個 OSD 中,那么就在在當前 OSD 中划分出一部分空間,格式化為 BlueFS 文件系統用於保存 RocksDB 中的元數據信息(稱為 BlueStore),並實現元數據的高可用,BlueStore 最大的特點是構建在裸磁盤設備之上,並且對諸如 SSD 等新的存儲設備做了很多優化工作。
對全 SSD 及全 NVMe SSD 閃存適配 繞過本地文件系統層,直接管理裸設備,縮短 IO 路徑 嚴格分離元數據和數據,提高索引效率 使用 KV 索引,解決文件系統目錄結構遍歷效率低的問題 支持多種設備類型 解決日志“雙寫”問題 期望帶來至少 2 倍的寫性能提升和同等讀性能 增加數據校驗及數據壓縮等功能
RocksDB 通過中間層 BlueRocksDB 訪問文件系統的接口。這個文件系統與傳統的 Linux文件系統(例如 Ext4 和 XFS)是不同的,它不是在 VFS 下面的通用文件系統,而是一個用戶態的邏輯。BlueFS 通過函數接口(API,非 POSIX)的方式為 BlueRocksDB 提供類似文件系統的能力
BlueStore 的邏輯架構如上圖所示,模塊的划分都還比較清晰,下面是各模塊的作用:
Allocator:負責裸設備的空間管理分配。
RocksDB:rocksdb 是 facebook 基於 leveldb 開發的一款 kv 數據庫,BlueStore 將元數據全部存放至 RocksDB 中,這些元數據包括存儲預寫式日志、數據對象元數據、Ceph 的 omap數據信息、以及分配器的元數據 。
BlueRocksEnv:這是 RocksDB 與 BlueFS 交互的接口;RocksDB 提供了文件操作的接口EnvWrapper(Env 封裝器),可以通過繼承實現該接口來自定義底層的讀寫操作,BlueRocksEnv 就是繼承自 EnvWrapper 實現對 BlueFS 的讀寫。
BlueFS:BlueFS 是 BlueStore 針對 RocksDB 開發的輕量級文件系統,用於存放 RocksDB產生的.sst 和.log 等文件。
BlockDecive:BlueStore 拋棄了傳統的 ext4、xfs 文件系統,使用直接管理裸盤的方式;BlueStore 支持同時使用多種不同類型的設備,在邏輯上 BlueStore 將存儲空間划分為三層:慢速(Slow)空間、高速(DB)空間、超高速(WAL)空間,不同的空間可以指定使用不同的設備類型,當然也可使用同一塊設備。
BlueStore 的設計考慮了 FileStore 中存在的一些硬傷,拋棄了傳統的文件系統直接管理裸設備,縮短了 IO 路徑,同時采用 ROW 的方式,避免了日志雙寫的問題,在寫入性能上有了極大的提高