Ceph的概述

目录

Ceph的概述

参考资料

设计目标

Ceph是加州大学Santa Cruz分校的Sage Weil(DreamHost的联合创始人)专为博士论文(PhD)设计的新一代自由软件分布式文件系统。自2007年毕业之后,Sage开始全职投入到Ceph开发之中,使其能适用于生产环境。

Ceph的主要目标是设计成基于POSIX的没有单点故障的(SPoF)分布式文件系统,容量轻松扩展到数PB,数据能够容错和无缝复制。2010年3月,Linus Torvalds将Ceph client合并到内核2.6.34中(Ceph Dependencies)。

不幸的是,这些目标之间会互相竞争(例如,可扩展性会降低或者抑制性能或者影响可靠性)。Ceph 开发了一些非常有趣的概念(例如,动态元数据分区去中心化的数据分布和多副本存储),Ceph 的设计还包括保护单一点故障的容错功能,它假设大规模(PB 级存储)存储故障是常见现象而不是例外情况。

优点:关键特征

  1. 低开销(内核级的驱动支持,性能更高,不影响用户级更新功能完善)
  2. 灵活性(统一底层object对象存储,上层提供fs,block,radosgw,librados接口,方便开发)
  3. 扩展性(容量设计可达PB级别)
  4. 完整性(PAXOS分布式选举和CURSH存储算法)
  5. 开源代码(更加透明安全,迭代更快,社区反馈和推广都相对成熟,代码会越来越完善)

Ceph uniquely delivers object, block, and file storage in one unified system. Ceph is highly reliable, easy to manage, and free.

缺点

  1. 对Btrfs依赖强,但btrfs目前还不成熟,临时解决方法是使用xfs来替换
  2. ceph的程序整体成熟度欠佳,会有内存泄漏和OSD/MON 偶发crash的异常出现

创新设计

对象存储系统的基本问题是如何分布数据到上千个存储设备上?

一个robust解决方案是把数据随机分布到存储设备上,这个方法能够保证负载均衡,保证新旧数据混合在一起。但是简单HASH分布不能有效处理设备数量的变化,导致大量数据迁移。

Ceph开发了CRUSH(Controled Replication Under Scalable Hashing),一种伪随机(确定性)的数据分布算法,它能够在层级结构的存储集群中有效的分布对象的副本。

  • CRUSH算法函数只需要参数:object id或object group id,并返回一组存储设备(用于保存object副本)。
  • CRUSH需要cluster map(描述存储集群的层级结构)、和副本分布策略(rule)。

CRUSH有三个关键优点:

  1. 任何组件都可以独立计算出每个object所在的位置(去中心化)。
  2. 只需要很少的元数据(cluster map),只要当删除添加设备时,这些元数据才需要改变。
  3. 副本策略定义包括bucket, rock, host, row 三种角色和四种结构算法,搭配定制。

CRUSH算法

参考资料

CRUSH算法通过每个设备的权重来计算数据对象的分布。对象分布是由cluster map和data distribution policy决定的。cluster map描述了可用存储资源和层级结构(比如有多少个机架,每个机架上有多少个服务器,每个服务器上有多少个磁盘)。data distribution policy由placement rules组成。rule决定了每个数据对象有多少个副本,这些副本存储的限制条件(比如3个副本放在不同的机架中)。

CRUSH算出x到一组OSD集合(OSD是对象存储设备):

(osd0, osd1, osd2 … osdn) = CRUSH(x)

CRUSH利用多参数HASH函数,HASH函数中的参数包括x,使得从x到OSD集合是确定性的和独立的。CRUSH只使用了cluster map、placement rules、x。CRUSH是伪随机算法,相似输入的结果之间没有相关性。

副本存储:PG

参考资料

ceph中引入了PG(placement group)的概念,PG是一个虚拟的概念,并不对应什么实体,类似于逻辑分区,一个PG可存放多个对象,每个存储节点可有上百个PG(官方推荐值为100)。

一个PG(placement group)由一个OSD列表组成,OSD的个数,就是对象的副本数,如三副本的PG就是由一个主,两个副本的OSD列表组成。

ceph中 PG的意义

首先是经过一个哈希函数把key映射到Placement Group(简称PG)。PG第二层是通过一致性哈希函数CRUSH从PGID映射到到实际存放数据的主机,对于给定PGID和副本数量,CRUSH会生成副本位置信息。其中第一个副本是主,其它为从。

主副本负责接收来自客户端的写,产生日志同步给从副本。如果出现多个客户端并发写,主副本也扮演协调者决定并发写的顺序。当少量机器发生宕机时,作为一致性哈希函数,CRUSH产生的PG副本的位置不会有很大改别。同时,缺失数据的其它副本散落在整个集群,这就保证了补齐副本数据时可以利用整个集群的网络带宽。

常用分布式文件系统对比

MooseFS(MFS)CephGlusterFSLustre
Metadata server单个MDS。存在单点故障和瓶颈。多个MDS,不存在单点故障和瓶颈。MDS可以扩展,不存在瓶颈。无,不存在单点故障。靠运行在各个节点上的动态算法来代替MDS,不需同步元数据,无硬盘I/O瓶颈。双MDS(互相备份)。MDS不可以扩展,存在瓶颈。
FUSE支持支持支持支持
访问接口POSIXPOSIXPOSIXPOSIX/MPI
文件分布/数据分布文件被分片,数据块保存在不同的存储服务器上。文件被分片,每个数据块是一个对象。对象保存在不同的存储服务器上。Cluster Translators(GlusterFS集群存储的核心)包括AFR、DHT和Stripe三种类型。AFR相当于RAID1,每个文件都被复制到多个存储节点上。Stripe相当于RAID0,文件被分片,数据被条带化到各个存储节点上。Translators可以组合,即AFR和stripe可以组成RAID10,实现高性能和高可用。可以把大文件分片并以类似RAID0的方式分散存储在多个存储节点
冗余保护/副本多副本多副本镜像
数据可靠性由数据的多副本提供可靠性。由数据的多副本提供可靠性。由镜像提供可靠性。由存储节点上的RAID1或RAID5/6提供可靠性。假如存储节点失效,则数据不可用。
备份 提供备份工具。支持远程备份。
故障恢复手动恢复当节点失效时,自动迁移数据、重新复制副本。当节点、硬件、磁盘、网络发生故障时,系统会自动处理这些故障,管理员不需介入。
扩展性增加存储服务器,可以提高容量和文件操作性能。但是由于不能增加MDS,因此元数据操作性能不能提高,是整个系统的瓶颈。可以增加元数据服务器和存储节点。容量可扩展。文件操作性能可扩展。元数据操作性能可扩展。容量可扩展。可增加存储节点,提高容量可文件操作性能,但是由于不能增加MDS,因此元数据操作性能不能提高,是整个系统的瓶颈。
安装/部署简单简单简单复杂。而且Lustre严重依赖内核,需要重新编译内核。
开发语言CC++CC
适合场景大量小文件读写小文件适合大文件。对于小文件,无元数据服务设计解决了元数据的问题。但GlusterFS并没有在I/O方面作优化,在存储服务器底层文件系统上仍然是大量小文件,本地文件系统元数据访问是瓶颈,数据分布和并行性也无法充分发挥作用。因此,GlusterFS的小文件性能还存在很大优化空间。大文件读写
产品级别小型中型中型重型
应用国内较多较多用户使用HPC的集群任务调度器
优缺点实施简单,但是存在单点故障。不稳定,目前还在实验阶段,不适合于生产环境。无元数据服务器,堆栈式架构(基本功能模块可以进行堆栈式组合,实现强大功能)。具有线性横向扩展能力。由于没有元数据服务器,因此增加了客户端的负载,占用相当的CPU和内存。但遍历文件目录时,则实现较为复杂和低效,需要搜索所有的存储节点。因此不建议使用较深的路径。很成熟

