ceph工作原理


一、概述

Ceph是一個分布式存儲系統,誕生於2004年,最早致力於開發下一代高性能分布式文件系統的項目。隨着雲計算的發展,ceph乘上了OpenStack的春風,進而成為了開源社區受關注較高的項目之一。
Ceph有以下優勢:

1. CRUSH算法

Crush算法是ceph的兩大創新之一,簡單來說,ceph摒棄了傳統的集中式存儲元數據尋址的方案,轉而使用CRUSH算法完成數據的尋址操作。CRUSH在一致性哈希基礎上很好的考慮了容災域的隔離,能夠實現各類負載的副本放置規則,例如跨機房、機架感知等。Crush算法有相當強大的擴展性,理論上支持數千個存儲節點。

2. 高可用

Ceph中的數據副本數量可以由管理員自行定義,並可以通過CRUSH算法指定副本的物理存儲位置以分隔故障域,支持數據強一致性; ceph可以忍受多種故障場景並自動嘗試並行修復。

3. 高擴展性

Ceph不同於swift,客戶端所有的讀寫操作都要經過代理節點。一旦集群並發量增大時,代理節點很容易成為單點瓶頸。Ceph本身並沒有主控節點,擴展起來比較容易,並且理論上,它的性能會隨着磁盤數量的增加而線性增長。

4. 特性豐富

Ceph支持三種調用接口:對象存儲塊存儲文件系統掛載。三種方式可以一同使用。在國內一些公司的雲環境中,通常會采用ceph作為openstack的唯一后端存儲來提升數據轉發效率。



二、CEPH的基本結構

Ceph的基本組成結構如下圖:

Ceph的底層是RADOS,RADOS本身也是分布式存儲系統,CEPH所有的存儲功能都是基於RADOS實現。RADOS采用C++開發,所提供的原生Librados API包括C和C++兩種。Ceph的上層應用調用本機上的librados API,再由后者通過socket與RADOS集群中的其他節點通信並完成各種操作。

RADOS GateWay、RBD其作用是在librados庫的基礎上提供抽象層次更高、更便於應用或客戶端使用的上層接口。其中,RADOS GW是一個提供與Amazon S3和Swift兼容的RESTful API的gateway,以供相應的對象存儲應用開發使用。RBD則提供了一個標准的塊設備接口,常用於在虛擬化的場景下為虛擬機創建volume。目前,Red Hat已經將RBD驅動集成在KVM/QEMU中,以提高虛擬機訪問性能。這兩種方式目前在雲計算中應用的比較多。

CEPHFS則提供了POSIX接口,用戶可直接通過客戶端掛載使用。它是內核態的程序,所以無需調用用戶空間的librados庫。它通過內核中的net模塊來與Rados進行交互。

 

 

三、Ceph的基本組件

如上圖所示,Ceph主要有三個基本進程

  • Osd

    用於集群中所有數據與對象的存儲。處理集群數據的復制、恢復、回填、再均衡。並向其他osd守護進程發送心跳,然后向Mon提供一些監控信息。
    當Ceph存儲集群設定數據有兩個副本時(一共存兩份),則至少需要兩個OSD守護進程即兩個OSD節點,集群才能達到active+clean狀態。

  • MDS(可選)

    為Ceph文件系統提供元數據計算、緩存與同步。在ceph中,元數據也是存儲在osd節點中的,mds類似於元數據的代理緩存服務器。MDS進程並不是必須的進程,只有需要使用CEPHFS時,才需要配置MDS節點。

  • Monitor
    監控整個集群的狀態,維護集群的cluster MAP二進制表,保證集群數據的一致性。ClusterMAP描述了對象塊存儲的物理位置,以及一個將設備聚合到物理位置的桶列表。

 

 

四、OSD

首先描述一下ceph數據的存儲過程,如下圖:

