前言
之前公司安排出差支援非結構化項目,采用springcloud+(redis+mysql資料冷熱處理)+s3+es+ceph+kafka還涉及一些區塊鍊技術等等…,在與大佬的溝通交流下對ceph産生了興趣,私下學習記錄一下;後續工作之餘會采用上面相關技術棧手動實作不帶公司業務的項目,可能不會分享出來;
ceph叢集部署、Amazon S3 API java uitl
這篇記錄學習ceph的相關知識
ceph簡介
- ceph是⼀種分布式存儲系統,可以将多台伺服器組成⼀個超⼤叢集,把這些機器中的磁盤資源整合到⼀塊⼉,形成⼀個⼤的資源池,⽀持PB級别,然後按需配置設定給用戶端應⽤使⽤。
- ⽀持三種存儲接口: 對象存儲、塊存儲、⽂件存儲。
- 采⽤CRUSH算法,資料分布均衡,并⾏度⾼,不需要維護固定的中繼資料結構(與結構化存儲不同,了解為非結構化)。
- CRUSH需要叢集的映射,使⽤CRUSH映射在OSDs中僞随機存儲和檢索資料,資料在叢集中均勻分布,資料具有強⼀緻性,確定所有副本寫⼊完成後才傳回确認,适合讀多寫少的場景。
- 去中⼼化,沒有固定的中⼼節點,叢集擴充靈活。
- 去中⼼化的分布式解決⽅案,需要提前做好元件和節點部署規劃設計。
- ceph擴容時,由于其資料分布均衡的特性,會導緻整個存儲系統性能下降。
ceph核心元件
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL3ADO4UTYiJzNxEjMwcTMiRWYkRzMwE2Y4YGZwETOjF2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Monitor(ceph-mon):維護叢集Cluster Map的狀态,維護叢集的Cluster MAP⼆進制表,保證叢集資料的⼀緻性。Cluster
MAP描述了對象塊存儲的實體位置,以及⼀個将裝置聚合到實體位置的桶清單,map中包含monitor元件資訊,manger 元件資訊,osd
元件資訊,mds 元件資訊,crush 算法資訊。還負責ceph叢集的身份驗證功能,client 在連接配接ceph叢集時通過此元件進⾏驗證。
OSD(ceph-osd):OSD全稱Object Storage Device,⽤于叢集中所有資料與對象的存儲。ceph 管理實體硬碟時,引⼊了OSD概念,每⼀塊盤都會針對的運⾏⼀個OSD程序。換句話說,ceph 叢集通過管理 OSD
來管理實體硬碟。負責處理叢集資料的複制、恢複、回填、再均衡,并向其他osd守護程序發送⼼跳,然後向Mon提供⼀些監控資訊。當Ceph存儲叢集設定資料有兩個副本時(⼀共存兩份),則⾄少需要三個OSD守護程序即三個OSD節點,叢集才能達到active+clean狀态,實作備援和⾼可⽤。
- Manager(ceph-mgr):⽤于 收集ceph叢集狀态、運⾏名額,⽐如存儲利⽤率、目前性能名額和系統負載。對外提供 ceph dashboard(ceph ui)和 resetful api。Manager元件開啟⾼可⽤時,⾄少2個實作⾼可⽤性。
MDS(ceph-mds):Metadata server,中繼資料服務。為ceph ⽂件系統提供中繼資料計算、緩存與同步服務(ceph 對象存儲和塊存儲不需要MDS)。同樣,中繼資料也是存儲在osd節點中的,mds類似于中繼資料的 代理緩存伺服器,為 posix
⽂件系統⽤戶提供性能良好的基礎指令(ls,find等)不過隻是在需要使⽤CEPHFS時,才需要配置MDS節點。
- Object:Ceph最底層的存儲單元是Object對象,每個Object包含中繼資料和原始資料。
- PG:PG全稱Placement Grouops,是⼀個邏輯的概念,⼀個PG包含多個OSD。引⼊PG這⼀層其實是為了更好的配置設定資料和定位資料。
- RADOS:RADOS全稱Reliable Autonomic Distributed Object Store(可靠、⾃治、分布式對象存儲),是Ceph叢集的精華,⽤戶實作資料配置設定、Failover(故障轉移)等叢集操作。
- Libradio驅動庫:Librados是Rados提供庫,因為RADOS是協定很難直接通路,是以上層的RBD、RGW和CephFS都是通過librados通路的,⽬前提供PHP、Ruby、Java、Python、C和C++⽀持。
- CRUSH:Ceph使⽤的資料分布算法,類似⼀緻性哈希,讓資料配置設定到預期的地⽅。
- RBD:RBD全稱RADOS block device,是Ceph對外提供的塊裝置服務。
- RGW:RGW全稱RADOS gateway,是Ceph對外提供的對象存儲服務,接⼝與S3和Swift相容。
- CephFS:CephFS全稱Ceph File System,是Ceph對外提供的⽂件系統服務。
核心架構
基礎存儲系統RADOS
- RADOS(Reliable Autonomic Object Store,可靠、⾃動、分布式對象存儲)是ceph存儲叢集的基礎,這⼀層本身就是⼀個完整的對象存儲系統。Ceph的⾼可靠、⾼可擴充、⾼性能、⾼⾃動化等等特性本質上也都是由這⼀層所提供的,在ceph中,所有資料都以對象的形式存儲,并且⽆論什麼資料類型,RADOS對象存儲都将負責儲存這些對象,確定了資料⼀緻性和可靠性。
- RADOS系統主要由兩部分組成,分别是OSD(對象儲存設備)和Monitor(監控OSD)。
- 能夠在動态變化和異質結構的儲存設備機群之上提供⼀種穩定、可擴充、⾼性能的單⼀邏輯對象(Object)存儲接⼝和能夠實作節點的⾃适應和⾃管理的存儲系統。
- 在傳統分布式存儲架構中,存儲節點往往僅作為被動查詢對象來使⽤,随着存儲規模的增加,資料⼀緻性的管理會出現很多問題。⽽新型的存儲架構傾向于将基本的塊配置設定決策和安全保證等操作交給存儲節點來做,然後通過提倡用戶端和存儲節點直接互動來簡化資料布局并減⼩io瓶頸。
基礎庫LIBRADOS
LIBRADOS基于RADOS之上,它允許應⽤程式通過通路該庫來與RADOS系統進⾏互動,⽀持多種程式設計語⾔,⽐如C、C++、Python等。
上層接⼝RADOSGW、RBD和CEPHFS
- 基于LIBRADOS層開發的三個接⼝:RGW、RBD、CephFS,其作⽤是在librados庫的基礎上提供抽象層次更⾼、更便于應⽤或用戶端使⽤的上層接⼝。
- RADOS GW(簡稱RGW)提供對象存儲服務,是⼀套基于RESTFUL協定的⽹關,⽀持對象存儲,相容S3和Swift。
- RBD提供分布式的塊儲存設備接⼝,主要⾯向虛拟機提供虛拟磁盤,可以被映射、格式化,像磁盤⼀樣挂載到伺服器使⽤。
- CephFS是⼀個POSIX相容的分布式⽂件系統,依賴MDS來跟蹤⽂件層次結構,基于librados封裝原⽣接⼝,它跟傳統的⽂件系統如 Ext4 是⼀個類型的,但差別在于分布式存儲提供了并⾏化的能⼒,像NFS等也是屬于⽂件系統存儲。
- 這⾥提到了兩個對象,⼀個是RGW中的對象存儲;⼀個是Ceph的後端存儲的對象,這兩個需要區分: 第⼀個對象⾯向⽤戶,是⽤戶接⼝能通路到的對象; 第⼆個對象是ceph 服務端操作的對象。
ceph存儲接口
- ⽀持三種存儲接⼝:對象存儲,塊存儲,⽂件存儲,三種⽅式可⼀同使⽤,在底層的資料存儲是一緻的。⽀持⾃定義接⼝,⽀持多種語⾔驅動。
- ceph是⼀套存儲系統但它同時提供:對象存儲、塊裝置存儲、⽂件系統存儲。
- 對象存儲(Object):有原生的API,而且也相容OpenStack Swift API和Amazon S3 API。
- 塊裝置存儲(Block):支援精簡配置、快照、克隆。
- ⽂件系統存儲(File):Posix接口,支援快照。
三種存儲
塊存儲
- 主要是将裸磁盤空間映射給主機使用的;(磁盤陣列,硬碟)。
- 多塊硬碟組合起來,提高容量;多塊磁盤組合出來的邏輯盤,提升讀寫效率。但是,主機之間無法共享資料。
- 通過Raid與LVM等手段,對資料提供了保護,但是采用SAN架構組網時,光纖交換機,造價成本高。
- rbd:(rados block devices) 是由ceph叢集提供出來的塊裝置。rbd是通過⽹絡連接配接到了ceph叢集中的⼀塊存儲區域,往rbd裝置⽂件寫⼊資料,最終會被存儲到ceph叢集的這塊區域中。延升:sda和hda都是通過資料線連接配接到了真實的硬碟。
- 你可以了解為:往rbd裝置⽂件寫⼊資料,最終會被存儲到ceph叢集的這塊區域中。
檔案存儲
- 克服了塊存儲檔案無法共享的問題。
- 在伺服器上架設FTP與NFS服務,就是檔案存儲。
- 造價低,随便一台機器就可以了,但是讀寫速率低。
- 友善檔案共享,但是傳輸速率慢。
對象存儲
- 多台伺服器内置大容量硬碟,安裝上對象存儲管理軟體,對外提供讀寫通路功能,有原生的API,而且也相容OpenStack Swift API和Amazon S3 API。
- 具備塊存儲的讀寫高速和檔案存儲的共享等特性。
- 使⽤⽅式是通過http協定上傳下載下傳删除對象(⽂件即對象)。
- ⽂件系統存儲具有複雜的資料組織結構,能夠提供給⽤戶更加豐富的資料操作接⼝,⽽對象存儲精簡了資料組織結構,提供給⽤戶有限的資料操作接⼝,以換取更好的存儲性能。對象接⼝提供了REST API,⾮常适⽤于作為web應⽤的存儲。
塊裝置接口與檔案系統接口差別
Ceph的塊裝置具有優異的讀寫性能,但不能多處挂載同時讀寫,⽬前主要⽤在OpenStack上作為虛拟磁盤;⽽Ceph的⽂件系統接⼝讀寫性能較塊裝置接⼝差,但具有優異的共享性。
為什麼Ceph的塊裝置接⼝不具有共享性,⽽Ceph的⽂件系統接⼝具有呢?
- 對于Ceph的塊裝置接⼝,⽂件系統的結構狀态是維護在各⽤戶機記憶體中的。假設Ceph塊裝置同時挂載到了⽤戶機1和⽤戶機2,當在⽤戶機1上的⽂件系統中寫⼊資料後,更新了⽤戶機1的記憶體中⽂件系統狀态,最終資料存儲到了Ceph叢集中,但是此時⽤戶機2記憶體中的⽂件系統并不能得知底層Ceph叢集資料已經變化⽽維持資料結構不變,是以⽤戶⽆法從⽤戶機2上讀取⽤戶機1上新寫⼊的資料。
- 對于Ceph的⽂件系統接⼝,⽂件系統的結構狀态是維護在遠端Ceph叢集中的。Ceph⽂件系統同時挂載到了⽤戶機1和⽤戶機2,當往⽤戶機1的挂載點寫⼊資料後,遠端Ceph叢集中的⽂件系統狀态結構随之更新,當從⽤戶機2的挂載點通路資料時會去遠端Ceph叢集取資料,由于遠端Ceph叢集已更新,所有⽤戶機2能夠擷取最新的資料。
ceph底層存儲過程
ceph IO算法
- File使用者需要讀寫的檔案。File->Object映射:ino (File的中繼資料,File的唯一id)。
Object是RADOS需要的對象。Ceph指定一個靜态hash函數計算oid的值,将oid映射成一個近似均勻分布的僞随機值,然後和mask按位相與,得到pgid。Object->PG映射:
hash(oid) & mask-> pgid 。
PG(Placement Group),用途是對object的存儲進行組織和位置映射, (類似于redis cluster裡面的slot的概念)
一個PG裡面會有很多object。采用CRUSH算法,将pgid代入其中,然後得到一組OSD。PG->OSD映射:CRUSH(pgid)->(osd1,osd2,osd3)。
IO流程
- client 建立cluster handler。
- client 讀取配置檔案。
- client 連接配接上monitor,擷取叢集map資訊。
- client 讀寫io 根據crshmap 算法請求對應的主osd資料節點。
- 主osd資料節點同時寫入另外兩個副本節點資料。
- 等待主節點以及另外兩個副本節點寫完資料狀态。
- 主節點及副本節點寫入狀态都成功後,傳回給client,io寫入完成。
新加入的OSD1取代了原有的 OSD4成為 Primary OSD
這時新加入的OSD1取代了原有的 OSD4成為 Primary OSD, 由于 OSD1 上未建立 PG , 不存在資料,那麼 PG 上的 I/O 無法進行,怎樣工作的呢?
- client連接配接monitor擷取叢集map資訊。
- 同時新主osd1由于沒有pg資料會主動上報monitor告知讓osd2臨時接替為主。
- 臨時主osd2會把資料全量同步給新主osd1。
- client IO讀寫直接連接配接臨時主osd2進行讀寫。
- osd2收到讀寫io,同時寫入另外兩副本節點。
- 等待osd2以及另外兩副本寫入成功。
- osd2三份資料都寫入成功傳回給client, 此時client io讀寫完畢。
- 如果osd1資料同步完畢,臨時主osd2會交出主角色。
- osd1成為主節點,osd2變成副本。
ceph RBD IO
- 采用的是librbd的形式,使用librbd建立一個塊裝置,向這個塊裝置中寫入資料。
- 在用戶端本地同過調用librados接口,然後經過pool,rbd,object、pg進行層層映射,在PG這一層中,可以知道資料儲存在哪3個OSD上,這3個OSD分為主從的關系。
- 用戶端與primay OSD建立SOCKET 通信,将要寫入的資料傳給primary OSD,由primary OSD再将資料發送給其他replica OSD資料節點。
- 用戶端建立一個pool,需要為這個pool指定pg的數量。
- 建立pool/image rbd裝置進行挂載。
- 使用者寫入的資料進行切塊,每個塊的大小預設為4M,并且每個塊都有一個名字,名字就是object+序号。
- 将每個object通過pg進行副本位置的配置設定。
- pg根據cursh算法會尋找3個osd,把這個object分别儲存在這三個osd上。
- osd上實際是把底層的disk進行了格式化操作,一般部署工具會将它格式化為xfs檔案系統。
- object的存儲就變成了存儲一個文rbd0.object1.file。
Pool和PG分布
- pool是ceph存儲資料時的邏輯分區,它起到namespace的作用。
- 每個pool包含一定數量(可配置)的PG。
- PG裡的對象被映射到不同的Object上。
- pool是分布到整個叢集的。
- pool可以做故障隔離域,根據不同的使用者場景不一進行隔離。
OSD資料擴容
每個OSD上分布很多PG, 并且每個PG會自動散落在不同的OSD上。如果擴容那麼相應的PG會進行遷移到新的OSD上,保證PG數量的均衡。
心跳機制
ceph 心跳檢測
- OSD節點會監聽public、cluster、front和back四個端口。
- public端口:監聽來自Monitor和Client的連接配接。
- cluster端口:監聽來自OSD Peer的連接配接。
- front端口:供用戶端連接配接叢集使用的網卡, 這裡臨時給叢集内部之間進行心跳。
- back端口:供客叢集内部使用的網卡。叢集内部之間進行心跳。
- hbclient:發送ping心跳的messenger。
OSD之間互相心跳檢測
- 同一個PG内OSD互相心跳,他們互相發送PING/PONG資訊。
- 每隔6s檢測一次(實際會在這個基礎上加一個随機時間來避免峰值)。
- 20s沒有檢測到心跳回複,加入failure隊列。
OSD與Mon心跳檢測
OSD報告給Monitor:
- OSD有事件發生時(比如故障、PG變更)。
- 自身啟動5秒内。
OSD周期性的上報給Monito:
3.1 OSD檢查failure_queue中的OSD失敗資訊。
3.2 向Monitor發送失效報告,并将失敗資訊加入failure_pending隊列,然後将其從failure_queue移除。
3.3 收到來自failure_queue或者failure_pending中的OSD的心跳時,将其從兩個隊列中移除,并告知Monitor取消之前的失效報告。
3.4 當發生與Monitor網絡重連時,會将failure_pending中的錯誤報告加回到failure_queue中,并再次發送給Monitor。
Monitor統計下線OSD:
4.1 Monitor收集來自OSD的失效報告。
4.2 當錯誤報告指向的OSD失效超過一定門檻值,且有足夠多的OSD報告其失效時,将該OSD下線。
Ceph通過OSD彙報失效節點和Monitor統計來自OSD的心跳兩種方式判定OSD節點失效。
ceph通信架構
- Accepter監聽peer的請求, 調用 SimpleMessenger::add_accept_pipe() 建立新的 Pipe 到 SimpleMessenger::pipes 來處理該請求。
- Pipe用于消息的讀取和發送。該類主要有兩個元件,Pipe::Reader,Pipe::Writer用來處理消息讀取和發送。
- Messenger作為消息的釋出者, 各個 Dispatcher 子類作為消息的訂閱者, Messenger 收到消息之後, 通過 Pipe 讀取消息,然後轉給 Dispatcher 處理。
Dispatcher是訂閱者的基類,具體的訂閱後端繼承該類,初始化的時候通過 Messenger::add_dispatcher_tail/head 注冊到 Messenger::dispatchers.
收到消息後,通知該類處理。
- DispatchQueue該類用來緩存收到的消息, 然後喚醒 DispatchQueue::dispatch_thread 線程找到後端的 Dispatch 處理消息。
CRUSH算法
- CRUSH算法:(Controlled Scalable Decentralized Placement of Replicated Data),可控的、可擴充的、分布式的副本資料放置算法。
- pg到OSD的映射的過程算法叫做CRUSH 算法。(一個Object需要儲存三個副本,也就是需要儲存在三個osd上)。
- CRUSH算法是一個僞随機的過程,他可以從所有的OSD中,随機性選擇一個OSD集合,但是同一個PG每次随機選擇的結果是不變的,也就是映射的OSD集合是固定的。
CRUSH算法原理
CRUSH算法因子:層級化的Cluster Map、Placement Rules。
層級化的Cluster Map
- 樹形結構,OSDMap更多記錄的是OSDMap的屬性(epoch/fsid/pool資訊以及osd的ip等等)。
- 葉子節點是device(也就是osd),其他的節點稱為bucket節點,這些bucket都是虛構的節點,可以根據實體結構進行抽象,當然樹形結構隻有一個最終的根節點稱之為root節點,中間虛拟的bucket節點可以是資料中心抽象、機房抽象、機架抽象、主機抽象等。
Placement Rules(資料分布政策)
Bucket随機算法
- 一般的buckets:适合所有子節點權重相同,而且很少添加删除item。
- list buckets:适用于叢集擴充類型。增加item,産生最優的資料移動,查找item,時間複雜度O(n)。 tree buckets:查找負責度是O (log n), 添加删除葉子節點時,其他節點node_id不變。
- straw buckets:允許所有項通過類似抽簽的方式來與其他項公平“競争”。定位副本時,bucket中的每一項都對應一個随機長度的straw,且擁有最長長度的straw會獲得勝利(被選中),添加或者重新計算,子樹之間的資料移動提供最優的解決方案。
ceph 官方QOS原理
(目前官方QOS子產品屬于半成品)
補充
- mClock是一種基于時間标簽的I/O排程算法,最先被Vmware提出來的用于集中式管理的存儲系統。(目前官方QOS子產品屬于半成品)。