Ceph研究实战

前期安装

环境配置

  1. OS-NODE1 客户端,测试前端
  2. OS-FS1 Ceph OSD,MON,MDS,一块系统盘,两块OSD数据盘(/dev/sdb1,/dev/sdc1)
  3. XFS文件系统 (mkfs.xfs -l internal,lazy-count=1,size=128m -i attr=2 -d agcount=8 -i size=512)
  4. mount -t xfs -o rw,swalloc,noexec,nodev,noatime,nodiratime,nobarrier,logbufs=8,logbsize=256k
  5. Ceph 0.56(Notable) 性能好于 v0.55(bobtail),0.48(argonaut)
  6. kenel >= 3.6.x livirt >= 0.9.13 qemu >= 0.14

升级内核

Kernel (3.6.11)

  • v3.6.6 or later in the v3.6 stable series
  • v3.4.20 or later in the v3.4 stable series

内核选项

  1. CONFIGBTRFSFS=m
  2. CONFIGBTRFSFSPOSIXACL=y
  3. # CONFIGBTRFSFSCHECKINTEGRITY is not set
  4. CONFIGCEPHFS=m
  5. CONFIGCEPHLIB=m
  6. CONFIGCEPHLIBPRETTYDEBUG=y - CONFIGCEPHLIBUSEDNSRESOLVER=y
  7. CONFIGBLKDEVDRBD=m - # CONFIGDRBDFAULTINJECTION is not set

内核编译注意选项

General setup

Kernel hacking

Security options

Cryptographic API

可选编译项,只保留必要的加密算法

安装软件包

yum install -y cryptopp.x86_64 cryptopp-devel.x86_64 libedit.x86_64 libedit-devel.x86_64 \
               libatomic_ops-devel.x86_64 snappy.x86_64 snappy-devel.x86_64 boost-devel.x86_64
 
./configure --prefix=/usr/local --sysconfdir=/etc --localstatedir=/var \
            --without-hadoop --without-nss --without-fuse --without-debug \
            --with-tcmalloc --with-rest-bench \
            --disable-static --disable-cephfs-java

快速配置

配置文件

[global]
        ; For version 0.55 and beyond, you must explicitly enable
        ; or disable authentication with "auth" entries in [global].
        auth cluster required = cephx
        auth service required = cephx
        auth client required = cephx
        keyring = /etc/ceph/keyring
 
[osd]   
        osd data = /srv/ceph/osd$id
        osd journal = /srv/ceph/osd$id/journal
        osd journal size = 512
        keyring = /etc/ceph/keyring.$name
        osd mkfs type = xfs
        ; solve rbd data corruption (sileht: disable by default in 0.48)
        filestore fiemap = false
        ; The following assumes ext4 filesystem.
        filestore xattr use omap = true
 
[mon]
        mon data = /srv/ceph/mon$id
 
[mon.a]
        host = OS-FS1
        mon addr = 192.168.10.2:6789
 
[osd.0]
        host = OS-FS1
        devs = /dev/sdb1
 
[osd.1]
        host = OS-FS1
        devs = /dev/sdc1
/etc/hosts 保证两台机器的主机名一致

生成keyring

mkcephfs -a -c /etc/ceph/ceph.conf
#也支持导入crushmap,osdmap
mkcephfs -a -c /etc/ceph/ceph.conf --crushmap /etc/ceph/crush.map --osdmap /etc/ceph/osd.map

CEPHFS方式挂载

mount -t ceph 192.168.10.2:6789:/ /srv/ -o name=admin,secret=$(awk '/key/{print $3}' /etc/ceph/ceph.keyring)

RBD块设备操作指令

rados lspools
rados mkpool nova
rados rmpool nova
 
rbd list [nova]
rbd create foo --pool nova --size 4096
rbd map foo --pool rbd --name client.admin
rbd map foo --pool nova --keyring /etc/ceph/ceph.keyring
rbd showmapped
rbd unmap /dev/rbd6
[root@OS-NODE1 ~]# rbd map foo --pool nova --keyring /etc/ceph/ceph.keyring
 
[root@OS-NODE1 ~]# rbd showmapped
id pool image snap device
1  nova foo   -    /dev/rbd1
 
[root@OS-NODE1 ~]# mkfs.xfs -d agcount=4 -l size=32m /dev/rbd1
 
[root@OS-NODE1 ~]# mount /dev/rbd1 /mnt/ceph/
防火墙要打开相应规则,不然报:
“error: couldn't connect to the cluster!”
man rados/rbd
RBD挂载远端的rados块设备,需要调优内核网络参数

块设备读写测试

XFS文件系统+2个OSD

XFS文件系统+3个OSD

BTRFS文件系统+3个OSD

高可用性模拟测试

Rados Bench测试

RBD命令行指南

导出ceph nfs

增删MON监视器

参考资料

实验步骤

添加mon.3

假设已经有两台服务器组合成集群,各自运行监视器和OSD集群,如今要添加一台新的机器,充当第三个监视器。

登录集群中的话任意机器,命令导出 authmap,monmap,osdmap →生成 keyring

ceph auth get mon. -o authmap
ceph mon getmap -o monmap
ceph osd getmap -o osdmap
 
#生成mon.3运行环境
ceph-mon -c /etc/ceph/ceph.conf --mkfs --monmap monmap --osdmap osdmap -k authmap -i 3
 
#启动mon.3
#/etc/init.d/ceph start mon.3
#/etc/init.d/ceph -a restart mon
 
#这时候可以看到集群中的其它机器,看到mon.3的加入了
#ceph -s
#如果没有加入,手动添加节点
#ceph mon add 3 192.168.0.99:6789
在ceph.conf中添加节点,保证下回能够正常启动

删除mon.3

#ceph mon remove 3
# vi /etc/ceph/ceph.conf 移除mon.3
#/etc/init.d/ceph -a restart mon
从ceph.conf中去除节点,保证下回能够正常启动

新增OSD实战

参考资料

实验步骤

[osd.2]
        host = OS-FS1
        devs = /dev/sda3
............
 
[root@OS-FS1 ceph]# ceph osd create osd.2
2
 
[root@OS-FS1 ceph]# ceph-osd -i 2 --mkfs --mkkey
2013-01-09 11:21:39 -1 created object store /srv/ceph/osd2 journal /srv/ceph/osd2/journal for osd.2 fsid 
2013-01-09 11:21:39 -1 created new key in keyring /srv/ceph/osd2/keyring
 