無論使用哪種存儲方式(對象、塊、掛載),存儲的數據都會被切分成對象(Objects)。Objects size大小可以由管理員調整,通常為2M或4M。每個對象都會有一個唯一的OID,由ino與ono生成,雖然這些名詞看上去很復雜,其實相當簡單。ino即是文件的File ID,用於在全局唯一標示每一個文件,而ono則是分片的編號。比如:一個文件FileID為A,它被切成了兩個對象,一個對象編號0,另一個編號1,那么這兩個文件的oid則為A0與A1。Oid的好處是可以唯一標示每個不同的對象,並且存儲了對象與文件的從屬關系。由於ceph的所有數據都虛擬成了整齊划一的對象,所以在讀寫時效率都會比較高。

但是對象並不會直接存儲進OSD中,因為對象的size很小,在一個大規模的集群中可能有幾百到幾千萬個對象。這么多對象光是遍歷尋址,速度都是很緩慢的;並且如果將對象直接通過某種固定映射的哈希算法映射到osd上,當這個osd損壞時,對象無法自動遷移至其他osd上面(因為映射函數不允許)。為了解決這些問題,ceph引入了歸置組的概念,即PG。

PG是一個邏輯概念,我們linux系統中可以直接看到對象,但是無法直接看到PG。它在數據尋址時類似於數據庫中的索引:每個對象都會固定映射進一個PG中,所以當我們要尋找一個對象時,只需要先找到對象所屬的PG,然后遍歷這個PG就可以了,無需遍歷所有對象。而且在數據遷移時,也是以PG作為基本單位進行遷移,ceph不會直接操作對象。

對象時如何映射進PG的?還記得OID么?首先使用靜態hash函數對OID做hash取出特征碼,用特征碼與PG的數量去模,得到的序號則是PGID。由於這種設計方式,PG的數量多寡直接決定了數據分布的均勻性,所以合理設置的PG數量可以很好的提升CEPH集群的性能並使數據均勻分布。

最后PG會根據管理員設置的副本數量進行復制,然后通過crush算法存儲到不同的OSD節點上(其實是把PG中的所有對象存儲到節點上),第一個osd節點即為主節點,其余均為從節點。

上圖中更好的詮釋了ceph數據流的存儲過程,數據無論是從三中接口哪一種寫入的,最終都要切分成對象存儲到底層的RADOS中。邏輯上通過算法先映射到PG上,最終存儲近OSD節點里。圖中除了之前介紹過的概念之外多了一個pools的概念。

Pool是管理員自定義的命名空間,像其他的命名空間一樣,用來隔離對象與PG。我們在調用API存儲即使用對象存儲時,需要指定對象要存儲進哪一個POOL中。除了隔離數據,我們也可以分別對不同的POOL設置不同的優化策略,比如副本數、數據清洗次數、數據塊及對象大小等。

OSD是強一致性的分布式存儲,它的讀寫流程如下圖

  Ceph的讀寫操作采用主從模型,客戶端要讀寫數據時,只能向對象所對應的主osd節點發起請求。主節點在接受到寫請求時,會同步的向從OSD中寫入數據。當所有的OSD節點都寫入完成后,主節點才會向客戶端報告寫入完成的信息。因此保證了主從節點數據的高度一致性。而讀取的時候,客戶端也只會向主osd節點發起讀請求,並不會有類似於數據庫中的讀寫分離的情況出現,這也是出於強一致性的考慮。由於所有寫操作都要交給主osd節點來處理,所以在數據量很大時,性能可能會比較慢,為了克服這個問題以及讓ceph能支持事物,每個osd節點都包含了一個journal文件,稍后介紹。

數據流向介紹到這里就告一段落了,現在終於回到正題:osd進程。在ceph中,每一個osd進程都可稱作是一個osd節點,也就是說,每台存儲服務器上可能包含了眾多的osd節點,每個osd節點監聽不同的端口,類似於在同一台服務器上跑多個mysql或redis。每個osd節點可以設置一個目錄作為實際存儲區域,也可以是一個分區,一整塊硬盤。如下圖,當前這台機器上跑了兩個osd進程,每個osd監聽4個端口,分別用於接收客戶請求、傳輸數據、發送心跳、同步數據等操作。

如上圖所示,osd節點默認監聽tcp的6800到6803端口,如果同一台服務器上有多個osd節點,則依次往后排序。

