Cehp-學習1

一、概述

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的基本組成結構如下圖:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

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的基本組件

640?wx_fmt=png&wxfrom=5&wx_lazy=1

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

  • Osd

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

  • MDS(可選)

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

  • Monitor

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


四、OSD

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

640?wx_fmt=png&wxfrom=5&wx_lazy=1

  無論使用哪種存儲方式(對象、塊、掛載),存儲的數據都會被切分成對象(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中的僞代碼,簡要描述了ceph的數據存儲流程
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:]

640?wx_fmt=png&wxfrom=5&wx_lazy=1

  上圖中更好的詮釋了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文件,如下圖:

640?wx_fmt=png&wxfrom=5&wx_lazy=1
  默認大小爲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分擔了用戶的訪問壓力,如下圖:



七、cephfs的簡易安裝

  在安裝ceph之前推薦把所有的ceph節點設置成無需密碼ssh互訪,配置hosts支持主機名互訪,同步好時間,並關閉iptables和selinux。

1、實驗環境說明:

當前實驗環境使用了4臺主機node1~node4,node1爲管理節點。

2、部署工具:

  Ceph官方推出了一個用python寫的工具 cpeh-deploy,可以很大的簡化ceph集羣的配置過程,建議大家用用。它的yum倉庫地址,下載地址如下:

http://download.ceph.com/rpm-firefly/el6/noarch/
3、安裝步驟
  • 在管理主機上安裝工具(通常是跳板機)
    yum install -y ceph-deploy
  • 創建工作目錄,用於存放生成的配置文件和祕鑰等信息
    Mkdir /ceph;cd /ceph
  • 下載yum源,下載地址如下
    http://download.ceph.com/rpm-firefly/el6/noarch/
  • 在node1~4上把上面的網址設置爲yum源
    yum install –y ceph
  • 到管理主機上的/ceph目錄操作,創建一個新集羣,並設置node1爲mon節點
    ceph-deploy new node1
    
    執行完畢後,可以看到/ceph目錄中生成了三個文件,其中有一個配置文件可以做各種參數優化,據說ceph的優化參數接近1000項。(注意,在osd進程生成並掛載使用後,想修改配置需要使用命令行工具,修改配置文件是無效的,所以需要提前規劃好優化的參數。)
  • 在ceph.conf中添加四個最基本的設置
     echo "osd pool default size = 4" >> ceph.conf
     echo "osd_pool_default_min_size = 3" >> ceph.conf
     echo "public network = 192.168.120.0/24" >> ceph.conf
     echo "cluster network =  10.0.0.0/8" >> ceph.conf
    
     設置每個pool默認的副本數是兩個(所有文件一共存四份,如果不設置此項則默認爲三份副本);設置最小副本數爲3,也就是說,4份副本的環境下有一個副本損壞了,其他osd可以照常相應用戶的讀寫請求;設置公共網絡地址段,即用於相應客戶讀寫的網段;設置集羣工作網段,用於集羣同步數據、發送心跳等使用的網段。
  • 激活監控節點
    ceph-deploy mon create-initial
  • 接下來創建osd節點,本例中使用整個分區作爲osd節點的物理存儲區域
    ceph-deploy osd prepare node2:/dev/sdb1 node3:/dev/sdb1 node4:/dev/sdb1
    ceph-deploy osd prepare node2:/dev/sdb1 node3:/dev/sdb1 node4:/dev/sdb1
  • 將管理節點上的配置文件同步到其他節點上
    ceph-deploy --overwrite-conf admin node{1..4}
  • 建立元數據服務器
    ceph-deploy mds create node1
  • 創建兩個池,最後的數字是PG的數量
    ceph osd pool create test1 256
    ceph osd pool create test2 256
  • 創建cephfs文件系統,注意一個ceph只能創建一個cephfs
    ceph fs new cephfs test2 test1
    默認第一個池會存儲元數據
到此一個簡單的cephfs集羣就誕生了,可以使用ceph –s查看,如果是HEALTH_OK狀態說明配置成功

八、cephfs的刪除

  • remove所有節點上的ceph
    ceph-deploy purge node{1..4}
  • 清除所有數據
  • ceph-deploy purgedata node{1..4}
  • 清除所有祕鑰文件
    ceph-deploy forgetkeys

九、結語

  目前來說,ceph在開源社區還是比較熱門的,但是更多的是應用於雲計算的後端存儲。官方推薦使用ceph的對象式存儲,速度和效率都比較高,而cephfs官方並不推薦直接在生產中使用。以上介紹的只是ceph的滄海一粟,ceph遠比上面介紹的要複雜,而且支持很多特性,比如使用糾刪碼就行尋址,所以大多數在生產環境中使用ceph的公司都會有專門的團隊對ceph進行二次開發,ceph的運維難度也比較大。但是經過合理的優化之後,ceph的性能和穩定性都是值得期待的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章