[root@OS-FS1 ceph]# ceph auth add osd.2 osd 'allow *' mon 'allow rwx' -i /srv/ceph/osd2/keyring
2013-01-09 16:26:24.614887 7f731523e760 -1 read 56 bytes from /srv/ceph/osd2/keyring
added key for osd.2
 
[root@OS-FS1 ceph]# ceph osd getcrushmap -o map
[root@OS-FS1 ceph]# crushtool -d map -o map.txt   # 编译文件加入新的节点信息
[root@OS-FS1 ceph]# crushtool -c map.txt -o newmap
 
[root@OS-FS1 ceph]# ceph osd setcrushmap -i newmap
2013-01-09 16:36:16.830139 7fa24c4fd760 -1 read 542 bytes from newmap
set crush map
 
[root@OS-FS1 ceph]# ceph -s
   health HEALTH_OK
   monmap e1: 1 mons at {a=192.168.10.2:6789/0}, election epoch 2, quorum 0 a
   osdmap e9: 3 osds: 3 up, 3 in
    pgmap v353: 576 pgs: 576 active+clean; 8730 bytes data, 1646 MB used, 939 GB / 941 GB avail
   mdsmap e4: 1/1/1 up {0=a=up:active}
ceph auth add必须添加,否则权限报错!
ceph osd setmaxosd很重要
# 先在集群中导出monmap,然后拷贝到新节点
ceph mon getmap -o monmap
 
# 在新增的OSD节点上运行先运行 easyCeph.sh genConfig生成ceph.conf配置文件,然后运行以下命令
for i in `sed -r -n "/\[osd.[0-9]*\]/s@\[osd.(.*)\]@\1@gp" /etc/ceph/ceph.conf`;do
   ceph-osd -c /etc/ceph/ceph.conf --monmap monmap -i $i --mkfs --mkkey
done
 
