概述
Ceph是一個分布式存儲系統(tǒng),誕生于2004年岗憋,最早致力于開發(fā)下一代高性能分布式文件系統(tǒng)的項目肃晚。隨著云計算的發(fā)展,ceph乘上了OpenStack的春風仔戈,進而成為了開源社區(qū)受關注較高的項目之一关串。
Ceph有以下優(yōu)勢:
CRUSH算法
Crush算法是ceph的兩大創(chuàng)新之一,簡單來說监徘,ceph摒棄了傳統(tǒng)的集中式存儲元數(shù)據(jù)尋址的方案晋修,轉而使用CRUSH算法完成數(shù)據(jù)的尋址操作。CRUSH在一致性哈匣丝基礎上很好的考慮了容災域的隔離墓卦,能夠實現(xiàn)各類負載的副本放置規(guī)則,例如跨機房户敬、機架感知等落剪。Crush算法有相當強大的擴展性,理論上支持數(shù)千個存儲節(jié)點山叮。高可用
Ceph中的數(shù)據(jù)副本數(shù)量可以由管理員自行定義著榴,并可以通過CRUSH算法指定副本的物理存儲位置以分隔故障域,支持數(shù)據(jù)強一致性屁倔; ceph可以忍受多種故障場景并自動嘗試并行修復脑又。高擴展性
Ceph不同于swift,客戶端所有的讀寫操作都要經過代理節(jié)點锐借。一旦集群并發(fā)量增大時问麸,代理節(jié)點很容易成為單點瓶頸。Ceph本身并沒有主控節(jié)點钞翔,擴展起來比較容易严卖,并且理論上,它的性能會隨著磁盤數(shù)量的增加而線性增長布轿。特性豐富
Ceph支持三種調用接口:對象存儲哮笆,塊存儲来颤,文件系統(tǒng)掛載。三種方式可以一同使用稠肘。在國內一些公司的云環(huán)境中福铅,通常會采用ceph作為openstack的唯一后端存儲來提升數(shù)據(jù)轉發(fā)效率。
整體結構
從下到上將Ceph結構分為4層项阴,分別介紹如下:
基礎存儲系統(tǒng)——可靠的自動化分布式對象存儲(RADOS)
所有存儲在Ceph系統(tǒng)中的用戶數(shù)據(jù)都在該層進行管理滑黔,而Ceph的高可靠、高可擴展环揽、高性能略荡、高自動化等等特性本質上也是由這一層所提供的。因此歉胶,理解RADOS是理解Ceph的基礎與關鍵汛兜。RADOS在物理形態(tài)上由大量的存儲設備節(jié)點組成,每個節(jié)點擁有自己的硬件資源(CPU通今、內存序无、硬盤、網絡)衡创,并運行著操作系統(tǒng)和文件系統(tǒng)。基礎庫Librados
對RADOS的封裝和抽象晶通,向上層提供API璃氢,以便于直接基于RADOS進行開發(fā)。因為RADOS是一個對象存儲系統(tǒng)狮辽,則Librados實現(xiàn)的API也主要是針對對象存儲功能的一也。-
高級應用接口
這一層包括了三個部分:RADOS GW(RADOS Gateway)、 RBD(Reliable Block Device)和Ceph FS(Ceph File System)喉脖,其作用是在librados庫的基礎上提供抽象層次更高椰苟、更便于應用或客戶端使用的上層接口。RADOS GW是一個提供與亞馬遜S3和Swift兼容的RESTful API的gateway树叽,以供相應的對象存儲應用開發(fā)使用舆蝴。RADOS GW提供的API抽象層次更高,但功能則不如librados強大题诵。因此洁仗,開發(fā)者應針對自己的需求選擇使用。
RBD則提供了一個標準的塊設備接口性锭,常用于在虛擬化的場景下為虛擬機創(chuàng)建volume赠潦。目前,Red Hat已經將RBD驅動集成在KVM/QEMU中草冈,以提高虛擬機訪問性能她奥。
應用層
這一層就是不同場景下對于Ceph各個應用接口的各種應用方式瓮增,例如基于librados直接開發(fā)的對象存儲應用,基于RADOS GW開發(fā)的對象存儲應用哩俭,基于RBD實現(xiàn)的云硬盤等等绷跑。
基本組件
Osd
用于集群中所有數(shù)據(jù)與對象的存儲。處理集群數(shù)據(jù)的復制携茂、恢復你踩、回填、再均衡讳苦。并向其他osd守護進程發(fā)送心跳带膜,然后向Mon提供一些監(jiān)控信息。當Ceph存儲集群設定數(shù)據(jù)有兩個副本時(一共存兩份)鸳谜,則至少需要兩個OSD守護進程即兩個OSD節(jié)點膝藕,集群才能達到active+clean狀態(tài)。Mds(可選)
為Ceph文件系統(tǒng)提供元數(shù)據(jù)計算咐扭、緩存與同步芭挽。在ceph中,元數(shù)據(jù)也是存儲在osd節(jié)點中的蝗肪,mds類似于元數(shù)據(jù)的代理緩存服務器袜爪。MDS進程并不是必須的進程,只有需要使用CEPHFS時薛闪,才需要配置MDS節(jié)點辛馆。Monitor
監(jiān)控整個集群的狀態(tài),維護集群的cluster MAP二進制表豁延,保證集群數(shù)據(jù)的一致性昙篙。ClusterMAP描述了對象塊存儲的物理位置,以及一個將設備聚合到物理位置的桶列表诱咏。
RADOS結構說明
無論使用哪種存儲方式(對象苔可、塊、掛載)袋狞,存儲的數(shù)據(jù)都會被切分成對象(Objects)焚辅。Objects size大小可以由管理員調整,通常為2M或4M苟鸯。每個對象都會有一個唯一的OID法焰,由ino與ono生成,雖然這些名詞看上去很復雜倔毙,其實相當簡單埃仪。ino即是文件的File ID,用于在全局唯一標示每一個文件陕赃,而ono則是分片的編號卵蛉。比如:一個文件FileID為A颁股,它被切成了兩個對象,一個對象編號0傻丝,另一個編號1甘有,那么這兩個文件的oid則為A0與A1。Oid的好處是可以唯一標示每個不同的對象葡缰,并且存儲了對象與文件的從屬關系亏掀。由于ceph的所有數(shù)據(jù)都虛擬成了整齊劃一的對象,所以在讀寫時效率都會比較高泛释。
但是對象并不會直接存儲進OSD中滤愕,因為對象的size很小,在一個大規(guī)模的集群中可能有幾百到幾千萬個對象怜校。這么多對象光是遍歷尋址间影,速度都是很緩慢的;并且如果將對象直接通過某種固定映射的哈希算法映射到osd上茄茁,當這個osd損壞時魂贬,對象無法自動遷移至其他osd上面(因為映射函數(shù)不允許)。為了解決這些問題裙顽,ceph引入了歸置組的概念付燥,即PG。
PG是一個邏輯概念愈犹,我們linux系統(tǒng)中可以直接看到對象机蔗,但是無法直接看到PG。它在數(shù)據(jù)尋址時類似于數(shù)據(jù)庫中的索引:每個對象都會固定映射進一個PG中甘萧,所以當我們要尋找一個對象時,只需要先找到對象所屬的PG梆掸,然后遍歷這個PG就可以了扬卷,無需遍歷所有對象。而且在數(shù)據(jù)遷移時酸钦,也是以PG作為基本單位進行遷移怪得,ceph不會直接操作對象。
對象時如何映射進PG的卑硫?還記得OID么徒恋?首先使用靜態(tài)hash函數(shù)對OID做hash取出特征碼,用特征碼與PG的數(shù)量去模欢伏,得到的序號則是PGID入挣。由于這種設計方式,PG的數(shù)量多寡直接決定了數(shù)據(jù)分布的均勻性硝拧,所以合理設置的PG數(shù)量可以很好的提升CEPH集群的性能并使數(shù)據(jù)均勻分布径筏。
最后PG會根據(jù)管理員設置的副本數(shù)量進行復制葛假,然后通過crush算法存儲到不同的OSD節(jié)點上(其實是把PG中的所有對象存儲到節(jié)點上),第一個osd節(jié)點即為主節(jié)點滋恬,其余均為從節(jié)點聊训。
下面是一段ceph中的偽代碼,簡要描述了ceph的數(shù)據(jù)存儲流程
locator = object_name
obj_hash = hash(locator)
pg = obj_hash % num_pg
osds_for_pg = crush(pg) # returns a list of osds
primary = osds_for_pg[0]
replicas = osds_for_pg[1:]
上圖中更好的詮釋了ceph數(shù)據(jù)流的存儲過程,數(shù)據(jù)無論是從三中接口哪一種寫入的恢氯,最終都要切分成對象存儲到底層的RADOS中带斑。邏輯上通過算法先映射到PG上,最終存儲近OSD節(jié)點里勋拟。圖中除了之前介紹過的概念之外多了一個pools的概念勋磕。
Pool是管理員自定義的命名空間,像其他的命名空間一樣指黎,用來隔離對象與PG朋凉。我們在調用API存儲即使用對象存儲時,需要指定對象要存儲進哪一個POOL中醋安。除了隔離數(shù)據(jù)杂彭,我們也可以分別對不同的POOL設置不同的優(yōu)化策略,比如副本數(shù)吓揪、數(shù)據(jù)清洗次數(shù)亲怠、數(shù)據(jù)塊及對象大小等。
Osd 的讀寫流程
OSD是強一致性的分布式存儲
Ceph的讀寫操作采用主從模型柠辞,客戶端要讀寫數(shù)據(jù)時团秽,只能向對象所對應的主osd節(jié)點發(fā)起請求。主節(jié)點在接受到寫請求時叭首,會同步的向從OSD中寫入數(shù)據(jù)习勤。當所有的OSD節(jié)點都寫入完成后,主節(jié)點才會向客戶端報告寫入完成的信息焙格。因此保證了主從節(jié)點數(shù)據(jù)的高度一致性图毕。而讀取的時候,客戶端也只會向主osd節(jié)點發(fā)起讀請求眷唉,并不會有類似于數(shù)據(jù)庫中的讀寫分離的情況出現(xiàn)予颤,這也是出于強一致性的考慮。由于所有寫操作都要交給主osd節(jié)點來處理冬阳,所以在數(shù)據(jù)量很大時蛤虐,性能可能會比較慢,為了克服這個問題以及讓ceph能支持事物肝陪,每個osd節(jié)點都包含了一個journal文件驳庭,稍后介紹。
數(shù)據(jù)流向介紹到這里就告一段落了氯窍,現(xiàn)在終于回到正題:osd進程嚷掠。在ceph中捏检,每一個osd進程都可稱作是一個osd節(jié)點,也就是說不皆,每臺存儲服務器上可能包含了眾多的osd節(jié)點贯城,每個osd節(jié)點監(jiān)聽不同的端口,類似于在同一臺服務器上跑多個mysql或redis霹娄。每個osd節(jié)點可以設置一個目錄作為實際存儲區(qū)域能犯,也可以是一個分區(qū),一整塊硬盤犬耻。如下圖踩晶,當前這臺機器上跑了兩個osd進程,每個osd監(jiān)聽4個端口枕磁,分別用于接收客戶請求渡蜻、傳輸數(shù)據(jù)、發(fā)送心跳计济、同步數(shù)據(jù)等操作茸苇。
如上圖所示,osd節(jié)點默認監(jiān)聽tcp的6800到6803端口沦寂,如果同一臺服務器上有多個osd節(jié)點学密,則依次往后排序。
在生產環(huán)境中的osd最少可能都有上百個传藏,所以每個osd都有一個全局的編號腻暮,類似osd0,osd1毯侦,osd2........序號根據(jù)osd誕生的順序排列哭靖,并且是全局唯一的。存儲了相同PG的osd節(jié)點除了向mon節(jié)點發(fā)送心跳外侈离,還會互相發(fā)送心跳信息以檢測pg數(shù)據(jù)副本是否正常试幽。
之前在介紹數(shù)據(jù)流向時說過,每個osd節(jié)點都包含一個journal文件霍狰,如下圖:
默認大小為5G,也就說每創(chuàng)建一個osd節(jié)點饰及,還沒使用就要被journal占走5G的空間蔗坯。這個值是可以調整的,具體大小要依osd的總大小而定燎含。
Journal的作用類似于mysql innodb引擎中的事物日志系統(tǒng)宾濒。當有突發(fā)的大量寫入操作時,ceph可以先把一些零散的屏箍,隨機的IO請求保存到緩存中進行合并绘梦,然后再統(tǒng)一向內核發(fā)起IO請求橘忱。這樣做效率會比較高,但是一旦osd節(jié)點崩潰卸奉,緩存中的數(shù)據(jù)就會丟失钝诚,所以數(shù)據(jù)在還未寫進硬盤中時,都會記錄到journal中榄棵,當osd崩潰后重新啟動時凝颇,會自動嘗試從journal恢復因崩潰丟失的緩存數(shù)據(jù)。因此journal的io是非常密集的疹鳄,而且由于一個數(shù)據(jù)要io兩次拧略,很大程度上也損耗了硬件的io性能,所以通常在生產環(huán)境中瘪弓,使用ssd來單獨存儲journal文件以提高ceph讀寫性能垫蛆。
monitor節(jié)點
Mon節(jié)點監(jiān)控著整個ceph集群的狀態(tài)信息,監(jiān)聽于tcp的6789端口腺怯。每一個ceph集群中至少要有一個Mon節(jié)點袱饭,官方推薦每個集群至少部署三臺。Mon節(jié)點中保存了最新的版本集群數(shù)據(jù)分布圖(cluster map)的主副本瓢喉∧啵客戶端在使用時,需要掛載mon節(jié)點的6789端口栓票,下載最新的cluster map决左,通過crush算法獲得集群中各osd的IP地址,然后再與osd節(jié)點直接建立連接來傳輸數(shù)據(jù)走贪。所以對于ceph來說佛猛,并不需要有集中式的主節(jié)點用于計算與尋址,客戶端分攤了這部分工作坠狡。而且客戶端也可以直接和osd通信继找,省去了中間代理服務器的額外開銷。
Mon節(jié)點之間使用Paxos算法來保持各節(jié)點cluster map的一致性逃沿;各mon節(jié)點的功能總體上是一樣的婴渡,相互間的關系可以被簡單理解為主備關系。如果主mon節(jié)點損壞凯亮,其他mon存活節(jié)點超過半數(shù)時边臼,集群還可以正常運行。當故障mon節(jié)點恢復時假消,會主動向其他mon節(jié)點拉取最新的cluster map柠并。
Mon節(jié)點并不會主動輪詢各個osd的當前狀態(tài),相反,osd只有在一些特殊情況才會上報自己的信息臼予,平常只會簡單的發(fā)送心跳鸣戴。特殊情況包括:1、新的OSD被加入集群粘拾;2窄锅、某個OSD發(fā)現(xiàn)自身或其他OSD發(fā)生異常。Mon節(jié)點在收到這些上報信息時半哟,則會更新cluster map信息并加以擴散酬滤。
cluster map信息是以異步且lazy的形式擴散的。monitor并不會在每一次cluster map版本更新后都將新版本廣播至全體OSD寓涨,而是在有OSD向自己上報信息時盯串,將更新回復給對方。類似的戒良,各個OSD也是在和其他OSD通信時体捏,如果發(fā)現(xiàn)對方的osd中持有的cluster map版本較低,則把自己更新的版本發(fā)送給對方糯崎。
MDS
Mds是ceph集群中的元數(shù)據(jù)服務器几缭,而通常它都不是必須的,因為只有在使用cephfs的時候才需要它沃呢,而目在云計算中用的更廣泛的是另外兩種存儲方式年栓。
Mds雖然是元數(shù)據(jù)服務器,但是它不負責存儲元數(shù)據(jù)薄霜,元數(shù)據(jù)也是被切成對象存在各個osd節(jié)點中的某抓,如下圖:在創(chuàng)建CEPHFS時,要至少創(chuàng)建兩個POOL惰瓜,一個用于存放數(shù)據(jù)否副,另一個用于存放元數(shù)據(jù)。Mds只是負責接受用戶的元數(shù)據(jù)查詢請求崎坊,然后從osd中把數(shù)據(jù)取出來映射進自己的內存中供客戶訪問备禀。所以mds其實類似一個代理緩存服務器,替osd分擔了用戶的訪問壓力,如下圖:
cephfs安裝(centos7)
清除歷史環(huán)境
#PreInstall ceph-deploy on centos
#remove old ceph-deploy
yum remove ceph-deploy
#clean old conf
rm -rf /etc/ceph/*
rm -rf /var/lib/ceph/*/*
rm -rf /var/log/ceph/*
rm -rf /var/run/ceph/*
更新資源包
cd /etc/yum.repos.d/
mv CentOS-Base.repo CentOS-Base.repo.bak
sudo wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum cleancache
yum clean all
yum makecache
sudo yum update && sudo yum install ceph-deploy
關閉防火墻
#stop fireware
iptables -F
getenforce
setenforce 0
設置主機域名映射
第一列是主機的地址奈揍,第二列是主機的hostname
[root@master tool]# cat /etc/hosts
10.129.11.84 ceph1
10.129.11.85 ceph2
創(chuàng)建配置目錄
mkdir ceph && cd ceph
設置mon節(jié)點
ceph-deploy new ceph1
設置ceph安裝配置
[global]
fsid = f2ff8da0-eb30-49b7-9982-6621b32f2da9
mon_initial_members = ceph1
mon_host = 10.129.11.84 #mon地址
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
public network = 10.129.11.0/24 #集群所在網段
安裝ceph
ceph-deploy install ceph1 ceph2
使能集群
ceph-deploy --overwrite-conf mon create-initial
創(chuàng)建osd節(jié)點
ceph-deploy osd prepare ceph1:/dev/sdb1 ceph2:/dev/sdb1
同步數(shù)據(jù)
ceph-deploy --overwrite-conf admin ceph{1..2}
建立元數(shù)據(jù)服務器
ceph-deploy mds create ceph1
創(chuàng)建pool
創(chuàng)建兩個池曲尸,最后的數(shù)字是PG的數(shù)量
ceph osd pool create test1 256
ceph osd pool create test2 256
創(chuàng)建cephfs文件系統(tǒng)
注意一個ceph只能創(chuàng)建一個cephfs
ceph fs new cephfs test2 test1
默認第一個池會存儲元數(shù)據(jù)
查詢ceph狀態(tài)
[root@master-11-84 ~]# ceph -s
cluster f2ff8da0-eb30-49b7-9982-6621b32f2da9
health HEALTH_ERR
64 pgs are stuck inactive for more than 300 seconds
64 pgs stuck inactive
64 pgs stuck unclean
no osds
monmap e1: 1 mons at {master-11-84=10.129.11.84:6789/0}
election epoch 3, quorum 0 master-11-84
osdmap e1: 0 osds: 0 up, 0 in
flags sortbitwise,require_jewel_osds
pgmap v2: 64 pgs, 1 pools, 0 bytes data, 0 objects
0 kB used, 0 kB / 0 kB avail
64 creating
[root@master-11-84 ~]#
刪除ceph
清除所有數(shù)據(jù)
ceph-deploy purgedata ceph{1..2}
remove所有節(jié)點上的ceph
ceph-deploy purge ceph{1..2}
清除所有秘鑰文件
ceph-deploy forgetkeys