Ceph集羣管理node
每次用命令啓動、重啓、中止Ceph守護進程(或整個集羣)時,必須指定至少一個選項和一個命令,還可能要指定守護進程類型或具體例程。
**命令格式如算法
{commandline} [options] [commands] [daemons]
經常使用的commandline爲"ceph",對應的options以下表:json
對應的commands以下表:vim
能指定的daemons(守護進程)類型包括mon,osd及mds。bash
經過SysVinit機制運行ceph:網絡
在 CentOS、Redhat、發行版上能夠經過傳統的SysVinit運行Ceph,Debian/Ubuntu的較老的版本也能夠用此方法。
使用SysVinit管理Ceph守護進程的語法以下:app
[root@ceph ~] sudo /etc/init.d/ceph [options] [start|restart] [daemonType|daemonID]
1)管理Ceph集羣內全部類型的守護進程:
經過缺省[daemonType|daemonID],並添加"-a" options,就能夠達到同時對集羣內全部類型的守護進程進行啓動、關閉、重啓等操做目的。框架
[root@ceph ~] sudo /etc/init.d/ceph -a start
[root@ceph ~] sudo /etc/init.d/ceph -a stop
2)管理Ceph集羣內指定類型的守護進程:
根據命令語法,要啓動當前節點上某一類的守護進程,只需指定對應類型及ID便可。ssh
#啓動當前節點內全部OSD進程 [root@ceph ~] sudo /etc/init.d/ceph start osd #啓動當前節點內某一個OSD進程,以osd.0爲例 [root@ceph ~] sudo /etc/init.d/ceph start osd.0
重啓及關閉進程,以OSD進程爲例:
#關閉當前節點內全部OSD進程 [root@ceph ~] sudo /etc/init.d/ceph stop osd #關閉當前節點內某一個OSD進程,以osd.0爲例 [root@ceph ~] sudo /etc/init.d/ceph stop osd.0 #重啓當前節點內全部OSD進程 [root@ceph ~] sudo /etc/init.d/ceph restart osd #重啓當前節點內某一個OSD進程,以osd.0爲例 [root@ceph ~] sudo /etc/init.d/ceph restart osd.0
Ceph集羣狀態監控工具
1)檢查集羣健康情況
[root@ceph ~] ceph health [detail]
若是集羣處於健康狀態,會輸出HEALTH_OK,若是輸出HEALTH_WARN甚至HEALTH_ERR,代表Ceph處於一個不正常狀態,能夠加上"detail"選項幫助排查問題。
[root@ceph ~] sudo ceph -s #輸出的內容大體以下: cluster b370a29d-xxxx-xxxx-xxxx-3d824f65e339 health HEALTH_OK monmap e1: 1 mons at {ceph1=10.x.x.8:6789/0}, election epoch 2, quorum 0 ceph1 osdmap e63: 2 osds: 2 up, 2 in pgmap v41338: 952 pgs, 20 pools, 17130 MB data, 2199 objects 115 GB used, 167 GB / 297 GB avail 952 active+clean
經過以上命令,能夠快速瞭解Ceph集羣的clusterID,health情況,以及monitor、OSD、PG的map概況。
若是須要實時觀察Ceph集羣狀態變化,可以使用以下命令:
[root@ceph ~] sudo ceph -w
2)檢查集羣容量使用狀況
[root@ceph ~] sudo ceph df #輸出的內容大體以下 GLOBAL: SIZE AVAIL RAW USED %RAW USED 1356G 1284G 73943M 5.32 POOLS: NAME ID USED %USED MAX AVAIL OBJECTS images 1 24983M 1.80 421G 3158 volumes 2 32768k 0 421G 20 vms 3 3251M 0.23 421G 434
輸出的GLOBAL段顯示了數據所佔用集羣存儲空間概況。
輸出的POOLS段展現了存儲池列表及各存儲池的大體使用率。本段沒有展現副本、克隆品和快照佔用狀況。 例如,把1MB的數據存儲爲對象,理論使用量將是1MB,但考慮到副本數、克隆數、和快照數,實際使用量多是2MB或更多。
注:POOLS 段內的數字是理論值,它們不包含副本、快照或克隆。所以,它與USED和%USED數量之和不會達到GLOBAL段中的RAW USED和 %RAW USED數量。
PG管理操做
PG(歸置組)是多個object的邏輯存儲集合,每一個PG會根據副本級別而被複制多份。一個POOL的PG個數能夠在建立時指定,也能夠在以後進行擴大。可是須要注意的是,目前Ceph尚不支持減小POOL中的PG個數。
1)預約義PG個數
Ceph對於集羣內PG的總個數有以下公式:
(OSD個數\*100)/ 副本數 = PGs
以上公式計算得出結果後,再取一個與之較大的2的冪的值,即可做爲集羣的總PG數。例如,一個配置了200個OSD且副本數爲3的集羣,計算過程以下:
(200\*100)/3 = 6667. Nearest power of 2 : 8192
獲得8192後,能夠根據集羣內所需創建的POOL的個數及用途等要素,進行PG劃分。具體劃分細則請參考官 方計算工具 PGcalc: http://ceph.com/pgcalc/
2)設置PG數量
要設置某個POOL的PG數量(pg_num),必須在建立POOL時便指定,命令以下:
[root@ceph ~] sudo ceph osd pool create "pool-name" pg_num [pgp_num] [root@ceph ~] sudo ceph osd pool create image 256 256
須要注意的是,在後續增長PG數量時,還必須增長用於歸置PG的PGP數量(pgp_num),PGP的數量應該與PG的數量相等。但在新增POOL時能夠不指定pgp_num,默認會與pg_num保持一致。
新增PG數量:
[root@ceph ~] sudo ceph osd pool set "pool-name" pg_num [pgp_num] [root@ceph ~] sudo ceph osd pool set image 512 512
3)查看PG信息
若須要獲取某個POOL的PG數量或PGP數量,可使用以下命令:
[root@ceph ~] sudo ceph osd pool get "pool-name" pg_num/pgp_num [root@ceph ~] sudo ceph osd pool get image pg_num pg_num : 512 [root@ceph ~] sudo ceph osd pool get image pgp_num pgp_num : 512
若要獲取集羣裏PG的統計信息,可使用以下命令,並指定輸出格式:
#不指定輸出格式的狀況下,會輸出純文本內容,可指定格式爲json [root@ceph ~] sudo ceph pg dump [--format json]
若要獲取狀態不正常的PG的狀態,可使用以下命令:
[root@ceph ~] sudo ceph pg dump_stuck inactive|unclean|stale|undersized|degraded [--format <format>]
4)PG狀態概述
一個PG在它的生命週期的不一樣時刻可能會處於如下幾種狀態中:
Creating(建立中)
在建立POOL時,須要指定PG的數量,此時PG的狀態便處於creating,意思是Ceph正在建立PG。
Peering(互聯中)
peering的做用主要是在PG及其副本所在的OSD之間創建互聯,並使得OSD之間就這些PG中的object及其元數據達成一致。
Active(活躍的)
處於該狀態意味着數據已經無缺的保存到了主PG及副本PG中,而且Ceph已經完成了peering工做。
Clean(整潔的)
當某個PG處於clean狀態時,則說明對應的主OSD及副本OSD已經成功互聯,而且沒有偏離的PG。也意味着Ceph已經將該PG中的對象按照規定的副本數進行了複製操做。
Degraded(降級的)
當某個PG的副本數未達到規定個數時,該PG便處於degraded狀態,例如:
在客戶端向主OSD寫入object的過程,object的副本是由主OSD負責向副本OSD寫入的,直到副本OSD在建立object副本完成,並向主OSD發出完成信息前,該PG的狀態都會一直處於degraded狀態。又或者是某個OSD的狀態變成了down,那麼該OSD上的全部PG都會被標記爲degraded。
當Ceph由於某些緣由沒法找到某個PG內的一個或多個object時,該PG也會被標記爲degraded狀態。此時客戶端不能讀寫找不到的對象,可是仍然能訪問位於該PG內的其餘object。
Recovering(恢復中)
當某個OSD由於某些緣由down了,該OSD內PG的object會落後於它所對應的PG副本。而在該OSD從新up以後,該OSD中的內容必須更新到當前狀態,處於此過程當中的PG狀態即是recovering。
Backfilling(回填)
當有新的OSD加入集羣時,CRUSH會把現有集羣內的部分PG分配給它。這些被從新分配到新OSD的PG狀態便處於backfilling。
Remapped(重映射)
當負責維護某個PG的acting set變動時,PG須要從原來的acting set遷移至新的acting set。這個過程須要一段時間,因此在此期間,相關PG的狀態便會標記爲remapped。
Stale(陳舊的)
默認狀況下,OSD守護進程每半秒鐘便會向Monitor報告其PG等相關狀態,若是某個PG的主OSD所在acting set沒能向Monitor發送報告,或者其餘的Monitor已經報告該OSD爲down時,該PG便會被標記爲stale。
Monitor管理操做
1)檢查集羣內Monitor狀態
若是你有多個監視器(極可能),你啓動集羣后、讀寫數據前應該檢查監視器法定人數狀態。運行着多個監視器時必須造成法定人數,最好週期性地檢查監視器狀態來肯定它們在運行。
要查看monmap,能夠執行以下命令:
[root@ceph ~] sudo ceph mon stat #輸出內容大體以下: e3: 3 mons at {controller-21=172.x.x.21:6789/0,controller-22=172.x.x.22:6789/0, controller-23=172.x.x.23:6789/0}, election epoch 48710, quorum 0,1,2 controller-21,controller-22,controller-23
經過以上信息能夠了解到集羣內monmap版本爲3,共有3個Monitor守護進程,分別處於哪些主機( 主機名、IP地址、端口號)上,當前的Monitor選舉版本爲48710,Monitor集羣內的法定監視器共有3個(顯示的qourumID個數總和),以及它們的MonitorID。
若是但願進一步瞭解monmap,能夠經過以下命令查看:
[root@ceph ~] sudo ceph mon dump #輸出內容大體以下: dumped monmap epoch 3 epoch 3 fsid 86673d4c-xxxx-xxxx-xxxx-b61e6681305d last_changed 2016-09-02 16:05:02.120629 created 2016-09-02 16:03:39.311083 0: 172.16.130.21:6789/0 mon.controller-21 1: 172.16.130.22:6789/0 mon.controller-22 2: 172.16.130.23:6789/0 mon.controller-23
經過以上信息能夠額外瞭解到monmap建立時間及最近一次修改時間。
要獲知Ceph集羣內Monitor集羣法定監視器的狀況,可使用以下命令查看:
[root@ceph ~] sudo ceph quorum_status #輸出內容大體以下: {"election_epoch":48710,"quorum":[0,1,2], "quorum_names":["controller-21","controller-22","controller-23"], "quorum_leader_name":"controller-22", "monmap":{"epoch":3, "fsid":"86673d4c-xxx-xxxx-xxxxx-b61e6681305d", "modified":"2016-09-02 16:05:02.120629", "created":"2016-09-0216:03:39.311083", "mons":[{"rank":0,"name":"controller-21","addr":"172.16.130.21:6789\ / 0"}, {"rank":1,"name":"controller-22","addr":"172.16.130.22:6789\/0"}, {"rank":2,"name":"controller-23","addr":"172.16.130.23:6789\/0"}]}}
經過以上信息,能夠了解到Monitor集羣法定監視器的個數,以及監視器leader。
2)實際業務場景
場景1、使用ceph-deploy新增mon節點
需求:產品標準部署完成時,ceph mon通常會部署在某些OSD節點上,須要將mon拆到其餘節點上。
操做步驟:
-> 使用ceph-deploy新建mon
[root@host-name ~]#ceph-deploy mon create {host-name [host-name]...} [root@host-name ~]#ceph-deploy mon create newhostname
注意事項:
-> 中止本來在計算節點上的mon進程,驗證集羣是否正常,若是正常則進行下一步。
[root@host-name ~]# /etc/init.d/ceph stop mon
-> 刪除本來在計算節點上的monitor。
[root@host-name ~]# ceph-deploy mon destroy {host-name [host-name]...} [root@host-name ~]# ceph-deploy mon destroy oldhostname
-> 修改配置文件中關於mon的配置,不要使用主機名,應直接使用IP(public網絡),以後同步到全部ceph節點上並重啓全部mon進程。
注意事項:
因爲默認狀況下,主機名和IP的對應關係是使用的管理網絡,而使用ceph-deploy新增的monitor默認會使用ceph public網絡因此須要修改配置文件中"mon_intial_members"及"mon_host"中的主機名爲ip地址。
場景2、從一個monitor狀態異常的Ceph集羣中獲取monmap
需求:當一個Ceph集羣的monitor集羣狀態出現異常時,集羣的基本命令都沒法使用,這個時候能夠嘗試提取出monmap,幫助排查問題。
操做步驟:
-> 導出集羣monmap
[root@host-name ~]# ceph-mon -i mon-host-name --extract-monmap /tmp/monmap-file
注意:以上命令在mon狀態正常的節點上沒法使用。會報以下錯誤:
IO error: lock /var/lib/ceph/mon/ceph-cont01/store.db/LOCK: Resource temporarily unavailable
-> 使用monmaptool查看
[root@host-name ~]# monmaptool --print /tmp/monmap-file monmaptool: monmap file /tmp/monmap epoch 3 fsid 86673d4c-xxxx-xxxx-xxxx-b61e6681305d last_changed 2016-10-13 16:17:33.590245 created 2016-10-13 16:16:33.801453 0: 172.16.50.136:6789/0 mon.cont01 1: 172.16.50.137:6789/0 mon.cont02 2: 172.16.50.138:6789/0 mon.cont03
OSD管理操做
1)OSD狀態
單個OSD有兩組狀態須要關注,其中一組使用in/out標記該OSD是否在集羣內,另外一組使用up/down標記該OSD是否處於運行中狀態。兩組狀態之間並不互斥,換句話說,當一個OSD處於「in」狀態時,它仍然能夠處於up或down的狀態。
OSD狀態爲in且up
這是一個OSD正常的狀態,說明該OSD處於集羣內,而且運行正常。
OSD狀態爲in且down
此時該OSD尚處於集羣中,可是守護進程狀態已經不正常,默認在300秒後會被踢出集羣,狀態進而變爲out且down,以後處於該OSD上的PG會遷移至其它OSD。
OSD狀態爲out且up
這種狀態通常會出如今新增OSD時,意味着該OSD守護進程正常,可是還沒有加入集羣。
OSD狀態爲out且down
在該狀態下的OSD不在集羣內,而且守護進程運行不正常,CRUSH不會再分配PG到該OSD上。
2)檢查OSD狀態
在執行ceph health、ceph -s或ceph -w等命令時,也許會發現集羣並未處於HEALTH狀態,就OSD而言,應該關注它是否處於集羣內,以及是否處於運行中狀態。咱們能夠經過如下命令查看集羣內全部OSD的狀態:
[root@ceph ~] sudo ceph osd stat #輸出內容大體以下: osdmap e3921: 5 osds: 5 up, 5 in;
命令的結果顯示,當前osdmap的版本號爲e3921,集羣內共有5個OSD,其中處於「up」狀態的OSD爲5個,處於「in」狀態的OSD也爲5個。這說明集羣中OSD的狀態處於正常狀況。
若是要啓動一個OSD守護進程,請參考前文"集羣管理操做"內容
3)查看集羣OSD配置
要了解集羣OSD的配置狀況,可使用下列命令進行查看。
查看OSD容量的使用狀況
[root@ceph ~] sudo ceph osd df #輸出內容大體以下: ID WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR 0 0.25999 1.00000 269G 21378M 248G 7.75 1.38 3 0.25999 1.00000 269G 19027M 250G 6.90 1.23 4 0.25999 1.00000 269G 14207M 255G 5.15 0.92 1 0.53999 1.00000 548G 23328M 525G 4.15 0.74 TOTAL 1356G 77942M 1280G 5.61 MIN/MAX VAR: 0/1.38 STDDEV: 1.47
從輸出結果能夠看到每一個OSD的總容量、當前使用量以及可用容量等信息。
查看OSD在集羣佈局中的設計分佈
[root@ceph ~] sudo ceph osd tree #輸出內容大體以下: ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY -1 0.08995 root default -2 0.02998 host ceph01 0 0.00999 osd.0 up 1.00000 1.00000 1 0.00999 osd.1 up 1.00000 1.00000 2 0.00999 osd.2 up 1.00000 1.00000 -3 0.02998 host ceph02 3 0.00999 osd.3 up 1.00000 1.00000 4 0.00999 osd.4 up 1.00000 1.00000 5 0.00999 osd.5 up 1.00000 1.00000 -4 0.02998 host ceph03 6 0.00999 osd.6 up 1.00000 1.00000 7 0.00999 osd.7 up 1.00000 1.00000 8 0.00999 osd.8 up 1.00000 1.00000
從輸出結果能夠看到每一個OSD的位置分佈狀況,默認的CRUSHMAP中,OSD按照所在的主機節點分佈,能夠經過修改CRUSHMAP進行定製化分佈設計。同時能夠看到每一個OSD的WEIGHT值,WEIGHT值與OSD的容量相關,1TB容量換算WEIGHT值爲1.0。
查看OSD的dump概況
[root@ceph ~] sudo ceph osd dump
OSD dump輸出的條目較多,基本能夠分爲三個部分:
輸出OSDmap信息,包括版本號、集羣ID以及map相關的時間;
POOL的相關信息,包括POOL ID、POOL名稱、副本數、最小副本數、ruleset ID等信息;
列出全部OSD的狀態等信息,包括OSD ID、狀態、狀態版本記錄以及被監聽的IP地址及端口等信息。
4)實際業務場景
場景1、使用ceph-deploy新增OSD節點
需求:因爲某些緣由沒法使用salt進行擴容Ceph集羣時,能夠考慮使用ceph-deploy工具擴容Ceph集羣。
操做步驟:
-> 任選一個monitor節點,安裝ceph-deploy。
[root@host-name ~]# yum install ceph-deploy
-> 切換至Ceph集羣配置文件所在目錄,如使用默認名稱ceph,則切換至以下目錄。
[root@host-name ~]# cd /etc/ceph
-> 編輯/etc/hosts目錄,將新增節點的主機名及IP加入該文件中。
[root@host-name ~]# vim /etc/hosts
-> 在新增節點上安裝ceph軟件,並解決依賴關係,也許須要安裝redhat-lsb。
[root@new-node ~]# yum install ceph [root@new-node ~]# yum install redhat-lsb
-> 推送相關密鑰及配置文件至新增節點。
[root@host-name ceph]# ceph-deploy admin new-node
-> 建立集羣關係key。
[root@host-name ceph]# ceph-deploy gatherkeys 當前節點 [root@host-name ceph]# ceph-deploy gatherkeys new-node
-> 檢查新增OSD節點的磁盤。
[root@host-name ceph]# ceph-deploy disk list new-node
-> 建立所要新增OSD節點上的osd。
[root@host-name ceph]# ceph-deploy osd create new-node:new-disk
-> 少數狀況下,須要手動激活新增的osd後,集羣才能正常識別新增的osd。
[root@new-node ~]# ceph-disk activate-all
場景2、徹底刪除osd
需求:須要刪除Ceph集羣中一個或多個osd時,能夠參考如下作法實現。
操做步驟:
-> 中止須要刪除的osd進程。
[root@host-name ~]# /etc/init.d/ceph stop osd.x
-> 將該osd的集羣標記爲out。
[root@host-name ~]# ceph osd out osd.x
-> 將該osd從Ceph crush中移除。
[root@host-name ~]# ceph osd crush remove osd.x
-> 從集羣中徹底刪除該osd的記錄。
[root@host-name ~]# ceph osd rm osd.x
-> 刪除該osd的認證信息,不然該osd的編號不會釋放。
[root@host-name ~]# ceph auth del osd.x
POOL管理操做
1)獲取POOL概況
在部署一個Ceph集羣時,會建立一個默認名爲rbd的POOL,使用如下命令,能夠獲取集羣內全部POOL的概況信息。
[root@ceph ~] sudo ceph osd pool ls detail
使用該命令你能夠了解到集羣內POOL的個數、對應的POOL id、POOL名稱、副本數、最小副本數,ruleset及POOL snap等信息。
2)建立POOL
在建立一個新的POOL前,可先查看配置文件中是否有關於POOL的默認參數,同時瞭解集羣內CRUSHMAP的設計,以後再新建POOL。
例如,配置文件中有關於pg_num,pgp_num等默認參數,那麼在使用ceph-deploy自動化部署工具,便會以此參數建立指定POOL。
要手動建立一個POOL的命令語法以下:
#建立一個副本類型的POOL [root@ceph ~] sudo ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] \ [ruleset] #建立一個糾刪碼類型的POOL [root@ceph ~] sudo ceph osd pool create {pool-name} {pg-num} {pgp-num} erasure \ [erasure-code-profile] [ruleset]
在{}內的參數爲必選項,[]內的參數均設有默認值,若是沒有更改設計,能夠不添加。
參數的含義以下:
3)重命名POOL
若是須要重命名存儲池,可使用如下命令:
[root@ceph ~] sudo ceph osd pool rename {current-pool-name} {new-pool-name}
須要注意的是,在POOL被重命名後,須要用新的POOL名更新對應的認證用戶權限。此部份內容請參考:用戶管理操做
4)刪除POOL
刪除存儲池,可使用如下命令:
[root@ceph ~] sudo ceph osd pool delete {pool-name} [{pool-name} --yes-i-really-really-mean-it]
若是有某個認證用戶擁有該池的某些權限,那麼你應該確認該認證用戶是否還有其餘做用,確認完畢後,或更 新,或將該用戶刪除。
此部份內容請參考:用戶管理操做
5)設置POOL的配置
能夠爲每一個POOL進行配額,能夠設置最大字節數及最大object數,命令以下:
[root@ceph ~] sudo ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}] 例如: [root@ceph ~] sudo ceph osd pool set-quota data max_objects 10000 [root@ceph ~] sudo ceph osd pool set-quota data max_bytes 10240
若是要取消配額,只須要將值設置爲0便可。
6)查看POOL的統計信息
查看集羣內POOL的使用狀況,可使用如下命令:
[root@ceph ~] sudo rados df
7)POOL快照操做
要拍下某個POOL的快照,可使用如下命令:
[root@ceph ~] sudo ceph osd pool mksnap {pool-name} {snap-name} 例如: [root@ceph ~] sudo ceph osd pool mksnap snappool snap1
要刪除某個POOL的快照,可使用如下命令:
[root@ceph ~] sudo ceph osd pool rmsnap {pool-name} {snap-name} 例如: [root@ceph ~] sudo ceph osd pool rmsnap snappool snap1
要查看集羣中POOL的快照信息,暫時未提供ls-snap相關的命令,但能夠藉助前文提到的命令查看:
[root@ceph ~] sudo ceph osd pool ls detail
8)置object副本數量
要設置副本類型POOL的對象副本數,可使用如下命令:
[root@ceph ~] sudo ceph osd pool set {pool-name} size {num-replicas} 例如: [root@ceph ~] sudo ceph osd pool set replpool size 3
當一個object的副本數小於規定值時,仍然能夠接受I/O請求。爲了保證I/O正常,能夠爲POOL設置最低副本數,如:
[root@ceph ~] sudo ceph osd pool set replpool min_size 3
這確保了該POOL內任何副本數小於min_size的對象都不會再進行I/O。
====Ceph常見故障排除方法===
1)修改 OSD CRUSH weight
1.1)問題描述
部署完成後,集羣處於 PG Degraded 狀態,經查 ceph health detail,發現 PG 的 acting OSD 只有 [0],而不是兩個。查 osd tree,osd 日誌等,看不出明顯問題。
1.2)緣由分析
個人 Ceph 集羣的 OSD 的 weight 都是 0!!
[root@ceph1]# /etc/ceph# ceph osd tree # id weight type name up/down reweight -1 0 root default -2 0 host ceph1 0 0 osd.0 up 1 2 0 osd.2 up 1 -3 0 host ceph2 1 0 osd.1 up 1 3 0 osd.3 up 1
從上面 ceph osd tree 的結果裏面能夠看到這裏有兩個weight:weight 和 reweight。這篇文章 有詳細的分析。簡單來講:
所以,問題的癥結就在於 osd crush weight 爲0。至於爲何會這樣,以及該值對 PG 分配的影響,有待進一步查明。
1.3)解決辦法:修改 osd crush weight
ceph osd crush reweight osd.0 1 ceph osd crush reweight osd.1 1 ceph osd crush reweight osd.2 1 ceph osd crush reweight osd.3 1
修改後,集羣就回到了 HEALTH_OK 狀態。
注意:修改 OSD 的 crush weight 會帶來部分 PG 之間的數據移動,這可能會影響集羣的性能,所以在生產環境中使用要當心。你能夠參考 這篇文章 來看數據移動的狀況。
2)修改 CRUSH tunables(可調參數)
2.1 )問題描述
將 osd.1 設置爲 out 後,集羣並無開始作 recovery,部分 PG 保持在 remapped 狀態:
[root@ceph1]# ceph -s cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71 health HEALTH_WARN 88 pgs stuck unclean monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1 osdmap e71: 4 osds: 4 up, 3 in pgmap v442: 256 pgs, 4 pools, 285 MB data, 8 objects 690 MB used, 14636 MB / 15326 MB avail 88 active+remapped 168 active+clean
2.2)緣由分析
-> 查看 ceph health detail
[root@ceph1]# ceph health detail HEALTH_WARN 88 pgs stuck unclean pg 1.23 is stuck unclean for 337.342290, current state active+remapped, last acting [0,1] pg 0.1f is stuck unclean for 336.838743, current state active+remapped, last acting [0,1] pg 1.1f is stuck unclean for 337.355851, current state active+remapped, last acting [0,1]
Remapped(重映射):當 PG 的 acting set 變化後,數據將會從舊 acting set 遷移到新 action set。新主 OSD 須要過一段時間後才能提供服務。所以,它會讓老的主 OSD 繼續提供服務,直到 PG 遷移完成。數據遷移完成後,PG map 將使用新 acting set 中的主OSD。
以 PG 爲例,比較在 osd.1 out 先後的 PG map:
state state_stamp v reported up up_primary acting acting_primary active+clean 2016-06-03 00:31:44.220896 0'0 57:74 [0,1] 0 [0,1] 0 #osd.1 out 以前 active+remapped 2016-06-03 00:47:12.703537 0'0 71:109 [0] 0 [0,1] 0 #osd.1 out 以後
2.3)解決辦法
辦法一:將 cursh tunables 設置爲 optimal
-> 從這篇文章中得到線索,這可能和 crush tunables 有關係。它的默認值應該是 legacy,運行下面的命令將其修改成 optimal 後,集羣狀態回到正常。
ceph osd crush tunables optimal
-> 繼續找緣由,Red Hat 這篇文章 給出了一些線索。
在新版本的Ceph 集羣中使用 legacy 值可能會有一些問題,包括:
而第一種狀況正是個人測試集羣所遇到的狀況,每一個 host 擁有的 OSD 數目在3個之內,而後部分 PG 所在的 OSD 數目較 replica 少一些。
辦法二:將 OSD 的 reweight 修改成 0 而不是使用 out 命令
Ceph 官方的這篇文章 給出了另外一個思路。它認爲在主機數目很小的集羣中,當一個 OSD 被 out 後,部分 PG 限於 active+remapped 狀態是常常出現的。解決辦法是先運行 ceph osd in {osd-num} 將集羣狀態恢復到初始狀態,而後運行 ceph osd crush reweight osd.{osd-num} 0 來將這個 osd 的 crush weight 修改成 0,而後集羣會開始數據遷移。對小集羣來講,reweight 命令甚至更好些。
當集羣中 PG 限於 active + remapped 狀態時,能夠經過 reweight 命令來使得集羣恢復正常。當往集羣中新加入 OSD 時,爲了減小數據移動對集羣性能的影響,Ceph 官方建議逐漸地增長 OSD 的 crush weight,好比起始值爲0,先設置爲 0.2,等數據遷移結束,再設置爲 0.4,依此類推,逐漸增長爲 0.6,0.8 和 1 甚至更高。在要停用一個 OSD 時,建議採用相反操做,逐漸減小 OSD 的 crush weight 直至 0.
3)修改 CRUSH ruleset
3.1)問題描述
繼續將跟 osd.1 在贊成個host 上的 osd.3 out,看看 Ceph 集羣能不能繼續恢復。Ceph 集羣中部分 PG 再次進入 remapped 狀態:
[root@ceph1:~]# ceph -s cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71 health HEALTH_WARN 256 pgs stuck unclean monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1 osdmap e77: 4 osds: 4 up, 2 in pgmap v480: 256 pgs, 4 pools, 285 MB data, 8 objects 625 MB used, 9592 MB / 10217 MB avail 256 active+remapped
運行 ceph pg 1.0 query 查看 PG 1.0 的狀態:
"recovery_state": [ { "name": "Started\/Primary\/Active", "enter_time": "2016-06-03 01:31:22.045434", "might_have_unfound": [], "recovery_progress": { "backfill_targets": [], "waiting_on_backfill": [], "last_backfill_started": "0\/\/0\/\/-1", "backfill_info": { "begin": "0\/\/0\/\/-1", "end": "0\/\/0\/\/-1", "objects": []}, "peer_backfill_info": [], "backfills_in_flight": [], "recovering": [], "pg_backend": { "pull_from_peer": [], "pushing": []}}, "scrub": { "scrubber.epoch_start": "0", "scrubber.active": 0, "scrubber.block_writes": 0, "scrubber.finalizing": 0, "scrubber.waiting_on": 0, "scrubber.waiting_on_whom": []}}, { "name": "Started", "enter_time": "2016-06-03 01:31:20.976290"}],
可見它已經開始 recovery 了,可是沒完成。
3.2)緣由分析
PG 的分佈和 CRUSH ruleset 有關。個人集羣當前只有一個默認的 ruleset:
[root@ceph1:~]# ceph osd crush rule dump [ { "rule_id": 0, "rule_name": "replicated_ruleset", "ruleset": 0, "type": 1, "min_size": 1, "max_size": 10, "steps": [ { "op": "take", "item": -1, "item_name": "default"}, { "op": "chooseleaf_firstn", "num": 0, "type": "host"}, { "op": "emit"}]}]
注意其 type 爲 「host」,也就是說 CRUSH 不會爲一個 PG 選擇在同一個 host 上的兩個 OSD。而個人環境中,目前只有 ceph1 上的兩個 OSD 是in 的,所以,CRUSH 沒法爲全部的 PG 從新選擇一個新的 OSD 來替代 osd.3.
3.3)解決辦法
按照如下步驟,將 CRUSH ruleset 的 type 由 「host」 修改成 「osd」,使得 CRUSH 爲 PG 選擇 OSD 時再也不侷限於不一樣的 host。
[root@ceph1:~]# ceph osd getcrushmap -o crushmap_compiled_file got crush map from osdmap epoch 77 [root@ceph1:~]# crushtool -d crushmap_compiled_file -o crushmap_decompiled_file [root@ceph1:~]# vi crushmap_decompiled_file rule replicated_ruleset { ruleset 0 type replicated min_size 1 max_size 10 step take default step chooseleaf firstn 0 type osd #將 type 由 「host」 修改成 「osd」 step emit } [root@ceph1:~]# crushtool -c crushmap_decompiled_file -o newcrushmap [root@ceph1:~]# ceph osd setcrushmap -i newcrushmap set crush map
以上命令執行完畢後,能夠看到 recovery 過程繼續進行,一段時間後,集羣恢復 OK 狀態。
[root@ceph1:~]# ceph -s cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71 health HEALTH_WARN 256 pgs stuck unclean monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1 osdmap e80: 4 osds: 4 up, 2 in pgmap v493: 256 pgs, 4 pools, 285 MB data, 8 objects 552 MB used, 9665 MB / 10217 MB avail 256 active+remapped [root@ceph1:~]# ceph -s cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71 health HEALTH_WARN 137 pgs stuck unclean monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1 osdmap e80: 4 osds: 4 up, 2 in pgmap v494: 256 pgs, 4 pools, 285 MB data, 8 objects 677 MB used, 9540 MB / 10217 MB avail 137 active+remapped 119 active+clean recovery io 34977 B/s, 0 objects/s [root@ceph1:~]# ceph -s cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71 health HEALTH_OK monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1 osdmap e80: 4 osds: 4 up, 2 in pgmap v495: 256 pgs, 4 pools, 285 MB data, 8 objects 679 MB used, 9538 MB / 10217 MB avail 256 active+clean recovery io 18499 kB/s, 0 objects/s
4)將一個 OSD 移出集羣
4.11)將該 osd 設置爲 out
[root@ceph1:/home/s1]# ceph osd out osd.1 marked out osd.1.
4.2)集羣作 recovery
2017-06-03 01:54:21.596632 mon.0 [INF] osdmap e90: 4 osds: 4 up, 3 in 2017-06-03 01:54:21.608675 mon.0 [INF] pgmap v565: 256 pgs: 256 active+clean; 1422 MB data, 2833 MB used, 12493 MB / 15326 MB avail 2017-06-03 01:54:26.352909 mon.0 [INF] pgmap v566: 256 pgs: 1 active, 255 active+clean; 1422 MB data, 2979 MB used, 12347 MB / 15326 MB avail; 2/40 objects degraded (5.000%); 51033 B/s, 0 objects/s recovering 2017-06-03 01:54:28.624334 mon.0 [INF] pgmap v567: 256 pgs: 4 active, 252 active+clean; 1422 MB data, 3427 MB used, 11899 MB / 15326 MB avail; 8/40 objects degraded (20.000%); 51053 B/s, 0 objects/s recovering 2017-06-03 01:54:31.320973 mon.0 [INF] pgmap v568: 256 pgs: 3 active, 253 active+clean; 1422 MB data, 3539 MB used, 11787 MB / 15326 MB avail; 6/40 objects degraded (15.000%); 19414 kB/s, 0 objects/s recovering 2017-06-03 01:54:32.323443 mon.0 [INF] pgmap v569: 256 pgs: 256 active+clean; 1422 MB data, 3730 MB used, 11595 MB / 15326 MB avail; 77801 kB/s, 0 objects/s recovering 2017-06-03 01:56:10.949077 mon.0 [INF] pgmap v570: 256 pgs: 256 active+clean; 1422 MB data, 3730 MB used, 11595 MB / 15326 MB avail
4.3)完成後,該 osd 的狀態仍是 up,表示它的服務還在運行。如今將其服務停掉。
[root@ceph1:/home/s1]# ssh ceph2 service ceph stop osd.1 /etc/init.d/ceph: osd.1 not found (/etc/ceph/ceph.conf defines , /var/lib/ceph defines )
該命令出錯,須要將 osd.1 加入 ceph.conf 中。在 ceph1 上的 ceph.conf 中添加:
[osd] [osd.1] host = ceph2 [osd.2] host = ceph1 [osd.3] host = ceph2 [osd.0] host = ceph1
而後運行 ceph-deploy –overwrite-conf config push ceph2 將它拷貝到 ceph2 上。重啓全部的 osd 服務。詭異的事情出現了:
[root@ceph1:/etc/ceph]# ceph osd tree # id weight type name up/down reweight -1 4 root default -2 4 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 1 1 osd.1 up 0 3 1 osd.3 up 1 -3 0 host ceph2
osd.1 和 osd.3 跑到了 ceph1 節點上!查看 start 命令,它將 curshmap 中的 osd.1 的 host 修改成了 ceph2:
[root@ceph1:/etc/ceph]# /etc/init.d/ceph -a start osd === osd.1 === df: ‘/var/lib/ceph/osd/ceph-1/.’: No such file or directory create-or-move updating item name 'osd.1' weight 1 at location {host=ceph1,root=default} to crush map Starting Ceph osd.1 on ceph2... starting osd.1 at :/0 osd_data /var/lib/ceph/osd/ceph-1 /var/lib/ceph/osd/ceph-1/journal
從 這篇文章 能夠看出,這實際上是Ceph的一個 bug:make osd crush placement on startup handle multiple trees (e.g., ssd + sas)。該bug 在 OSD location reset after restart 中也有討論。目前 Ceph 沒有機制能夠確保 CRUSH map 結構不變,最簡單的辦法是在 ceph.conf 中 [OSD] 部分設置 osd crush update on start = false。
嘗試手工挪動 osd.1 和 osd.3:
[root@ceph1:/etc/ceph]# ceph osd crush remove osd.1 removed item id 1 name 'osd.1' from crush map [root@ceph1:/etc/ceph]# ceph osd crush remove osd.3 removed item id 3 name 'osd.3' from crush map [root@ceph1:/etc/ceph]# ceph osd tree # id weight type name up/down reweight -1 2 root default -2 2 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 -3 0 host ceph2 1 0 osd.1 up 0 3 0 osd.3 up 1 [root@ceph1:/etc/ceph]# ceph osd crush set 1 1 root=default host=ceph2 Error ENOENT: unable to set item id 1 name 'osd.1' weight 1 at location {host=ceph2,root=default}: does not exist
該錯誤的緣由待查。索性直接修改 crush map,而後正確的結果就回來了:
[root@ceph1:/etc/ceph]# ceph osd tree # id weight type name up/down reweight -1 2 root default -2 2 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 -3 0 host ceph2 1 1 osd.1 up 0 3 1 osd.3 up 1
繼續運行命令 ssh ceph2 /etc/init.d/ceph stop osd.1 去中止 osd.1 的服務,可是沒法中止。聽說是由於用 ceph-deploy 部署的 OSD 的服務都無法中止。只能想辦法把進程殺掉了。
而後繼續執行:
[root@ceph1:/etc/ceph]# ceph osd crush remove osd.1 removed item id 1 name 'osd.1' from crush map [root@ceph1:/etc/ceph]# ceph auth del osd.1 updated [root@ceph1:/etc/init]# ceph osd rm osd.1 removed osd.1
此時,osd tree 中再也沒有 osd.1 了:
[root@ceph1:/etc/ceph]# ceph osd tree # id weight type name up/down reweight -1 3 root default -2 2 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 -3 1 host ceph2 3 1 osd.3 up 1
5)將一個 OSD 加入集羣
結果OSD就回來了:
[root@ceph1:~]# ceph-deploy osd create ceph2:sdb:/dev/sdd1c^C [root@ceph1:~]# ceph osd tree # id weight type name up/down reweight -1 2 root default -2 2 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 -3 0 host ceph2 4 0 osd.4 up 1 1 0 osd.1 up 1
其實將上面第四步和第五步合併在一塊兒,就是替換一個故障磁盤的過程。
6)在特定 OSD 上建立存儲池
假設 osd.0 和 osd.2 的磁盤是 SSD 磁盤,osd.1 和 osd.4 的磁盤是 SATA 磁盤。咱們將建立兩個pool:pool-ssd 和 pool-sata,並確保 pool-ssd 中的對象都保存在 osd.0 和 osd.2 上,pool-sata 中的對象都保存在 osd.1 和 osd.4 上。
6.1)修改 CRUSH map
[root@ceph1:~]# ceph osd getcrushmap -o crushmapdump got crush map from osdmap epoch 124 [root@ceph1:~]# crushtool -d crushmapdump -o crushmapdump-decompiled [root@ceph1:~]# vi crushmapdump-decompiled [root@ceph1:~]# crushtool -c crushmapdump-decompiled -o crushmapdump-compiled [root@ceph1:~]# ceph osd setcrushmap -i crushmapdump-compiled
在 crushmapdump-decompiled 文件中添加以下內容:
root ssd { id -5 alg straw hash 0 item osd.0 weight 1 item osd.2 weight 1 } root sata { id -6 alg straw hash 0 item osd.1 weight 1 item osd.4 weight 1 } # rules ... rule ssd-pool { ruleset 1 type replicated min_size 1 max_size 10 step take ssd step chooseleaf firstn 0 type osd step emit } rule sata-pool { ruleset 2 type replicated min_size 1 max_size 10 step take sata step chooseleaf firstn 0 type osd step emit }
6.2) ceph osd tree 以下:
[root@ceph1:~]# ceph osd tree # id weight type name up/down reweight -6 2 root sata 1 1 osd.1 up 1 4 1 osd.4 up 1 -5 2 root ssd 0 1 osd.0 up 1 2 1 osd.2 up 1 -1 2 root default -2 2 host ceph1 0 1 osd.0 up 1 2 1 osd.2 up 1 -3 0 host ceph2 4 0 osd.4 up 1 1 0 osd.1 up 1
6.3)建立 ssd-pool,其默認的 ruleset 爲 0:
[root@ceph1:~]# ceph osd pool create ssd-pool 8 8 pool 'ssd-pool' created root@ceph1:~# ceph osd dump | grep -i ssd pool 4 'ssd-pool' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 8 pgp_num 8 last_change 126 flags hashpspool stripe_width 0
6.4)修改 ssd-pool 的 ruleset 爲 ssd-pool 其id 爲 1:
[root@ceph1:~]# ceph osd pool set ssd-pool crush_ruleset 1 set pool 4 crush_ruleset to 1 [root@ceph1:~]# ceph osd dump | grep -i ssd pool 4 'ssd-pool' replicated size 2 min_size 1 crush_ruleset 1 object_hash rjenkins pg_num 8 pgp_num 8 last_change 128 flags hashpspool stripe_width 0
6.5)相似地建立 sata-pool 並設置其 cursh ruleset 爲 sata-pool 其id 爲 2:
[root@ceph1:~]# ceph osd pool create sata-pool 8 8 pool 'sata-pool' created [root@ceph1:~]# ceph osd pool set sata-pool crush_ruleset 2 set pool 5 crush_ruleset to 2 [root@ceph1:~]# ceph osd dump | grep -i sata pool 5 'sata-pool' replicated size 2 min_size 1 crush_ruleset 2 object_hash rjenkins pg_num 8 pgp_num 8 last_change 131 flags hashpspool stripe_width 0
6.6)分別放一個文件進這兩個pool:
[root@ceph1:/home/s1]# rados -p ssd-pool put root-id_rsa root-id_rsa [root@ceph1:/home/s1]# rados -p sata-pool put root-id_rsa root-id_rsa [root@ceph1:/home/s1]# rados -p ssd-pool ls root-id_rsa [root@ceph1:/home/s1]# rados -p sata-pool ls root-id_rsa
6.7)查看對象所在的 OSD
[root@ceph1:/home/s1]# ceph osd map ssd-pool root-id_rsa osdmap e132 pool 'ssd-pool' (4) object 'root-id_rsa' -> pg 4.38e001ef (4.7) -> up ([2,0], p2) acting ([2,0], p2) [root@ceph1:/home/s1]# ceph osd map sata-pool root-id_rsa osdmap e132 pool 'sata-pool' (5) object 'root-id_rsa' -> pg 5.38e001ef (5.7) -> up ([4,1], p4) acting ([4,1], p4)
可見,兩個pool各自在ssd 和 sata 磁盤上。