# 拷贝OSD节点上的keyring.*到集群中的/tmp临时目录下,运行auth导入集群的认证
cd /tmp
for i in keyring.osd.*;do
   ii=${i#keyring.osd.}
   ceph auth add osd.$ii osd 'allow *' mon 'allow rwx' -i /tmp/keyring.osd.$ii
done
# 检查keyring是否正确导入
ceph auth list
 
####################################################################
# 在新节点上重新编译easyCeph.sh主机列表,生成新的ceph.conf和crushmap,然后分别导入到所有机器上生效
./easyCeph.sh genConfig;./easyCeph.sh genCrushmap;./easyCeph.sh syncConfig
####################################################################
 
# 在集群的任意节点上放大maxosd
ceph osd setmaxosd 10000
 
# 在新的节点上启动OSD
/etc/init.d/ceph start/restart osd,mon
 
ceph osd crush set 301 osd.301 1.0 pool=default rack=rack-1 host=ceph3
ceph osd setcrushmap -i /etc/ceph/crush.map
 
# OSD有up,down,in,out四种状态
# 从运行中的集群中移除故障OSD的步骤如下:
 
ceph osd crush remove osd.301
ceph auth del osd.301
ceph osd down 301
ceph osd out 301
ceph osd rm 301
 
# 新增OSD并插入生产
ceph osd up 301
ceph osd in 301
新增OSD的时候,最好是以rep size的倍数增加,可以降低degrade的比例,但不知是不是bug?

OSD异常测试

OSD正常下线

ceph osd down osd.301
/etc/init.d/ceph stop osd.301

Ceph立即感知到节点故障,开始做降级处理

stop osd.301

ceph osd out 301

当我们把301这个节点摘除后,Ceph开始做数据平衡

out osd.301

/etc/init.d/ceph start osd.301
ceph osd in 301

重启节点,加入分布图,数据恢复中

in osd.301

OSD异常退出

kill -9 osd.301.pid

restart osd.301

模拟硬盘热插拔

手动把二块硬盘直接拔出,模拟硬盘硬件故障,再逐个还原硬盘 ceph osd out 301 309

直接拔出二块硬盘的监控

先还原309号OSD,操作如下

umount  /srv/ceph/osd309
mount -t xfs -o rw,noexec,nodev,noatime,nodiratime,barrier=0 -L /disk/sata9 /srv/ceph/osd309
/etc/init.d/ceph restart osd.309
ceph osd in 309

恢复309号OSD

先还原301号OSD,操作如下

恢复301号OSD

继续平衡数据,直到降级后的数据全部恢复(约15分钟恢复1OSD)

再来一次插拔,换个干净的硬盘添加进去

ceph osd out 310
dmesg | tail -5 -> /dev/sdb
mkfs.xfs -f -l internal,lazy-count=1,size=128m -i attr=2 -d agcount=8 -i size=512 /dev/sdb
xfs_admin -L /disk/sata10 /dev/sdb
mount -t xfs -o rw,noexec,nodev,noatime,nodiratime,barrier=0 -L /disk/sata10 /srv/ceph/osd310
ceph mon getmap -o monmap
ceph-osd -c /etc/ceph/ceph.conf --monmap monmap -i 310 --mkfs --mkkey
ceph auth add osd.310 osd 'allow *' mon 'allow rwx' -i /etc/ceph/keyring.osd.310
ceph auth list
ceph osd setmaxosd 10000
/etc/init.d/ceph restart osd.310
ceph osd in 310

插入新盘的数据恢复进度有点缓慢

Ceph PG管理

参考资料

When you create a pool, set the number of placement groups to a reasonable value (e.g., 100). Consider the total number of placement groups per OSD too. Placement groups are computationally expensive, so performance will degrade when you have many pools with many placement groups (e.g., 50 pools with 100 placement groups each). The point of diminishing returns depends upon the power of the OSD host.
Important Increasing the number of placement groups in a pool after you create the pool is still an experimental feature in Bobtail (v 0.56). We recommend defining a reasonable number of placement groups and maintaining that number until Ceph’s placement group splitting and merging functionality matures.
单个pool中的PG数量不能超过65536,多个池并存可以,但注意性能

导出PG-OSD对应map

ceph pg dump --format plain > pg_map
awk '/^[0-9]\./{print $1,$14,$15}' pg_map | sort -k1n > pg_map.sort

定位PG异常

分布式存储设计的几个要素

存储路由层

临时缓存层

数据处理层

㊙️ 状态专业名词

backfill_wait

pgs 排队等候开始回填

backfilling

Ceph正在扫描并同步pgs的整个内容,而不是从最近操作的日志中推断出需要同步的内容。回填是一种特殊的恢复状态。

stuck unclean

状态不一致,不干净

objects degraded

Ceph尚未将pgs组中的某些对象复制到完整的三副本状态

objects misplaced

pgs组中的待正确放置位置的数据

inactive

配置组已经长时间处于非激活状态(比如,它一直无法处理读写请求)

unclean

配置组长时间未被清理(比如,它没有完全从上一个错误中恢复)

stale

配置组的状态没有被OSD更新过,意味着所有存储在该配置组的节点都down掉了

常见问题

✅ OSD Journal文件

每个osd分配一个journal,默认日志大小为1000M,可调整,这是个回环可以重复写的文件圈。

分离OSD的data和journal到不同设备,推荐用ssd来记录journal,可以提高整体性能。

✅ connect protocol version mismatch

检查各服务器上的Ceph安装版本是否一致

OSD容量爆盘

OSD的容量警告有两个级别:

  1. health warning: mon osd nearfull ratio = .60
  2. health error : mon osd full ratio = .95

因此当ceph -s 报告容量警告时,一定要及时添加硬件资源,但到达95%会报Error。 ceph osd is full

此Error并非表示出错,只是ceph为了保证已经存在的数据的完整性,不再接受新数据写入的防御措施,但后果依然严重,要提前避免

OSD偶尔莫名会hang

osd hang

现在在平衡数据的过程中,有时候会莫名其妙的发生osd hang的现象,进程依然在运行,但集群不能接受新数据,从日志上分析出现的slow request时间特别长,这时候,就需要restart osd,才能恢复,估计是软件bug.

解决思路

监控日志中的slow request的时间值和数据写入量是否为0,如果出现以上情况,则检查ceph pg dump_stuck unclean中出现频率最高的osd,并且重启

OSD突然crash

ceph crash

尝试方法:

Ceph退回到0.56.6版本,增加了“journal aio = true”

✅ Ceph的网络问题

建议使用两个分开的网络,因为ceph支持两个网络:位于前端的公网、位于后端的集群网,可以防止OSD平衡数据或者遇到攻击时,导致延时增大和性能下降;当OSD间的流量中断时,归置组就再也不能进入active+clean状态了,它也会阻止用户读写数据。

杜绝此类问题发生的最佳方法就是彻底分开集群网和公网,推荐使用至少2个网卡

只有一个公网也可以,但仅限于内部演示。

Ceph中levebdb的应用

  • osd: put large xattrs in leveldb
  • osd: move pg info into leveldb
  • mon: ObjectMap,key→value的map属性,其保存在levelDB

Ceph的radosgw API

radosgw是遵循fastcgi协议的网关服务,可以通过前端的nginx/apache/varnish做负载均衡.

✅ Message too long

Message too long

上传文件大小由“osd max write size”这个参数控制,系统默认是90M,可调整这个参数控制文件尺寸

✅ PG/PGP increase crash

目前ceph版本,无论是不是有写入操作,增加pg/pgp数目,会造成ceph的osd崩溃,因此不建议线上调整

假设单台机器12个磁盘=12个osd,按照200台机器的规模算,12200100/3=80000,最多只能支持60000个pg_num

Each placement group requires some amount of system resources:
 
**Directly**: Each PG requires some amount of memory and CPU.
**Indirectly**: The total number of PGs increases the peering count.
PG不能设置过大,容易造成系统资源不足和性能瓶颈

✅ 总结的一些忠告

  1. 尽可能多的OSD是集群中的负载平衡。 As many OSDs you have as better is the load-balance in the cluster. Let’s assume that you use 1 disk per OSD, it means that you will prefer 2 disk of 500G instead of 1T disk.
  2. SSD的使用大大提高了OSD的性能。 The usage of a SSD dramatically improves your OSD’s performance
  3. 副本数为2会带来比副本数为3更多的性能,但它的安全性较低。 Replica count of 2 brings more performance than a replica count of 3, but it’s less secure
  4. 使用专用的私有网络进行内部OSD复制确实可以提高性能。Using a dedicated private network for the internal OSDs replication really improve the performance
  5. 使用更高带宽的网络硬件来克服1G带宽限制很容易。 It’s really easy with decent hardware to overcome the 1G bandwidth limitation
  6. 将filestore flusher选项设置为false可以从根本上改善您的性能,主要是在旧系统。 Setting the filestore flusher option to false can radically improve your performance, mainly on old system
  7. 即使更多的pg意味着更好的负载平衡,但大量的pg并不会提高性能。 Even if more pg means better load-balance, setting a large number of pg doesn’t enhance your performance

CRUSH Maps & Weight

Weighting Bucket Items

Ceph expresses bucket weights as double integers, which allows for fine weighting. A weight is the relative difference between device capacities. We recommend using 1.00 as the relative weight for a 1TB storage device. In such a scenario, a weight of 0.5 would represent approximately 500GB, and a weight of 3.00 would represent approximately 3TB. Higher level buckets have a weight that is the sum total of the leaf items aggregated by the bucket.

A bucket item weight is one dimensional, but you may also calculate your item weights to reflect the performance of the storage drive. For example, if you have many 1TB drives where some have relatively low data transfer rate and the others have a relatively high data transfer rate, you may weight them differently, even though they have the same capacity (e.g., a weight of 0.80 for the first set of drives with lower total throughput, and 1.20 for the second set of drives with higher total throughput).

修改weight会影响osdmap的变化

Numerical argument out of domain

✅ failed verifying authorize reply

确保每个节点keyring文件中key值相同

/var/lib/ceph/mon/{ceph-node}/keyring

✅ HEALTH_WARN too few PGs per OSD

ceph osd pool set rbd pg_num 128
ceph osd pool set rbd pgp_num 128

✅ HEALTH_WARN clock skew detected的解决办法

[root@Mysql-SSD-Bakcup ~]# ceph health detail
HEALTH_WARN clock skew detected on mon.DBS-SAD-018; Monitor clock skew detected
mon.DBS-SAD-018 addr 192.168.147.18:6789/0 clock skew 40.2243s > max 5s (latency 0.000928916s)

同步国际时间,如果执行完以上两步仍有报错,则需要重启所有monitor(/etc/init.d/ceph restart mon)

✅ HEALTH_ERR 1 pgs inconsistent

[root@MySQL-Backup ~]# ceph health detail
HEALTH_ERR 1 pgs inconsistent; 1 pgs repair; 5 scrub errors
pg 0.4a4 is active+clean+scrubbing+deep+inconsistent+repair, acting [15,4,49]
5 scrub errors
 
[root@MySQL-Backup ~]# ceph osd find 15
{
    "osd": 15,
    "ip": "192.168.146.12:6832\/14224",
    "crush_location": {
        "host": "EBS-SAD-002",
        "root": "default"
    }
}
 
 
问题PG:0.4a4
OSD编号:15,4,49

常规修复

[root@MySQL-Backup ~]# ceph pg repair 0.4a4
instructing pg 0.4a4 on osd.15 to repair

深度清洗

要洗刷一个pg组,执行命令:

ceph pg scrub 0.4a4   
ceph pg deep-scrub  0.4a4
ceph pg repair 0.4a4

修复osd

修复pg所属的三块osd ,执行命令如下:

ceph osd repair 75
ceph osd repair 6
ceph osd repair 35
以上修复步骤按顺序依次进行,只要一个成功,后续无需执行。

✅ 实在没有办法

查询pg 使用主osd信息

ceph pg 2.37c query |grep primary  # <-- 查询出哪个主 osd 号
journalctl -xeu ceph-osd@38 # <-- 查看日志有什么错误,删除那个 input/output error 所在的文件

删除md5sum报IO错误的文件,然后执行

ceph pg repair 14.16a

pg状态恢复正常

✅ pgs not deep-scrubbed in time

CEPH会定期(默认每个星期一次)对所有的PGs进行scrub,即通过检测PG中各个osds中数据是否一致来保证数据的安全。

当CEPH更换一块坏硬盘,进行数据修复后,出现了大量的PGs不能及时进行scrub,甚至有些PGs数据不一致,导致CEPH系统报警,如下所示:

Cluster Status:HEALTH_WARN
126 pgs not deep-scrubbed in time

此时,需要提高对PGs的scrub速度。默认情况下一个OSD近能同时进行一个scrub操作且仅当主机低于0.5时才进行scrub操作。我运维的CEPH系统一个PG对应10个OSDs,每个OSD仅能同时进行一个scrub操作,导致大量scrub操作需要等待,而同时进行的scrub操作数量一般为8个。因此需要在各台存储服务器上对其OSDs进行参数修改,来提高scrub速度。

osdmaxscrubs参数用于设置单个OSD同时进行的最大scrub操作数量;osdscrubload参数设置负载阈值。主要修改以上两个参数来提高scrub速度,其默认值为1和0.5。
ceph health detail|awk '/not deep-scrubbed since/{print "ceph pg deep-scrub "$2}'

✅ HEALTH_ERR pgs stuck stale的解决办法

pgs stuck stale

[root@MySQL-Backup ~]# ceph health detail
 
HEALTH_ERR 1 pgs are stuck inactive for more than 300 seconds; 1 pgs stale; 1 pgs stuck stale; 2 requests are blocked > 32 sec; 1 osds have slow requests
pg 2.70 is stuck stale for 173219.873722, current state stale+active+clean, last acting [52]
2 ops are blocked > 131.072 sec on osd.52
1 osds have slow requests
 
[root@EBS-SAD-005 ~]# ceph pg dump_stuck stale
ok
pg_stat state   up      up_primary      acting  acting_primary
2.70    stale+active+clean      [52]    52      [52]    52
 
[root@MySQL-Backup deploy-key]# ceph pg map 2.70
osdmap e9983 pg 2.70 (2.70) -> up [52] acting [52]
pg 2.70 is stuck stale
[root@EBS-SAD-005 ~]# ceph pg 2.7 query > x.log    #  留待排查
 
[root@EBS-SAD-005 ~]# ceph pg ls|grep ^2.70
2.70    866     0       0       0       0       3613425664      3006    3006    stale+active+clean      2019-01-26 10:04:28.891302      8106'2738703    8127:1254451    [52] 
在某些场景下Ceph集群会出现stale的情况,也就是ceph集群PG的僵死状态,这个状态实际上是无法处理新的请求了,新的请求过来只会block,如只有一个副本的情况下,有个pg失效了,集群这个时候就会出现stale的情况了,因为数据都丢了,在一些环境下,数据本身就是临时的或者不是那么重要的,比如存储日志,这样的环境下,只需要快速的恢复环境即可,而不担心数据的丢失。
[root@MySQL-Backup ~]# ceph pg force_create_pg 2.70
pg 2.70 now creating, ok

✅ rbd: map failed

dmesg | tail

[96615.562272] rbd: image foo: image uses unsupported features: 0x38

for i in deep-flatten fast-diff object-map;do rbd feature disable foo $i;done
一些编码的转译:
exclusive-lock ->  0x4 

✅ Found valid GPT with corrupt MBR ceph

sgdisk -Z /dev/sdb

✅ mount /dev/rbd1 on /sqlbackup failed: Structure needs cleaning

解决办法: xfs_repair -L /dev/sdb1

✅ summary Failed to get system container stats

kubelet中追加配置

--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice

✅ bootstrap-osd keyring not found

在准备一台主机作为OSD或元数据服务器时,你得收集监视器、OSD、和MDS的初始密钥环,可用下列命令:

ceph-deploy gatherkeys EBS-SAD-002

那么就会先找

/etc/ceph/ceph.client.admin.keyring

然后再找

/var/lib/ceph/bootstrap-osd/ceph.keyring
/var/lib/ceph/bootstrap-mds/ceph.keyring

实时返回集群中的密钥

a6ac67145475bbf202b6adb7c23ccb6f  ceph.bootstrap-mds.keyring
b8b37b5c940564f9fa6444d9a2f3d2cc  ceph.bootstrap-mgr.keyring
28da5445fae3288df51aab15ccb27293  ceph.bootstrap-osd.keyring
ce9876c07c4285c4138e0948dde80d86  ceph.bootstrap-rgw.keyring
591b0bb706aa2a688ec47201527d8cdd  ceph.client.admin.keyring
注意:disk zap 命令是不需要权限的,而osd prepare 需要bootstrap-mds.keyring

✅ 用SYSTEMD控制ceph

  • systemctl start ceph.target # start all daemons or
  • systemctl start ceph-osd.target # start osd daemons
  • systemctl start ceph-mon.target # start mon daemons
  • systemctl start ceph-mds.target # start mds daemons
  • systemctl start ceph-osd@{id}
  • systemctl start ceph-mon@{hostname}
  • systemctl start ceph-mds@{hostname}
  • systemctl status ceph-osd@12 # check status of osd.12

✅ Ceph常规配置

ceph osd pool get rbd pg_num
ceph osd pool set rbd pg_num 1440
ceph osd pool set rbd pgp_num 1440
ceph osd pool rename rbd cold-mysql
 
ceph osd pool ls detail #查看资源池的具体信息,包括副本数,pg_num,pgp_num
ceph osd pool set poolname size X #设置资源池副本数
 
rbd create ssd_mysql --size 10000 #创建镜像空间大小,默认单位为G
for i in exclusive-lock deep-flatten fast-diff object-map;do rbd feature disable gitlab-backup $i;done
rbd mv ssd_mysql ssd-mysql
rbd map/unmap/showmapped

✅ Ceph扩容伸缩

blockdev --getsize64 /dev/rbd0    #获取镜像大小
rbd resize --size 20000 ssd-mysql #设置新的镜像大小
resize2fs /dev/rbd0               #动态扩容,如果是xfs则应该使用xfs_growfs

✅ Ceph判断磁盘和日志盘

列举机器上的磁盘

ceph-deploy --ceph-conf /etc/ceph/ceph.conf  disk list  EBS-SAD-001
 
# ceph-disk list
# lsof /dev/sdbxx  # 判断哪个journal 与 osd 相对应

脚本判断挂载点及日志盘

#!/bin/sh
sed -r -i '/ceph/d' /etc/fstab
df -h|awk '/ceph-[0-9]/{print $1,$NF}' > /tmp/.xxx
while read LINE;do
        dev=`echo $LINE|cut -f1 -d' '|cut -d'/' -f3`
        uuid=`blkid |sed -r -n "/$dev/s@.*(UUID=.*)@\1@gp"`
        dir=`echo $LINE|cut -f2 -d' '`
        journal_dev=$(blkid | grep `cat $dir/journal_uuid`|awk -F: '{print $1}')
        echo -e "#$uuid\t$dir\txfs\tdefaults 0 0\t# $dev -> $journal_dev" >> /etc/fstab
done < /tmp/.xxx

找出对应盘符的磁盘

while `sleep 2`;do dd if=/dev/sdg1 of=/dev/null bs=300M count=10;done

检查磁盘是否健康的脚本

for dev in $(lsblk |grep -B1 ceph|awk '/^sd/{print $1}');do
                       smartctl -A /dev/sdi|awk '
                        /^  5/{if($NF>300) print "'$dev'"}
                        /^188|^197|^198/{if($NF>100) print "'$dev'"}
                        /^183/{if($NF>10) print "'$dev'"}
                        '
done
 
# smartctl -H /dev/$dev

✅ Ceph故障处理

# 增加或维护osd之前,先暂停数据平衡
for opt in nobackfill norebalance norecover noout;do ceph osd set $opt;done # set -> unset解除
 
# 摘除一个osd,但事先要获取设备名,盘符及日志盘分区 
systemctl stop ceph-osd@3
ceph osd out osd.3
ceph osd crush rm 3
ceph auth del osd.3
ceph osd rm 3
umount /var/lib/ceph/osd/ceph-3
 
# 尝试修复osd磁盘,但不要强求能够恢复
xfs_repair /dev/sdo1 #修复分区,无法修复就更换磁盘
 
# 初始化新osd
ceph-deploy --ceph-conf /etc/ceph/ceph.conf disk list EBS-SAD-002
ceph-deploy --ceph-conf /etc/ceph/ceph.conf disk zap EBS-SAD-002:sdg
ceph-deploy --ceph-conf /etc/ceph/ceph.conf osd prepare  EBS-SAD-002:sdg1:sdb6
ceph-deploy --ceph-conf /etc/ceph/ceph.conf osd activate EBS-SAD-002:sdg1:sdb6
ceph osd crush reweight osd.16 0.1
一般生产环境会设置为noout,当然不设置也可以,那就交给程序去控制节点的out,默认是在进程停止后的五分钟,总之这个地方如果有 out 触发,不管是人为触发,还是自动触发数据流是一定的。
  • prepare EBS-SAD-002:sdg:sdb6 → sdg 可以省略 /dev前缀,prepare 后面不用带分区号
  • activate EBS-SAD-002:sdg1:sdb6 → activate 后面要带上分区号

✅ Ceph摘盘脚本

#!/bin/sh
stop(){ 
        for opt in nobackfill norebalance norecover noout;do
                ceph osd set $opt
        done
        systemctl stop ceph-osd@$ID
        ceph osd out osd.$ID
        ceph osd crush rm $ID
        ceph auth del osd.$ID
        ceph osd rm $ID
        umount /var/lib/ceph/osd/ceph-$ID
}
 
start(){
        ceph-deploy disk zap EBS-SAD-001:sdf
        ceph-deploy osd prepare EBS-SAD-001:sdf:sdb5
        ceph-deploy osd activate EBS-SAD-001:sdf1:sdb5
        ceph osd crush reweight osd.3 3.63689
        for opt in nobackfill norebalance norecover;do
                ceph osd unset $opt
        done
}
 
ID=$2
[ -z $ID ] && echo "$0 stop osd-id" && exit 0
 
case $1 in
        start)   
                start;;
        stop)   
                stop;;
        *)
                echo "$0 start|stop"
                exit 0;;