在生產環境中的osd最少可能都有上百個,所以每個osd都有一個全局的編號,類似osd0,osd1,osd2........序號根據osd誕生的順序排列,並且是全局唯一的。存儲了相同PG的osd節點除了向mon節點發送心跳外,還會互相發送心跳信息以檢測pg數據副本是否正常。

之前在介紹數據流向時說過,每個osd節點都包含一個journal文件,如下圖:

  默認大小為5G,也就說每創建一個osd節點,還沒使用就要被journal占走5G的空間。這個值是可以調整的,具體大小要依osd的總大小而定。

Journal的作用類似於mysql innodb引擎中的事物日志系統。當有突發的大量寫入操作時,ceph可以先把一些零散的,隨機的IO請求保存到緩存中進行合並,然后再統一向內核發起IO請求。這樣做效率會比較高,但是一旦osd節點崩潰,緩存中的數據就會丟失,所以數據在還未寫進硬盤中時,都會記錄到journal中,當osd崩潰后重新啟動時,會自動嘗試從journal恢復因崩潰丟失的緩存數據。因此journal的io是非常密集的,而且由於一個數據要io兩次,很大程度上也損耗了硬件的io性能,所以通常在生產環境中,使用ssd來單獨存儲journal文件以提高ceph讀寫性能。

 
 

五、monitor節點

Mon節點監控着整個ceph集群的狀態信息,監聽於tcp的6789端口。每一個ceph集群中至少要有一個Mon節點,官方推薦每個集群至少部署三台。Mon節點中保存了最新的版本集群數據分布圖(cluster map)的主副本。客戶端在使用時,需要掛載mon節點的6789端口,下載最新的cluster map,通過crush算法獲得集群中各osd的IP地址,然后再與osd節點直接建立連接來傳輸數據。所以對於ceph來說,並不需要有集中式的主節點用於計算與尋址,客戶端分攤了這部分工作。而且客戶端也可以直接和osd通信,省去了中間代理服務器的額外開銷。

Mon節點之間使用Paxos算法來保持各節點cluster map的一致性;各mon節點的功能總體上是一樣的,相互間的關系可以被簡單理解為主備關系。如果主mon節點損壞,其他mon存活節點超過半數時,集群還可以正常運行。當故障mon節點恢復時,會主動向其他mon節點拉取最新的cluster map。

Mon節點並不會主動輪詢各個osd的當前狀態,相反,osd只有在一些特殊情況才會上報自己的信息,平常只會簡單的發送心跳。特殊情況包括:1、新的OSD被加入集群;2、某個OSD發現自身或其他OSD發生異常。Mon節點在收到這些上報信息時,則會更新cluster map信息並加以擴散。

cluster map信息是以異步且lazy的形式擴散的。monitor並不會在每一次cluster map版本更新后都將新版本廣播至全體OSD,而是在有OSD向自己上報信息時,將更新回復給對方。類似的,各個OSD也是在和其他OSD通信時,如果發現對方的osd中持有的cluster map版本較低,則把自己更新的版本發送給對方。

推薦使用以下的架構
這里的ceph除了管理網段外,設了兩個網段,一個用於客戶端讀寫傳輸數據。另一個用於各OSD節點之間同步數據和發送心跳信息等。這樣做的好處是可以分擔網卡的IO壓力。否則在數據清洗時,客戶端的讀寫速度會變得極為緩慢。
 
 

六、MDS

Mds是ceph集群中的元數據服務器,而通常它都不是必須的,因為只有在使用cephfs的時候才需要它,而目在雲計算中用的更廣泛的是另外兩種存儲方式。

Mds雖然是元數據服務器,但是它不負責存儲元數據,元數據也是被切成對象存在各個osd節點中的,如下圖:

在創建CEPHFS時,要至少創建兩個POOL,一個用於存放數據,另一個用於存放元數據。Mds只是負責接受用戶的元數據查詢請求,然后從osd中把數據取出來映射進自己的內存中供客戶訪問。所以mds其實類似一個代理緩存服務器,替osd分擔了用戶的訪問壓力,如下圖:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM