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 磁盘上。