esac

✅ Ceph的配置文件

[global]
fsid = 7a261d53-a9d0-493e-aa1f-d22ab9d55dbc
mon_initial_members = EBS-SAD-001, EBS-SAD-002, EBS-SAD-003, EBS-SAD-004
mon_host = 192.168.146.11,192.168.146.12,192.168.146.13,192.168.146.14
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
mon_clock_drift_allowed = 5
osd_journal_size = 20480
public_network=192.168.0.0/16
max_open_files=131072
mon_osd_down_out_interval=86400  # 此参数有待验证

✅ 基于rdb cow快照的增量备份

Ceph 支持对 rbd 快照创建很多 写时复制(Copy-on-write, COW) 克隆. 快照层次化能够使 Ceph 块设备客户端非常快速地建立镜像. 比如你可以创建一个块设备, 让一个 Linux VM 对其读写; 然后对镜像建立快照, 保护这一快照, 这样你就可以创建任意多的 COW 克隆体.

在了解了 Ceph RBD 的快照功能后, 我们就可以来看看如何通过快照来对 RBD image 进行备份. 过程也非常简单.

#!/bin/sh
BASE_DIR=$(dirname $0)
CONF_DIR=${BASE_DIR}/conf
source $CONF_DIR/auth
 
POOL="rbd"
IMAGE="cold-db-76-77"
NUMS="72"
 
rbd snap list $POOL/$IMAGE > $IMAGE.list
NUM=`wc -l $IMAGE.list | awk '{print $1}'`
 
sleep $(($RANDOM%120))
 
if [ $NUM -gt $NUMS ];then
        diff=$((NUM-NUMS))
        for id in $(sed -r -n "2,${diff}p" $IMAGE.list | awk '{print $2}');do
                rbd snap rm $POOL/$IMAGE@$id
        done
fi
 
#mysql -u$DB_USER -p$DB_PASSWD -e "FLUSH TABLES WITH READ LOCK"
xfs_freeze -f /usr/mysqldata
/usr/bin/rbd snap create $POOL/$IMAGE@`date +%Y%m%d-%H%M`
xfs_freeze -u /usr/mysqldata

定时修复脚本 fixed_ceph.sh

#!/bin/sh
FILE="/tmp/bad_ceph.log"
dingding(){
curl 'https://oapi.dingtalk.com/robot/send?access_token=0f0b2e4b29ccedbfa6ef2b609dbbc1dbda3aa074c4f198337acad55119f3cba5' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text",
        "text": {
             "content": "[Ceph-new]:OSD.'"$1 $2"' "
        }
      }'
}
 
touch $FILE
 
if [ -s $FILE ];then
        while read id;do
                echo $id
                ceph health detail | grep -q "$id .*repair"
                if [ $? != 0 ];then
                        ceph health detail | grep -q "$id"
                        if [ $? = 0 ];then
                                dingding $id "bad to repaired"
                                ceph pg repair $id
                        else
                                dingding $id "is OK"
                                sed -r -i -e '/^$/d' -e "/$id/d" $FILE
                        fi
                fi
        done < $FILE
else
        ceph health detail | grep -iq err
        [ $? == 0 ] && (ceph health detail | sed -r -n 's@.* pg (.*) is (.*)@\1@gp' > $FILE)
 
        num=$(ceph health detail | grep -ic inactive)
        if [ $num -ge 2 ];then
                dingding PG_NOT_HEALTH " > $num"
        fi
 
        num=$(ceph health detail | awk '/PG_NOT_DEEP_SCRUBBED/{print $2}')
        if [ $num -ge 3 ];then
                dingding PG_NOT_DEEP_SCRUBBED " > $num"
        fi
fi
  1. rdb rollback快照时,先取消镜像的exclusive-lock(独占锁)特性
  2. 做快照前,先暂停slave同步,加只读锁,结束后再解锁,开启slave同步
  3. 恢复快照时,先stop mysqld进程; umount /usr/mysqldata挂载; unmap /dev/rbd0;
  4. date; rbd snap rollback rbd/cold-db-76-77@20191009-0400; date (时间约3.5小时)
  5. 重新 rbd map, mount, start mysqld
  6. rbd snap purge {pool-name}/{image-name} # 清除某一镜像的所有快照

✅ 在线扩容rbd磁盘

查看映射盘

[root@updbs-74-75 data]# rbd showmapped
id pool image         snap device    
0  rbd  cold-db-74-75 -    /dev/rbd0 
1  rbd  backup-db-105 -    /dev/rbd1 

先扩容rbd容量

rbd resize rbd/backup-db-105 --size 4096G
 
Resizing image: 100% complete...done.

在线扩容文件系统

[root@updbs-74-75 data]# xfs_growfs /sqlbackup/
meta-data=/dev/rbd1              isize=256    agcount=33, agsize=16382976 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=524288000, imaxpct=5
         =                       sunit=1024   swidth=1024 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=256000, version=2
         =                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 524288000 to 1073741824

✅ 如何正确替换osd

可以很清楚的看到三种不同的方法,最终的触发的迁移量是不同的,处理的好的话,能节约差不多一半的迁移的数据量,这个对于生产环境来说还是很好的,关于这个建议先在测试环境上进行测试,然后再操作,上面的操作只要不对磁盘进行格式化,操作都是可逆的,也就是可以比较放心的做,记住所做的操作,每一步都做完都去检查 PG 的状态是否是正常的

✅ ceph-deploy使用指南

验证通过:
Ceph-disk 在部署journal分区的时候,能自动侦测SSD盘已有分区数,不破坏已有分区,分配不冲突的新分区号来创建分区。

✅ 如何动态增加mon/osd服务器

  • 从ceph-deploy主控机,加入要控制的目标机,添加相应的公钥
host EBS-SAD-001 EBS-SAD-002 EBS-SAD-003 EBS-SAD-004 EBS-SAD-005 EBS-SAD-006 ceph-master
    Port 65422
    Identityfile ~/.ssh/id_rsa
  • 同步所有机器的/etc/hosts,加入主机名别名
192.168.144.83  ceph-master
192.168.146.11  EBS-SAD-001
192.168.146.12  EBS-SAD-002
192.168.146.13  EBS-SAD-003
192.168.146.14  EBS-SAD-004
192.168.146.15  EBS-SAD-005
192.168.146.16  EBS-SAD-006
  • 编辑/etc/ceph/ceph.conf,加入要增加mon的机器
[global]
fsid = 7a261d53-a9d0-493e-aa1f-d22ab9d55dbc
mon_initial_members = EBS-SAD-001, EBS-SAD-002, EBS-SAD-003, EBS-SAD-004, EBS-SAD-005
mon_host = 192.168.146.11,192.168.146.12,192.168.146.13,192.168.146.14,192.168.146.15
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
mon_clock_drift_allowed = 5
osd_journal_size = 20480
public_network=192.168.0.0/16
max_open_files=131072
mon_osd_down_out_interval=86400
  • 推送配置到目标机
ceph-deploy --overwrite-conf config push EBS-SAD-001 EBS-SAD-002 EBS-SAD-003 EBS-SAD-004 EBS-SAD-005
  • 在ceph.conf 和 ceph.mon.keyring 目录下运行命令
ceph-deploy --overwrite-conf mon add EBS-SAD-005 

✅ 如何动态增加osd node服务器

prepare 命令只准备 OSD 。

在大多数操作系统中,硬盘分区创建后,不用 activate 命令也会自动执行 activate 阶段(通过 Ceph 的 udev 规则)。详情见激活 OSD。

✅ 如何动态的修改osd journal size

前提是:

  • Ceph cluster should be health “OK” state
  • All placement groups (PGs) should be “active + clean”
  • Set ceph osd noout to stop the rebalancing activity.
  1. Update the ceph.conf file with desired journal size.
  2. set noout – so that no data migration start
  3. /etc/init.d/ceph stop osd.id
  4. ceph-osd -i <osdid> –flush-journal - cd /var/lib/ceph/osd/ceph-osd.1 && rm journal - ceph-osd –mkjournal -i <osd id> - /etc/init.d/ceph start osd.< id> - ceph –admin-daemon /var/run/ceph/ceph-osd.<osd-id>.asok config get osdjournal_size
  5. Finally unset the noout flag. : ceph osd unset noout

✅ Ceph重新挂载下线的osd

先执行ceph osd create,直到create出已经删除的osd的序号.

[root@EBS-SAD-005 /]# ceph osd create
52
 
[root@EBS-SAD-005 /]# ceph auth add osd.52 osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/ceph-52/keyring
 
[root@EBS-SAD-005 /]# ceph osd crush add 52 3.63689 host=EBS-SAD-005
 
[root@EBS-SAD-005 /]# systemctl start ceph-osd@52

✅ Ceph怎么最优化平衡数据

注意:在生产环境中,一般不会再新节点加入ceph集群后,立即开始数据回填,这样会影响集群性能。所以我们需要设置一些标志位,来完成这个目的。

#ceph osd set noin
#ceph osd set nobackfill
#ceph osd set norecover

在用户访问的非高峰时,取消这些标志位,集群开始在平衡任务。

#ceph osd unset noin
#ceph osd unset nobackfill
#ceph osd unset norecover

✅ Ceph中使用sgdisk

ceph中两种类型分区的type code:

type type code
journal 45b0969e-9b03-4f30-b4c6-b4b80ceff106
osd 4fbd7e29-9d25-41b8-afd0-062c0ceff05d

/usr/lib/udev/rules.d/95-ceph-osd.rules 中可以看到:

# OSD_UUID
ACTION=="add", SUBSYSTEM=="block", \
  ENV{DEVTYPE}=="partition", \
  ENV{ID_PART_ENTRY_TYPE}=="4fbd7e29-9d25-41b8-afd0-062c0ceff05d", \
  OWNER:="ceph", GROUP:="ceph", MODE:="660", \
  RUN+="/usr/sbin/ceph-disk --log-stdout -v trigger /dev/$name"
ACTION=="change", SUBSYSTEM=="block", \
  ENV{ID_PART_ENTRY_TYPE}=="4fbd7e29-9d25-41b8-afd0-062c0ceff05d", \
  OWNER="ceph", GROUP="ceph", MODE="660"
 
# JOURNAL_UUID
ACTION=="add", SUBSYSTEM=="block", \
  ENV{DEVTYPE}=="partition", \
  ENV{ID_PART_ENTRY_TYPE}=="45b0969e-9b03-4f30-b4c6-b4b80ceff106", \
  OWNER:="ceph", GROUP:="ceph", MODE:="660", \
  RUN+="/usr/sbin/ceph-disk --log-stdout -v trigger /dev/$name"
ACTION=="change", SUBSYSTEM=="block", \
  ENV{ID_PART_ENTRY_TYPE}=="45b0969e-9b03-4f30-b4c6-b4b80ceff106", \
  OWNER="ceph", GROUP="ceph", MODE="660"

ceph中创建journal分区和data分区:

sgdisk -n {part num}:0:+{part size}G {disk} -t {part num}:4fbd7e29-9d25-41b8-afd0-062c0ceff05d -c {part num}:”ceph data” 
sgdisk -n {part num}:0:+{part size}G {disk} -t {part num}:45b0969e-9b03-4f30-b4c6-b4b80ceff106 -c {part num}:”ceph journal”
分区后要用 partprobe 即时生效

✅ 掉电后osdmap丢失

✅ ceph-osd NOTE: a copy of the executable

  • ceph osd out 59 启动后再加入 ceph osd in 59
  • journalctl -xeu ceph-osd@56 → “ epoch 51322, but missing map. Crashing ” 从别的机器打包拷贝过来
  • 机器死机后,OSD 分区受到损坏,需要用 xfs_repair 修复一下文件系统
  • 新节点与老节点内核版本不一致的情况

✅ cephfs启用新的ec纠删码存储

删除原来的pool,必须要先删除fs,有顺序!

ceph osd pool ls
 
ceph config set mon mon_allow_pool_delete true
ceph fs rm cephfs --yes-i-really-mean-it
ceph osd pool rm cephfs.cephfs.data cephfs.cephfs.data --yes-i-really-really-mean-it
ceph osd pool rm cephfs.cephfs.meta cephfs.cephfs.meta --yes-i-really-really-mean-it
 
ceph osd erasure-code-profile set gcec k=2 m=1 crush-failure-domain=host
ceph osd pool create gcfsdata erasure gcec
ceph osd pool set gcfsdata allow_ec_overwrites true
ceph osd pool create gcfsmeta
 
ceph fs new cephfs gcfsmeta gcfsdata --force

创建新的cephfs后,就需要给节点配置ceph.conf和cephfs.keyring

[global]
        fsid = a5d6a556-cce7-11ef-8106-6a1a3a5aac7e
        mon_host = [v2:10.17.4.201:3300/0,v1:10.17.4.201:6789/0] [v2:10.17.4.202:3300/0,v1:10.17.4.202:6789/0] [v2:10.17.4.203:3300/0,v1:10.17.4.203:6789/0]
 
#  /etc/ceph/ceph.client.cephfs.keyring 
[client.cephfs]
        key = AQCNHH1nRZdROBAA8qdXEC40sUl+jQ512dHBDA==

🆘 SSD journal failure

ceph-osd --flush-journal -i 56
ceph-osd --mkjournal -i 56

急救步骤

  1. 防止OSD down的时候,马上引发recovery,应该设置noout标志位(ceph osd set noout)
  2. 记录osd对应的盘符(df -h 也可以尝试挂载,然后看里面的whoami文件)
  3. 换新盘标志为gpt(parted /dev/sdb mklabel gpt, partprobe /dev/sdb ⇐将分区表变化通知内核)
  4. 读取osd上的journal uuid,并还原分区
  5. 修改journal ssd 权限,chown -R ceph.ceph /dev/ssd
  6. 启动osd,/etc/init.d/ceph restart osd.x
  7. ceph osd unset noout
parted -m -s $dev rm 1
parted -m -s $dev mklabel gpt
parted -m -s $dev mkpart primary xfs 2048s 100%
partx -a $dev

制作脚本

#!/bin/sh
journal_disk=/dev/sdb
 
partition=1
for osd_id in {0..11}; do
  journal_uuid=$(sudo cat /var/lib/ceph/osd/ceph-$osd_id/journal_uuid)
  sgdisk --new=$partition:0:+20480M --change-name=$partition:'ceph journal' --partition-guid=$partition:$journal_uuid --typecode=$partition:$journal_uuid --mbrtogpt -- $journal_disk
  partprobe $journal_disk
  ceph-osd --mkjournal -i $osd_id
  echo systemctl start ceph-osd@$osd_id
  let partition+=1
done
chown ceph.ceph ${journal_disk}*
正确调整mon osd down out interval 参数
ceph daemon /var/run/ceph/ceph-mon.asok config show|grep mon_osd_down_out_interval
ceph daemon /var/run/ceph/ceph-mon.asok config set mon_osd_down_out_interval 86400

🆘 故障盘替换的正确操作

🆘 系统盘坏了如何修复

系统盘坏了,再也无法进入系统,时间紧张,来不及修复旧系统,直接用新ssd重装系统。 安装过程略…….

进入新系统后:

  1. 执行 ssh-keygen 创建临时公密钥,上传覆盖为自己的
  2. 执行 adjust-centos7.sh 优化系统,升级新内核
  3. 导入 /etc/yum.repos.d/ceph.repo ; yum install ceph 安装相关版本的软件
  4. 导入 /etc/hosts , 主机间需要通讯
  5. 拷贝 /etc/ceph/. 相关证书用于ceph命令
  6. 执行 checkcephmount.sh, 找出主机 osd whoami 与 journaluuid 之间的关联 - 执行 createcephjournal.sh, 重新创建 journaluuid 分区(sgdisk ; ceph-osd –mkjournal)
  7. 执行 chown -R ceph.ceph /dev/sdx(rules: KERNEL==“sdb*”, OWNER=“ceph”, GROUP=“ceph”, MODE=“0660”

; udevadm trigger)

  1. 执行 systemctl start ceph-osd@osd_id

🆘 更换机器主板后各种疑难杂症

ceph又报警了,IP不通,连接显示器键盘无反应,重启机器后,开机点不亮,由此判断是硬件问题,赶紧带上家伙赶机房:

  • ssd磁盘(系统盘坏了要带,但此例不是它的问题)
  • sata磁盘(数据盘,但开机不亮说明不是数据盘问题)

赶到机房,先重新插拔内存条,看能不能起死回生,但是无用功,由此判断是主板问题(后发现是其中一条内存有问题),但短期之内不能立即联系到硬件厂商解决问题(先报修了,再自己想办法)

  • 找一台配置相当的机器,至少要能够容纳12 * sata盘 + 2 * ssd盘
  • 进入修复系统(为什么是修复系统,后面会说),发现网络起不来。。。
  • 排查疑难一:网卡命名方式会改变,enps4f0 → ens7f0 类似xxx
  • 排查疑难二:磁盘在不同的阵列卡,盘符居然也发生了变化,导致ceph的udev规则不能生效,后果是进不了系统,只好进修复系统排查,巨坑!!!
  • 排查疑难三:由于是进了修复系统,手动要启动一系列进程(network,sshd),ceph osd也不能自动挂载了,于是现场搓了一段代码,挂载一个查看一个whoami,然后再挂载到正确的点上
chown ceph:ceph /dev/sdxx
  • 排查疑难四:ceph-osd启动失败,通过journalctl查看,是journal盘没有权限写入,这个是ceph的特性,可以把日志和数据分离,我猜是udev的规则没有开机启动加入相应的权限,于是排查udev规则,找到
/usr/bin/systemctl --no-block restart ceph-disk@dev/sd${i}1.service

至此,ceph节点恢复完毕,加入集群,开始平衡数据…

新版本ceph的硬盘更换

新版本的ceph支持祼盘引擎 bluestore,评测性能比xfs文件系统好太多了,所以就用了新的ceph版本和存储引擎,ceph会通过操作lvm来创建osd,好处是容易操作多种不同磁盘介质.

ceph-volume lvm zap /dev/sdg
ceph-volume lvm prepare --bluestore --data /dev/sdg
ceph-volume lvm activate --bluestore 133 2e4cc047-56ab-4fda-bd29-c924ea0ad097

daemons have recently crashed

ceph rdma协议的集群总是报daemons have recently crashed,而且数目越来越多,然并没有找到相关错误的日志

  ceph health detail
  ceph crash archive-all
  ceph config set mgr mgr/crash/warn_recent_interval 0
wiki/public/linux/ceph.txt · 最后更改: 2025/11/17 09:51