所有文档
存储
- ceph故障排查指南
- OSD omap 目录过大导致服务启动失败的问题分析
- Ceph peering 相关参数测试
- Ceph filestore op threadsce 测试报告
- ceph 重启osd io block问题
- ceph性能瓶颈分析
- arm环境ceph慢请求问题分析
- ceph对象存储添加osd导致业务io被长时间block问题
- ceph对象存储bucket数据过期自动删除使用方法
网络
ceph故障排查指南
ceph故障排查指南
1.概论
本文描述了ceph集群运行中的各种常见问题及解决方法。ceph基于rados基础组件提供了块存储,文件存储和对象存储3种不同接口的服务,在生产环境中难免会遇到各种问题。分布式存储系统对资源的消耗主要有CPU,内存,磁盘,网络,文件句柄,进程和线程,端口等,对这些容易出现问题点的资源做好监控并进行历史趋势分析,从而发现性能容量瓶颈,提前发现软硬件故障,才能保持整个集群运行良好。
2.网络故障排查
2.1网络问题
ceph完全依赖网络可靠性,mon和osd之间使用网络相互通信。网络问题可能会导致osd存在很多问题,如osd抖动,或直接变成错误状态down。网络问题也会导致存储节点之间出现时钟不同步问题。此外,丢包,高时延,或带宽受限,这些现象都会影响集群性能和稳定性。
1. 检查并确认public network和cluster network使用的网卡
cat /etc/ceph/ceph.conf | grep net
cluster_network = x.x.x.x/x
public_network = x.x.x.x/x
也可以查看osd使用的网络配置,其中osd.x替换为具体的osd id
ceph daemon osd.x config show | grep network
"cluster_network": "x.x.x.x/x",
"cluster_network_interface": "",
"public_network": "x.x.x.x/x",
"public_network_interface": "",
2. 安装net-tools和telnet
yum install net-tools telnet -y
3. 检查网卡状态是up,如果是down状态排查网线连接
ip link list
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group
default
qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp6s0: mtu 1500 qdisc noop state UP mode DEFAULT group default
qlen 1000
link/ether x:x:x:x:x:x brd x:x:x:x:x:x
4. 检查存储节点之间互ping能通,延时在正常范围,没有丢包
ping node-1
5. 检查防火墙关闭,iptables规则放行端口
iptables -I INPUT -p tcp -m multiport --dport 3300,6789,6800:7300,8003 -m comment --comment
'ceph ports' -j xue
6. 检查网卡计数器上是否存在errors,节点之间网络连接延迟正常,没有丢包
a.使用ethtool命令
ethtool -S ens11f0 | grep errors
NIC statistics:
rx_errors: 0
tx_errors: 0
rx_over_errors: 0
rx_crc_errors: 0
rx_frame_errors: 0
rx_fifo_errors: 0
rx_missed_errors: 0
tx_aborted_errors: 0
tx_carrier_errors: 0
tx_fifo_errors: 0
tx_heartbeat_errors: 0
rx_long_length_errors: 0
rx_short_length_errors: 0
rx_csum_offload_errors: 0
b. 使用ifconfig命令,检查
RX-ERR RX-DRP RX-OVR
TX-ERR TX-DRP TX-OVR
RX errors 0 dropped 0 overruns 0 frame 0
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig ens11f0
ens11f0: flags=4163 mtu 1500
inet x.x.x.x netmask x.x.x.x broadcast x.x.x.x
inet6 x::x:x:x:x divfixlen 64 scopeid 0x20
ether x:x:x:x:x:x txqueuelen 1000 (Ethernet)
RX packets 263699359 bytes 290440048415 (270.4 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 240604319 bytes 254389924875 (236.9 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
c. 使用netstat命令,检查
RX-ERR RX-DRP RX-OVR
TX-ERR TX-DRP TX-OVR
netstat -ai
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
br-ex 1500 0 0 0 0 0 0 0 0 BM
br-int 1450 0 0 77899 0 0 0 0 0 BM
br-tun 1500 0 0 0 0 0 0 0 0 BM
enp4s0f0 1500 114624836 0 0 0 97394709 0 0 0 BMRU
enp4s0f1 1500 0 0 0 0 0 0 0 0 BM
ens11f0 1500 263852013 0 0 0 240770314 0 0 0 BMRU
ens11f1 1500 7507120 0 0 0 4355666 0 0 0 BMRU
7. 对于性能问题,除了检查网卡延迟,还要使用iperf3工具验证存储集群所有节点之间的网络带宽。
a. 安装iperf工具
yum install iperf3 -y
b. 在存储节点上启动iperf3服务端
iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
默认端口5201,可以用-p参数指定为其他端口
d. 在不同存储节点上启动iperf3客户端
iperf3 -c x.x.x.x
Connecting to host x.x.x.x, port 5201
[ 4] local x.x.x.x port 53350 connected to x.x.x.x port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 1.10 GBytes 9.42 Gbits/sec 0 662 KBytes
[ 4] 1.00-2.00 sec 1.09 GBytes 9.41 Gbits/sec 0 675 KBytes
[ 4] 2.00-3.00 sec 1.07 GBytes 9.21 Gbits/sec 0 714 KBytes
[ 4] 3.00-4.00 sec 1.08 GBytes 9.29 Gbits/sec 0 742 KBytes
[ 4] 4.00-5.00 sec 1.09 GBytes 9.41 Gbits/sec 0 748 KBytes
[ 4] 5.00-6.00 sec 1.09 GBytes 9.41 Gbits/sec 0 751 KBytes
[ 4] 6.00-7.00 sec 1.10 GBytes 9.42 Gbits/sec 0 754 KBytes
[ 4] 7.00-8.00 sec 1.10 GBytes 9.41 Gbits/sec 0 759 KBytes
[ 4] 8.00-9.00 sec 1.09 GBytes 9.41 Gbits/sec 0 790 KBytes
[ 4] 9.00-10.00 sec 1.09 GBytes 9.40 Gbits/sec 0 824 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 10.9 GBytes 9.38 Gbits/sec 0 sender
[ 4] 0.00-10.00 sec 10.9 GBytes 9.37 Gbits/sec receiver
iperf Done.
上述测试结果表示节点之间网络带宽在10.9Gbits/s,Retr为0表示测试过程中没有重传,建议所有节点之间网络带宽都执行测试
8. 确保所有节点具有相同的网络带宽,连接较慢的节点会减慢连接速度较快的节点。另外确保交换机可以处理聚合带宽,命令:
ethtool
ethtool ens11f0
Settings for ens11f0:
Supported ports: [ FIBRE ]
Supported link modes: 1000baseT/Full
10000baseT/Full
Supported pause frame use: Symmetric
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseT/Full
10000baseT/Full
Advertised pause frame use: Symmetric
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 10000Mb/s
Duplex: Full
Port: FIBRE
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
Speed: 10000Mb/s 万兆网卡
Duplex: Full 全双工
Link detected: yes 物理链路正常
2.2 ntp问题
确保所有节点使用同一ntp源,并保持与server节点时间同步
systemctl status chronyd
如果没有运行,启动服务
systemctl enable chronyd
systemctl start chronyd
确保正确同步时钟
chronyc sources
210 Number of sources = 2
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* node-3.node.kolla-consul> 11 6 377 64 +11us[ +19us] +/- 642ms
^* 表示已和server时间同步,如果是其它值^x表示没有同步
立即手动同步时间
chronyc -a makestep
有些旧版本环境没有安装chrony,安装了ntp服务,排查方法类似
确保所有节点使用同一ntp源,并保持与server节点时间同步
systemctl status ntpd
如果没有运行,启动服务
systemctl enable ntpd
systemctl start ntpd
检查ntp同步状态
ntpstat
synchronised to NTP server (x.x.x.x) at stratum 3
time correct to within 303 ms
polling server every 64 s
确保正确同步时钟
ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
*x.x.x.x x.x.x.x 2 u - 64 7 26.416 38.377 5.322
+time.cloudflare x.x.x.x 3 u 136 64 4 271.879 -13.373 13.047
tock.ntp.infoma x.x.x.x 2 u 12 64 3 172.720 24.246 2.853
ntp7.flashdance x.x.x.x 2 u 11 64 7 275.671 56.658 16.497
*表示目前使用的ntp server
st | 即stratum阶层,值越小表示ntp serve的精准度越高 |
when | 几秒前曾做过时间同步更新的操作; |
Poll | 每隔多少毫秒与ntp server同步一次 |
reach | 已经向上层NTP服务器要求更新的次数; |
delay | 网络传输过程钟延迟的时间; |
offset | 时间补偿的结果; |
jitter | Linux系统时间与BIOS硬件时间的差异时间 |
手动强制同步时间
ntpdate < server>
各节点时间差最好控制在0.05s以内,如果超过该值需要修改ceph配置项
ceph默认配置允许时间误差mon_clock_drift_allowed=0.05
3. 磁盘故障排查
1. 如果没有raid卡,可借助smartctrl工具进行检查,返回PASSED表示硬盘物理状态正常
smartctl -H /dev/sda
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.10.0-957.10.1.el7.x86_64] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
硬盘的 SMART 子系统已经具备一套完整的算法来评估硬盘的健康状况
SMART 子系统算法会参考硬盘运行时各个方面的参数,media error 是其中一项
SMART 对于 media error 的评估是基于单位时间增长数来计算的
当 SMART 子系统中任何一个评估项达到对应的阈值时,硬盘会报告 Sense Code: 01 5D 00 (FAILURE divDICTION THRESHOLD
EXCEEDED)
遵循 SCSI 协议标准的 host (OS SCSI 子系统,SAS 控制器, RAID 卡等) 可以正确解析出该 Sense Code
磁盘出现坏块,可以使用磁盘坏块检查工具如badblocks检查磁盘是否有坏块,如下:
badblocks /dev/sda -s -v
Checking blocks 0 to 62522711
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found. (0/0/0 errors)
2. 此外可以借助raid卡工具排查磁盘是否出现坏道/坏块
安装megacli
wget https://docs.broadcom.com/docs-and-downloads/sep/oracle/files/Linux_MegaCLI-8-07-07.zip
unzip Linux_MegaCLI-8-07-07.zip
rpm -ivh MegaCli-8.07.07-1.noarch.rpm
查询磁盘读写错误数量
/opt/MegaRAID/MegaCli/MegaCli64 -pdlist -aALL | grep -iE "failure|error"
Media Error Count: 0
Other Error Count: 0
divdictive Failure Count: 0
Last divdictive Failure Event Seq Number: 0
a. Media Error
磁盘存在错误,可能是磁盘有坏道。值越大,越危险。根据磁盘状况,一般大于100报修更换。
b. Other Error
磁盘存在未知的错误,可能是磁盘松动,需要重新再插入。根据磁盘状况,一般大于100报修更换。
c. divdictive Failure Count
磁盘的预警数。一般大于0,就报修更换。
d. Last divdictive Failure Event Seq Number
最后一条预警的时间序列号。这个值不为0,肯定divdictive Failure Count也不为0。
3. 由于storcli工具已替代megacli,建议使用storcli工具检测磁盘
登录到broadcom网站下载工具
/opt/MegaRAID/storcli/storcli64 /c0/eall/sall show all | grep -iE "failure|error"
Media Error Count = 0
Other Error Count = 0
divdictive Failure Count = 0
Last divdictive Failure Event Sequence Number = 0
https://www.broadcom.com/products/storage/raid-controllers/megaraid-sas-9361-8i#downloads
4. 其它raid卡工具参考厂商提供的文档操作
4.mon故障排查
4.1. 常见mon错误及排查方法
ceph完全依赖网络可靠性,mon和osd之间使用网络相互通信。网络问题可能会导致osd存在很多问题,如osd抖动,或直接变成错误状态down。网络问题也会导致存储节点之间出现时钟不同步问题。此外,丢包,高时延,或带宽受限,这些现象都会影响集群性能和稳定性。
错误信息 | 排查方法 |
---|---|
HEALTH_WARN | |
mon.X is down (out of quorum) | 4.3 mon超出仲裁数 |
clock skew | 4.4 时钟偏移 |
store is getting too big! | 4.5 mon占用存储空间过大 |
4.2. 常见mon错误日志
错误信息 | 日志文件 | 排查方法 |
---|---|---|
clock skew | /var/log/ceph.log | 4.4 时钟偏移 |
clocks not synchronized | /var/log/ceph.log | 4.4 时钟偏移 |
Conrruption: error in middle of record | /var/log/ceph/ceph-mon.X.log | 4.3 超出仲裁数 4.6 恢复mon store |
Conrruption: 1 missing files | /var/log/ceph/ceph-mon.X.log | 4.3 mon超出仲裁数 4.6 恢复mon store |
Caught signal (Bug error) | /var/log/ceph/ceph-mon.X.log | 4.3 mon超出仲裁数 4.5 mon占用存储空间过大 |
4.3. mon超出仲裁数
1个或多个mon被标记未down,但是其它mon仍然能仲裁成功,ceph health detail 命令返回如下类似错误信息
HEALTH_WARN 1 mons down, quorum 1,2 mon.b,mon.c
mon.a (rank 0) addr x.x.x.x:6789/0 is down (out of quorum)
mon down的原因很多:
1. mon守护进程未运行
如果mon进程拉不起来,可能是mon
store文件损坏或出现其它错误(强制断电可能出现数据损坏)。另外/var/分区被写满也有可能导致mon无法启动,检查mon store文件是否正常
/var/lib/ceph/mon/ceph-X/store.db/
2. mon守护进程已运行,但mon没有仲裁成功
如果mon仲裁失败,无法和其它mon通信,可能是网络问题导致;也可能是monmap和其它节点不同步,也有可能是mon
ip地址配置错误。如果monmap是最新的,也有可能是时间不同步导致;
如果mon长时间处于electing状态,可能是时间不同步;
如果mon状态从synchronizing到electing状态变化,表示生成mon map的速度比同步数据的速度要快;
如果mon将自己标记为leader或peon,但集群中其它mon认为它不是,出现脑裂问题,可能是时间不同步;
解决方法:尝试拉起mon进程
systemctl status ceph-mon@$(hostname)
systemctl restart ceph-mon@$(hostname)
mon进程无法启动,根据对应日志执行修复/var/log/ceph/ceph-mon.X.log
常见3种错误:
1. 节点强制断电或其它原因导致ceph mon数据损坏,日志报错,修复方法参考4.6 恢复mon store
Corruption: error in middle of record
Corruption: 1 missing files; e.g.: /var/lib/ceph/mon/mon.0/store.db/1234567.ldb
2. /var/分区满了,日志报错,修复方法删除其它数据或扩大/var/分区大小,
不要手动删除mon store数据中的文件,或者压缩mon store,修复方法参考
4.5 mon占用存储空间过大
Caught signal (Bug error)
3. mon守护进程运行正常,但依然处于down状态,登录到不在仲裁内的mon主机检查状态
ceph daemon mon.$(hostname) mon_status
如果mon ip地址不正确,修复方法参考 4.7 修改monmap
如果mon ip地址正确,状态是electing/synchronizing/peon等,检查时间是否与其它mon节点同步,修复方法参考4.4
时钟偏移
4.4. 时钟偏移
ceph health detail 命令输出如下类似错误
mon.a (rank 0) addr x.x.x.x:6789/0 is down (out of quorum)
mon.a addr x.x.x.x:6789/0 clock skew 0.08235s > max 0.05s (latency 0.0045s)
另外ceph.log含有如下类似错误信息
2015-06-04 07:28:32.035795 7f806062e700 0 log [WRN] : mon.a x.x.x.x:6789/0 clock skew 0.14s
> max 0.05s
2015-06-04 04:31:25.773235 7f4997663700 0 log [WRN] : message from mon.1 was stamped
0.186257s in the future, clocks not synchronized
上述错误信息表示mon节点间时钟不同步
解决方法:
1. 修改mon_clock_drift_allowed=0.05,如果集群规模较大可适当调大该值,例如调大到1s,不建议调的过大,会影响集群稳定性
2. 同步节点时间,如果无法同步排查ntp同步问题
时间同步完成后,重启mon进程,ceph每隔5分钟检查一次时钟,因此告警信息clock skew会有一段延迟才会消失
4.5. mon占用存储空间过大
ceph health detail 命令返回如下类似错误信息
mon.ceph1 store is getting too big! 48031 MB >= 15360 MB -- 62% avail
mon store
实质上就是一个rocksdb数据库(J版是leveldb数据库),所有数据都是key/value形式存放,文件保存位置/var/lib/ceph/mon/ceph-X/store.db/
当mon store数据库内容变大时,访问数据延迟也会增加,生产环境建议系统盘使用SSD存放mon store,如果/var/分区被写满会导致mon store无法写入数据库
修复方法:
1. 检查mon store占用空间大小
du -sch /var/lib/ceph/mon/*/store.db/
64M /var/lib/ceph/mon/ceph-openstack-con01/store.db/
64M total
2. 压缩mon store数据,参考 4.8 压缩mon store数据
4.6. 恢复mon store
如果存在部分mon store数据正常,直接从其它节点拷贝到数据异常的节点即可。示例从node2正常节点修复node1异常数据
scp -r node2:/var/lib/ceph/mon/ceph-node2/store.db/ /var/lib/ceph/mon/ceph-node1/store.db/
systemctl restart ceph-mon@$(hostname)
当所有mon store数据都损坏时,可通过所有osd数据进行合成,注意该方法有可能丢失数据,谨慎使用
1. 在所有osd节点执行以下命令
查询节点部署了osd的磁盘列表,记录各osd id信息
ceph-volume lvm list
N版以前的版本使用ceph-disk命令查询
ceph-disk list
挂载数据到临时目录
for i in {OSD_ID}; do mount -t tmpfs /var/lib/ceph/osd/ceph-$i; done
还原SELinux上下文
sfor i in {OSD_ID}; do restorecon /var/lib/ceph/osd/ceph-$i; done
修改文件权限为ceph:ceph
for i in {OSD_ID}; do chown -R ceph:ceph /var/lib/ceph/osd/ceph-$i; done
从所有osd节点收集集群map数据
cd /root/
ms=/tmp/monstore/
db=/root/db/
db_slow=/root/db.slow/
mkdir $ms
for host in $osd_nodes; do
echo "$host"
rsync -avz $ms $host:$ms
rsync -avz $db $host:$db
rsync -avz $db_slow $host:$db_slow
rm -rf $ms
rm -rf $db
rm -rf $db_slow
ssh -t $host < < EOF for osd in /var/lib/ceph/osd/ceph-*; do
ceph-objectstore-tool --type bluestore --data-path \$osd --op update-mon-db
--mon-store-path $ms done EOF rsync -avz $host:$ms $ms rsync -avz
$host:$db $db rsync -avz $host:$db_slow $db_slow done
生成admin keyring并设置权限
ceph-authtool /etc/ceph/ceph.client.admin.keyring -n mon. --cap mon 'allow *' --gen-key
cat /etc/ceph/ceph.client.admin.keyring
[mon.]
key = XXXXXXXXXXXXXXXXXXXXXXXXXXX
caps mon = "allow *"
[client.admin]
key = XXXXXXXXXXXXXXXXXXXXXXXXXXX
auid = 0
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
从db和db.slow目录移动所有sst文件到临时目录
mv /root/db/*.sst /root/db.slow/*.sst /tmp/monstore/store.db
通过从os收集到的数据重建mon store
ceph-monstore-tool /tmp/monstore rebuild -- --keyring /etc/ceph/ceph.client.admin
命令执行完成后所有client密钥都会丢失,需要手动导入恢复
拷贝mon store到其它mon节点,HOSTNAME替换为mon节点的hostname
scp -r /tmp/monstore/store.db HOSTNAME:/var/lib/ceph/mon/ceph-HOSTNAME/
修改mon store目录权限为ceph:ceph
chown ceph:ceph /var/lib/ceph/mon/ceph-HOSTNAME/
启动mon进程
systemctl restart ceph-mon@$(hostname)
4.7. 修改monmap
常见操作修改mon ip地址
1. 备份集群最新版本monmap
ceph mon getmap -o /tmp/monmap
2. 查看monmap数据
monmaptool --print /tmp/monmap
monmaptool: monmap file /tmp/monmap
epoch 1
fsid x-x-x-x-x
last_changed 2021-09-18 01:55:50.742034
created 2021-09-18 01:55:50.742034
0: x.x.x.x:6789/0 mon.node1
1: x.x.x.x:6789/0 mon.node2
2: x.x.x.x:6789/0 mon.node3
3. 删除mon,可以同时删除多个
monmaptool --rm node1 --rm node2 --rm node3 /tmp/monmap
monmaptool: monmap file /tmp/monmap
monmaptool: removing node1
monmaptool: removing node2
monmaptool: removing node3
monmaptool: writing epoch 1 to /tmp/monmap (0 monitors)
4. 添加mon,使用修改后的ip地址
monmaptool --add node1 x.x.x.x:6789 --add node2 x.x.x.x:6789 --add node3 x.x.x.x:6789
/tmp/monmap
monmaptool: monmap file /tmp/monmap
monmaptool: writing epoch 1 to /tmp/monmap (3 monitors)
5. 停止所有mon进程
systemctl stop ceph-mon@node1
systemctl stop ceph-mon@node2
systemctl stop ceph-mon@node3
6. 在每个mon节点注入新的monmap,比如要先停止mon进程才能正常注入monmap
ceph-mon -i node1 --inject-monmap /tmp/monmap
ceph-mon -i node2 --inject-monmap /tmp/monmap
ceph-mon -i node3 --inject-monmap /tmp/monmap
7. 修改/etc/ceph/ceph.conf配置文件中mon ip地址
mon host = x.x.x.x,x.x.x.x,x.x.x.x
[mon.node1]
host = node1
mon addr = x.x.x.x
[mon.node2]
host = node2
mon addr = x.x.x.x
[mon.node3]
host = node3
mon addr = x.x.x.x
8. 重启所有mon进程
systemctl restart ceph-mon@$(hostname)
4.8. 压缩mon store数据
当mon
store占用空间过大时,可以进行压缩,执行数据压缩前确保集群状态正常,所有pg状态为activate+clean,如果mon进程正常可以使用在线压缩方式,也可以关闭mon进程后离线压缩
1. 在线压缩mon store
ceph tell mon.$(hostname) compact
compacted rocksdb in 0.148352 seconds
2. 离线压缩mon store
a. 修改/etc/ceph/ceph.conf添加如下配置项
scp -r /tmp/monstore/store.db HOSTNAME:/var/lib/ceph/mon/ceph-HOSTNAME/
命令执行完成后所有client密钥都会丢失,需要手动导入恢复
拷贝mon store到其它mon节点,HOSTNAME替换为mon节点的hostname
[mon]
mon_compact_on_start = true
b. 重启mon进程(如果mon
store文件过大,重启时压缩数据可能耗时时间会很长,注意观察进程一定要等压缩完成后再操作其它mon节点)
systemctl restart ceph-mon@$(hostname)
c. 确保mon正常仲裁
ceph mon stat
e1: 3 mons at {node1=x.x.x.x:6789/0,node2=x.x.x.x:6789/0,node3=x.x.x.x:6789/0}, election
epoch 690, leader 0 node1, quorum 0,1,2 node1,node2,node3
d. 使用ceph-monstore-tool压缩,J版之前该工具包含在ceph-test rpm包,因此要先安装,J后面的版本无需安装
yum install ceph-test -y
e. 压缩mon store数据,注意压缩前需要先停止mon进程
systemctl stop ceph-mon@$(hostname)
ceph-monstore-tool /var/lib/ceph/mon/ceph-$(hostname) compact
chown -R ceph:ceph /var/lib/ceph/mon/ceph-$(hostname)/store.db/
systemctl start ceph-mon@$(hostname)
关于store数据压缩可以参考如下文档:
4.9. mon状态
通过 ceph mon_status命令 可以看到mon很多状态,例如State,Rank,Elections epoch,Monmap等
ceph mon_status -f json-divtty
如果mon没有仲裁成功,但进程能够运行,可以通过admin socket执行mon_status命令来判断其状态
ceph daemon mon.$(hostname) mon_status
常见的几种状态
mon状态 | 含义 |
Leader | 通过paxos算法选举,最终有且仅有一个胜利者称为leader,leader节点的rank值最低,rank值越低成为leader的优先级越高 |
Peon | Peon是非leader,如果leader挂了,则具有最低rank值的节点会变成新leader |
Probing | 如果mon处于probing状态,表示它正在寻找其他mon,它们互相探测直到有足够的mon节点达到仲裁条件。 |
Electing | 当所有mon都满足仲裁条件后开始选举leader,这个状态通常变化速度很快 |
Synchronizing | 如果mon正在与其它mon同步数据后加入仲裁,则mon处于synchronizing状态,mon store数据量越小,同步速度越快,当然也跟mon store存放的磁盘性能有关 |
5. osd故障排查
如果集群出现故障,先排查mon问题,确保mon都正常之后再看osd问题
5.1. 常见osd错误告警及排查方法
ceph完全依赖网络可靠性,mon和osd之间使用网络相互通信。网络问题可能会导致osd存在很多问题,如osd抖动,或直接变成错误状态down。网络问题也会导致存储节点之间出现时钟不同步问题。此外,丢包,高时延,或带宽受限,这些现象都会影响集群性能和稳定性。
错误信息 | 排查方法 |
---|---|
HEALTH_ERR | |
full osds | 5.3 Full OSDs |
HEALTH_WARN | |
nearfull osds | 5.4 Nearfull OSDs |
osds are down | 5.5 Down OSDs 5.6 Flapping OSDs |
requests are blocked | 5.7 Slow requests or requests are blocked |
slow requests | 5.7 Slow requests or requests are blocked |
5.2. 常见osd错误日志
错误信息 | 日志文件 | 排查方法 |
---|---|---|
heartbeat_check: no reply from osd.X | /var/log/ceph/ceph.log | 5.6 Flappingl OSDs |
wrongly marked me down | /var/log/ceph/ceph.log | 5.6 Flappingl OSDs |
osds have slow requests | /var/log/ceph/ceph.log | 5.7 Slow requests or requests are blocked |
FAILED assert(0 == "hit suicide timeout") | /var/log/ceph/ceph-osd.X.log | 5.5 Down OSDs |
5.3. Full OSDs
ceph health detail命令返回如下类似错误
ceph health detail
HEALTH_ERR 1 full osds osd.X is full at 95%
为了防止数据丢失,ceph禁止客户端在出现单个full
osd集群上执行写操作。当osd空间使用率达到配置文件mon_osd_full_ratio设置的值时,会返回HEALTH_ERR full
osds错误信息。该参数默认设置为0.95,即集群容量的95%。
解决方法:
执行ceph df命令确认存储空间%RAW USED已达到95%
ceph df
临时方案:删除部分不重要的数据
如果只是部分osd处于nearfull状态,可以通过reweight方式进行调整后降低处于nearfull状态osd权重,等待pg迁移平衡完成后删除数据
ceph osd crush reweight osd.X xxx
如果集群osd都处于nearfull状态,这时只能临时调整参数后才能删数据
ceph osd set-nearfull-ratio 0.90
ceph osd set-full-ratio 0.98
ceph osd set-backfillfull-ratio 0.95
长期方案:扩容osd节点
最好的方式监控集群容量,在容量超过70%后及时进行扩容
5.4. Nearfull OSDs
ceph health detail返回如下错误信息:
ceph health detail
HEALTH_WARN 1 nearfull osds osd.X is near full at 85%
当osd空间使用率达到配置文件mon_osd_nearfull_ratio设置的值时,会返回HEALTH_WARN nearfull
osds错误信息。该参数默认设置为0.85,即集群容量的85%。
检查osd pg分布情况,以及磁盘空间使用率
如果pg num太少,可适当增加,建议单个osd pg个数200左右,不要设置的过大
如果是由于pg分布不均导致问题,可以调整pg分布,参考5.8 通过balancer模块均衡pg分布
ceph osd df
ID CLASS WEIGHT REWEIGHT SIZE RAW USE DATA OMAP META AVAIL %USE VAR PGS STATUS
0 hdd 5.45799 1.00000 5.5 TiB 59 GiB 58 GiB 409 KiB 1024 MiB 5.4 TiB 1.05 0.95 79 up
1 hdd 5.45799 1.00000 5.5 TiB 62 GiB 61 GiB 412 KiB 1024 MiB 5.4 TiB 1.11 1.01 87 up
2 hdd 5.45799 1.00000 5.5 TiB 64 GiB 63 GiB 444 KiB 1024 MiB 5.4 TiB 1.15 1.04 90 up
TOTAL 16 TiB 185 GiB 182 GiB 1.2 MiB 3.0 GiB 16 TiB 1.10
MIN/MAX VAR: 0.95/1.04 STDDEV: 0.04
5.5. Down OSDs
ceph health detail返回如下错误信息:
ceph health detail
HEALTH_WARN 1/3 in osds are down
ceph-osd进程down可能是进程挂了或者osd和其它osd网络通信出现问题,导致活着的osd向mon报告错误。
如果ceph-osd进程没有运行,可能原因:
* 磁盘故障
* 文件系统由于丢失文件,bluestore丢失部分数据也可能导致osd进程起不来
* omap过大,load_pgs超时导致osd自杀
* 线程数过多,超出操作系统允许创建的最大pid数
* 其它错误,例如keyring文件丢失或密钥错误
如果ceph-osd进程正常运行,但是mon标记为down,可能原因:
* public 或 cluster network网络不通
* 时间不同步
解决方法:
主要分2种情况
1. osd进程可以拉起
a. 找到down osd所在节点
ceph health detail
HEALTH_WARN 1 osds down; 1 host (1 osds) down; Degraded data redundancy: 3418/10292 objects
degraded (33.210%), 59 pgs degraded
OSD_DOWN 1 osds down
osd.0 (root=default,host=node-1) is down
OSD_HOST_DOWN 1 host (1 osds) down
host node-1 (root=default) (1 osds) is down
b. 登录到对应节点尝试重启osd
systemctl restart ceph-osd@${id}
c. 如果进程能正常启动,osd依然为down,需要根据日志排查具体原因
检查对应osd日志详情/var/log/ceph/ceph-osd.X.log,如果出现如下类似错误日志,参考5.6. Flapping
OSDs
...
2021-06-22 22:49:40.678580 7f3f03bef800 0 osd.358 167453 load_pgs
2021-06-22 22:58:24.717052 7f3f03bef800 0 osd.358 167453 load_pgs opened 814 pgs
...
2021-06-22 22:58:54.011093 7f3df68d1700 1 heartbeat_map is_healthy 'OSD::osd_op_tp thread
0x7f3e4fd13700' had timed out after 15
...
2021-06-22 22:59:37.638095 7f3efe4d2700 1 heartbeat_map is_healthy 'FileStore::op_tp thread
0x7f3ef30c7700' had timed out after 60
...
2021-06-22 23:01:12.640608 7f3efe4d2700 1 heartbeat_map is_healthy 'OSD::osd_op_tp thread
0x7f3e4fd13700' had suicide timed out after 150
2021-06-22 23:01:12.647665 7f3efe4d2700 -1 common/HeartbeatMap.cc: In function 'bool
ceph::HeartbeatMap::_check(const ceph::heartbeat_handle_d*, const char*, time_t)' thread
7f3efe4d2700 time 2021-06-22 23:01:12.640626
common/HeartbeatMap.cc: 86: FAILED assert(0 == "hit suicide timeout")
...
2. osd进程无法拉起
常见原因:
a. 如果单个节点osd个数过多,一般情况12个osd,需要检查pid个数是否足够,如果不够调大即可
sysctl -w kernel.pid.max=4194303
b. 检查osd磁盘数据和元数据/日志分区是否正常挂载。
ceph-volume lvm list
c. 如果日志提示缺少keyring
ERROR: missing keyring, cannot use cephx for authentication
拷贝对应的keyring文件到osd目录,每个osd都会有一个单独keyring
cat /var/lib/ceph/osd/ceph-0/keyring
[osd.0]
key = XXXXXXXXXXXXXXXXXXXXXX
d. 如果日志提示无法读取osd superblock,需要确定是否磁盘坏了还是分区文件损坏
ERROR: unable to open OSD superblock on /var/lib/ceph/osd/ceph-1
filestore如果日志看到如下类似错误信息,表示磁盘可能故障,考虑更换磁盘解决
FAILED assert(!m_filestore_fail_eio || r != -5)
bluestore如果日志看到如下类似错误信息,表示磁盘可能故障,考虑更换磁盘解决
020-09-02 15:51:10.925582 7f495c44bd80 -1 bluestore(/var/lib/ceph/osd/ceph-2/block)
_read_bdev_label failed to read from /var/lib/ceph/osd/ceph-2/block: (5) Input/output error
e. 检查dmesg一般也能看到磁盘读写错误
dmesg -T
Buffer I/O error on dev dm-0, logical block 468834288, async page read
f. filestore 如果出现journal日志错误,可以尝试跳过日志
2021-10-29 13:50:07.196997 7ff76e664800 -1 journal Unable to read past sequence 1152396918
but header indicates the journal has committed up through 1152397338, journal is corrupt
解决方法:修改/etc/ceph/ceph.conf后重启osd进程,等集群pgs恢复active+clean后再把配置文件还原并重启osd
vim /etc/ceph/ceph.conf
[osd]
journal_ignore_corruption = true
systemctrl restart ceph-osd@X
5.6. Flapping OSDs
osd状态短时间内在down和up状态之间来回跳动,这种osd称为flapping osd,从日志能看到类似错误信息
2017-04-05 06:27:20.810535 mon.0 [INF] osdmap e609: 9 osds: 8 up, 9 in
2017-04-05 06:27:24.120611 mon.0 [INF] osdmap e611: 9 osds: 7 up, 9 in
2017-04-05 06:27:25.975622 mon.0 [INF] HEALTH_WARN; 118 pgs stale; 2/9 in osds are down
2017-04-05 06:27:27.489790 mon.0 [INF] osdmap e614: 9 osds: 6 up, 9 in
2017-04-05 06:27:36.540000 mon.0 [INF] osdmap e616: 9 osds: 7 up, 9 in
2017-04-05 06:27:39.681913 mon.0 [INF] osdmap e618: 9 osds: 8 up, 9 in
2017-04-05 06:27:43.269401 mon.0 [INF] osdmap e620: 9 osds: 9 up, 9 in
2017-04-05 06:27:54.884426 mon.0 [INF] osdmap e622: 9 osds: 8 up, 9 in
2017-04-05 06:27:57.398706 mon.0 [INF] osdmap e624: 9 osds: 7 up, 9 in
2017-04-05 06:27:59.669841 mon.0 [INF] osdmap e625: 9 osds: 6 up, 9 in
2017-04-05 06:28:07.043677 mon.0 [INF] osdmap e628: 9 osds: 7 up, 9 in
2017-04-05 06:28:10.512331 mon.0 [INF] osdmap e630: 9 osds: 8 up, 9 in
2017-04-05 06:28:12.670923 mon.0 [INF] osdmap e631: 9 osds: 9 up, 9 in
此外,osd日志中还能看到类似如下错误
2016-07-25 03:44:06.510583 osd.50 x.x.x.x:6801/149046 18992 : cluster [WRN] map e600547
wrongly marked me down
2016-07-25 19:00:08.906864 7fa2a0033700 -1 osd.254 609110 heartbeat_check: no reply from
osd.2 since back 2016-07-25 19:00:07.444113 front 2016-07-25 18:59:48.311935 (cutoff
2016-07-25 18:59:48.906862)
产生这种问题的原因可能有:
* 单个object上元数据过大或单个pg对象过多(pg
num太少),当对数据量较多的object执行scrub或deep-scrub时会耗费大量时间,可能会导致osd心跳上报超时
* 网络丢包,或网络不稳定,网卡MTU配置错误等,可能导致心跳报文发送异常
* 时间不同步,可能会导致osd心跳报文异常
如果出现这种flapping osd,生产环境一般很容易出现slow request,影响业务性能
心跳相关的一些参数如下
[mon] | ||
---|---|---|
mon osd min down reporters | 向monitor报告down的最小OSD数。 | 默认值:2 修改建议:13(每个节点osd为12个) |
mon osd down out interval | mon标记一个osd为down+out的最大时间间隔 | 默认值: 600s |
mon osd report timeout | mon接收osd上报数据最大超时时间 | 默认值: 900s |
[osd] | ||
osd heartbeat grace time | osd报告其它osd为down的最大时间间隔,不能调的太多,如果某个osd异常退出,这个osd上承载的pg io会hang住 | 默认值: 20s |
osd heartbeat interval | osd发送心跳给其它osd的间隔时间(同一pg之间的osd) | 默认值: 6 |
关于cluster network网络不通可能遇到集群io hang住的问题,通过日志能够很明显判断出osd处于flapping状态
5.7. Slow requests or requests are blocked
生产环境遇到最多的问题应该就是集群出现slow requests告警,业务io出现明显卡顿:
ceph health detail
HEALTH_WARN 30 requests are blocked > 32 sec; 3 osds have slow requests 30 ops are blocked >
268435 sec
1 ops are blocked > 268435 sec on osd.11
1 ops are blocked > 268435 sec on osd.18
28 ops are blocked > 268435 sec on osd.39
3 osds have slow requests
/var/log/ceph/ceph-osd.X.log
2015-08-24 13:18:10.024659 osd.1 127.0.0.1:6812/3032 9 : cluster [WRN] 6 slow requests, 6
included below; oldest blocked for > 61.758455 secs
2016-07-25 03:44:06.510583 osd.50 [WRN] slow request 30.005692 seconds old, received at
{date- time}: osd_op(client.4240.0:8 benchmark_data_ceph-1_39426_object7 [write 0~4194304]
0.69848840) v4 currently waiting for subops from [610]
出现上述告警信息是由于集群存在io响应时间超过30s,默认配置
osd_op_complaint_time=30s,出现slow request的原因主要有:
* 磁盘故障,慢盘(硬盘长时间使用后出现某些扇区读写缓慢),或磁盘iops达到上限
* 网络故障,osd频繁up或down,osd之间连接重连
* 系统压力过大,cpu负载过高
* 程序bug,ceph问题,os问题,driver问题等
ceph提供了一些跟踪指标来判断io处理慢的原因
# 查询指定osd的op处理情况
ceph daemon osd.X dump_historic_ops
# 查询指定osd的op处理时间超过30s情况
ceph daemon osd.X dump_historic_slow_ops
# 查询osd性能情况
ceph daemon osd.X dump_ops_in_flight
# 查询osd落盘和收发数据包延时
ceph osd perf | sort -nk3
常见的一些事件
网络层 | |
---|---|
header_read | messenger线程开始从网络读取消息 |
throttled | messenger线程将网络上收到的消息读取到内存 |
all_read | messenger线程完成消息读取 |
dispatched | osd将消息转发给其它osd |
initiated | messenger线程重新开始从网络读取消息,和header_read形成一个闭环 |
osd处理(线程和消息队列) | |
queued_for_pg | osd接收到消息将操作放入队列给PG对象处理 |
reached_pg | PG开始处理op |
waiting for \* | op正在等待其它一些操作完成才能继续(例如一个新的OSDMap,上面的对象需要执行scrub,等待PG完成peering) |
started | osd开始执行op消息对应的事件 |
waiting for subops from | 等待副本osd处理op返回 |
filestore相关事件 | |
commit_queued_for_journal_write | op已发送给filestore进入待处理队列 |
write_thread_in_journal_buffer | op在日志缓冲区中等待持久化(作为下一次磁盘写入) |
journaled_completion_queued | op已被写入到journal盘,等待回调 |
磁盘相关事件 | |
op_commit | 主osd已提交op |
op_applied | 主osd已写入op到磁盘 |
sub_op_applied | 副本osd已提交op |
sub_op_committed | 副本osd提交子op(仅适用EC pool) |
sub_op_commit_rec/sub_op_apply_rec from |
主osd已收到副本osd处理op/落盘的事件并记录 |
commit_sent | 主osd给客户端回复数据已落盘 |
上面的很多事件看似多余,但都是代码中的重要变更点,例如通过pg锁将op数据提交给其它线程。
常见slow request 类型
慢请求类型 | 描述 |
---|---|
waiting for rw locks | OSD正在等待PG读写锁 |
waiting for subops | OSD正在等待副本OSD落盘 |
no flag points reached | OSD没有达到条件 |
waiting for degraded object | OSD副本数没有达到条件 |
排查方法:
1.
检查出现慢请求的osd对应磁盘压力,await平均值如果长时间不在硬盘厂家描述的范围内,说明磁盘压力过大,其它值如%util只对HDD有参考价值,长时间处于100%状态说明磁盘io过于繁忙,针对NVNE
SSD
%util指标没有参考价值。普通SATA盘iops在120左右,需要注意的是如果做了raid-0,缓存没写满iops可以达到1k-2k,在判断磁盘io是否跑满时先检查raid是jbob模式还是raid-0。
iostat -dmx 5 | grep -v dm
Linux 3.10.0-957.10.1.el7.x86_64 (node-1) 10/19/2021 _x86_64_ (32 CPU)
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 1.36 0.00 0.09 0.00 128.33 0.00 0.28 0.28 0.00 0.28 0.04
sdb 0.12 94.98 0.40 116.84 0.02 1.59 28.20 0.12 1.02 2.61 1.01 0.07 0.78
sdc 0.05 0.01 2.49 9.79 0.19 0.34 87.70 0.13 10.81 11.32 10.67 4.26 5.22
sdd 0.00 0.00 0.01 0.00 0.00 0.00 199.42 0.01 716.93 725.08 5.01 134.11 0.13
iostat参数含义如下:
rrqm/s | 每秒合并放入请求队列的读操作数。 |
wrqm/s | 每秒合并放入请求队列的写操作数。 |
r/s | 每秒磁盘实际完成的读I/O设备次数。 |
w/s | 每秒磁盘实际完成的写I/O设备次数。 |
rMB/s | 每秒从磁盘读取MB数。 |
avgrq-sz | 平均I/O队列长度(操作请求数)。 |
await | 平均每次设备I/O操作的等待时间(毫秒)。 |
w_await | 平均每次设备写I/O操作的等待时间(毫秒)。 |
svctm | 平均每次设备I/O操作的响应时间(毫秒)。 |
%util | 用于I/O操作时间的百分比,即使用率。 |
重要参数详解
a.
rrqm/s和wrqm/s,每秒合并后的读或写的次数(合并请求后,可以增加对磁盘的批处理,对HDD还可以减少寻址时间)。如果值在统计周期内为非零,也可以看出数据的读或写操作的是连续的,反之则是随机的。
b.
如果%util接近100%(即使用率为百分百),说明产生的I/O请求太多,I/O系统已经满负荷,相应的await也会增加,CPU的wait时间百分比也会增加(通过TOP命令查看),这时很明显就是磁盘成了瓶颈,拖累整个系统。这时可以考虑更换更高性的能磁盘,或优化软件以减少对磁盘的依赖。
c. await(读写请求的平均等待时长)需要结合svctm
参考。svctm的和磁盘性能直接有关,它是磁盘内部处理的时长。await的大小一般取决于svctm以及I/O队列的长度和。svctm一般会小于await,如果svctm比较接近await,说明I/O几乎没有等待时间(处理时间也会被算作等待的一部分时间);如果wait大于svctm,差的过高的话一定是磁盘本身IO的问题;这时可以考虑更换更快的磁盘,或优化应用。
d. 队列长度(avgqu-sz)也可作为衡量系统I/O负荷的指标,但是要多统计一段时间后查看,因为有时候只是一个峰值过高。
磁盘性能数据(裸盘),下面是不同介质的性能对比数据,对于随机小 I/O,SSD 比 HDD 存在几十到上百倍的 性能优势,但是顺序 I/O 来说,优势其实并不明显。
介质类型 | 4k 随机写 IOPS | 4k 随机读 IOPS | 1M 写带宽 | 1M 读带宽 | 平均时延 |
---|---|---|---|---|---|
SAS | 180 | 200 | 150MB | 150MB | 3~5ms |
NL-SAS | 100 | 100 | 100MB | 100MB | 7~8ms |
SATA | 100 | 100 | 80MB | 80MB | 8~10ms |
SSD 盘 | 70K | 40K | 500MB | 500MB | < 1ms |
SSD 卡 | 600K | 800K | 2GB | 3GB | < 1ms |
2. 检查网络,具体参考2.
网络故障排查,如果网络有问题,例如心跳异常,可能导致osd出现震荡,一般可通过日志分析,可参考文档“某项目arm环境ceph慢请求问题分析”。
3. 检查pg分布是否均衡,常见单个osd上pg num太少,建议按照社区提供的公式单个osd 200个pg计算,pg
num不能设置过大,pg太多可能出现scrub/deep-scrub时间过长,加盘时peering持续时间过长等问题影响业务io,如果pg分布不均,可参考
5.8. 通过balancer模块均衡pg分布
下面的脚本可以查看指定pool在所有osd上pg分布情况
vim pool_pgs_osd.sh
#set -x
#
# Show information about the PGs in a ceph cluster.
# Especially show the PGs per OSD and the number of primary PGs per OSD.
# This script does not fix primary PG balancing issues but it displays valuable information
# The important number that shows imbalance issues is the Max/Ave ratio for primary PGs per OSD
#
# Usage: $0 [pool_name] [ceph_bin_dir]
# ======
#
# Written by Mark Kogan and Josh Salomon, Red Hat, 2019
#
if [[ $($CEPH pg dump 2>/dev/null | egrep -c "incomplete") -gt 0 ]]; then
echo "inclomplete pgs found, please fix and restart"
exit 1
fi
CEPH_DIR=${2:-"./bin"}
if [ -f "$CEPH_DIR/ceph" ]; then
CEPH="$CEPH_DIR/ceph"
else
CEPH=ceph
fi
echo "CEPH: $CEPH"
POOL=${1:-default.rgw.buckets.data}
POOL_NUM=$($CEPH osd pool stats ${POOL} 2>/dev/null | head -1 | awk "{print \$4}")
date
echo "# POOL=${POOL} , POOL_NUM=${POOL_NUM}"
echo "# ceph -s"
$CEPH -s 2>/dev/null
$CEPH osd df 2>/dev/null
echo
TMPF=$(mktemp /tmp/pgdump.XXXXXX)
$CEPH pg dump pgs_brief 2>/dev/null > $TMPF
if [[ "$POOL_NUM" -eq "" ]]; then
echo "ERROR: Did not find a pool named $POOL, exiting now."
echo
echo "Usage: $0 [pool_name] [ceph_bin_dir]"
echo
rm $TMPF
exit 2
fi
echo -e "\n# PRIMARY PGs number per OSD sorted descending:"
for OSD in $($CEPH osd ls 2>/dev/null); do printf "osd.$OSD\tPGs number: " ;
printf "% 3d\n" "$(cat $TMPF | grep "^$POOL_NUM\." | awk '{print $4}' | grep -w $OSD | wc -l)" ; done | sort -n -r -k 4,4
#rm $TMPF
echo
SIZE=$($CEPH osd dump 2>/dev/null | grep "pool $POOL_NUM" | awk '{ print $6 }')
SORTC=$(( SIZE + 4 ))
NDEVS=`$CEPH osd ls 2>/dev/null | wc -l`
echo -e "\n# PRIMARY and Replicated/EC PGs number per OSD sorted by total descending:"
#$CEPH pg dump brief_pgs 2>/dev/null | grep "^$POOL_NUM\." | awk "{ \ ===
cat $TMPF | grep "^$POOL_NUM\." | awk "{ \
seps[1]=\",\"; split(substr(\$3, 2, length(\$3)-2), res, seps[1]); \
for (s = 1 ; s <= $SIZE ; s++) { dist[s][res[s]]++; }
} END { \
min=65535; max=0; sump=0; \
for (i = 0 ; i < $NDEVS ; i++) {
printf(\"osd.%d\tPGs: \", i); \
tot = 0; \
for (s = 1 ; s <= $SIZE ; s++) { printf(\"% 5d \", dist[s][i]); tot+=dist[s][i]; }
printf(\" ,total=% 5d\n\", tot)
if (min > dist[1][i]) {min = dist[1][i]} \
if (max < dist[1][i]) {max = dist[1][i]} \
sump+=dist[1][i]; \
}; \
ratio=\"NaN\"; \
if (min > 0){ratio=max/min}; \
printf( \" Primary: Min=%d Max=%d Ratio=%s Average=%s Max/Ave=%s\n\", min,max,ratio,sump/$NDEVS,max/(sump/$NDEVS) )
}" | sort -n -r -k 3,3 | sort -n -r -s -k $SORTC,$SORTC
rm $TMPF
查看volumes pool pg分布
sh pool_pgs_osd.sh volumes
4. 检查克隆链层级是否过深,根据生产环境经验值,同一父卷克隆出来的子卷数量超过150很容易出现该问题,表现为单个osd磁盘压力很大,其它osd基本没压力,具体排查方法待补充
5. 其它检查,CPU和内存,交换机等,需要根据具体日志分析
5.8. 通过balancer模块均衡pg分布
pg分布是否均匀直接影响集群读写性能,以及磁盘空间利用率,因此有必要在业务上线之前对pg分布进行优化调整。balancer模块可以帮助实现上述功能,开启banlancer功能后pg可能会发生移动,导致recovery或backfill,建议业务低峰期进行调整尽量不影响业务io
检查balancer模块是否开启
ceph mgr module ls
{
"always_on_modules": [
"balancer",
"crash",
"devicehealth",
"orchestrator_cli",
"progress",
"rbd_support",
"status",
"volumes"
],
"enabled_modules": [
"iostat",
"pg_autoscaler",
"restful"
],
......
}
N版balancer模块默认开启状态,如果上面的enabled_modules里面没有balancer
插件,则需要使用命令开启balancer
ceph mgr module enable balancer
查看balancer状态
ceph balancer status
{
"last_optimize_duration": "0:00:00.001038",
"plans": [],
"mode": "upmap",
"active": true,
"optimize_result": "Unable to find further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect",
"last_optimize_started": "Sat Oct 16 19:50:14 2021"
}
设置balancer模式为upmap
ceph balancer mode upmap
1. 手动调整pg分布
ceph balancer off
a. 评估集群pg分布,得分越低说明越均匀
ceph balancer eval
current cluster score 0.016797 (lower is better)
b. 也可以对单个pool评分
ceph balancer eval volumes
pool "volumes" score 0.027060 (lower is better)
c. 创建任务
ceph balancer optimize < plan-name> {pool-name}
d. 执行任务
ceph balancer execute < plan-name>
e. 对任务评分,如果得到的评分比之前的低,说明这次调整是有效的,可以执行该计划,否则不需要执行该计划任务
ceph balancer eval < plan-name>
2. 自动调整pg分布
ceph balancer on
a. 查看调整结果,开启后需要等待一段时间pg会发生移动,检查balancer状态,如果出现提示内容表示平衡完成: "optimize_result": "Unable to find
further optimization, or pool(s) pg_num is decreasing, or distribution is already perfect"
ceph balancer status
b. 关闭balancer
ceph balancer off
c. 粒度参数可以调高或调低,默认值0.05
ceph config set mgr target_max_misplaced_ratio .03
d. 调整时间间隔,单位是秒
ceph config set mgr mgr/balancer/sleep_interval 60
e. 设置平衡开始时间,格式为HHMM
ceph config set mgr mgr/balancer/begin_time 0000
f. 设置平衡结束时间,格式为HHMM
ceph config set mgr mgr/balancer/end_time 2400
g. 设置平衡开启周期,和crontab格式一样,0或7是周日,1是周一,其它依次类推
ceph config set mgr mgr/balancer/begin_weekday 0
h. 设置平衡结束周期,和crontab格式一样,0或7是周日,1是周一,其它依次类推
ceph config set mgr mgr/balancer/end_weekday 7
i. 可单独设置对部分pool执行平衡,pool id通过命令获取ceph osd pool ls detail
ceph config set mgr mgr/balancer/pool_ids 1,2,3
5.9. osd相关故障处理文档
6. mgr故障排查
ceph-mgr
依赖ceph-mon进程,它是为了分担mon的压力,将监控和管理集群的操作放在mgr进程实现。从12.x(Luminous)版本开始,ceph-mgr成为必要进程,对集群的运维操作很多都依赖mgr进程。如果mgr全部挂了,集群状态信息会不更新(L版本rbd卷读写io会卡住,N版mgr如果全部挂了,不会影响rbd卷读写);
由于mgr本身不存储任何数据,它只是mon的搬运工,因此如果mgr进程挂了,只需要拉起即可。
systemctl restart ceph-mgr@$(hostname)
7. rgw故障排查
对象存储用的不多,一般都是性能问题,相对mon和osd,rgw进程也是个客户端,可以理解为rgw把rados对象存储转变为符合s3标准接口的对象存储。
8. pg故障排查
8.1. PG状态机
在排查PG故障之前,先简单了解下PG状态机。社区提供了一个脚本用于生成PG状态变化流程图,执行如下命令自动生成
yum install graphviz -y
git clone https://github.com/ceph/ceph.git
cd ceph
cat src/osd/PeeringState.h src/osd/PeeringState.cc | doc/scripts/gen_state_diagram.py > doc/dev/peering_graph.generated.dot
sed -i 's/7,7/1080,1080/' doc/dev/peering_graph.generated.dot
dot -Tsvg doc/dev/peering_graph.generated.dot > doc/dev/peering_graph.generated.svg
根据源码生成的状态机流程图如下所示
状态机分为3种:状态,事件和转换
正方形、椭圆形和菱形是状态,正方形是具有内部状态的状态,椭圆是没有内部状态的状态,菱形中的状态是初始状态。
具有内部状态的状态必须定义初始状态。例如,状态 Start 是状态 Started 的初始状态。
同样,Activating 是状态 Active 的初始状态。通过定义触发事件和转换,一个状态可以转换到另一个状态。在状态图中,箭头是转换,它们的标签是触发转换的事件。
浅灰色是初始状态,相同颜色的线条标记了状态之间转换的关联关系,图中有一个例外 Peering 状态是 Primary 状态的初始状态
8.2. 常见pg错误告警及排查方法
错误信息 | 排查方法 |
---|---|
HEALTH_ERR | |
pgs down | 8.3. Down PGs |
pgs inconsistent | 8.5. Inconsistent PGs |
scrub errors | 8.5. Inconsistent PGs |
HEALTH_WARN | |
pgs stale | 8.4. Stale PGs |
unfound | 8.8. Unfound PGs |
pgs stuck unclean | 8.6. Unclean PGs |
pgs stuck inactive | 8.7. Inactive PGs |
8.3. Down PGs
ceph health detail 命令返回如下类似错误
HEALTH_ERR 7 pgs degraded; 12 pgs down; 12 pgs peering; 1 pgs recovering; 6 pgs stuck
unclean; 114/3300 degraded (3.455%); 1/3 in osds are down
...
pg 0.5 is down+peering
pg 1.4 is down+peering
...
osd.1 is down since epoch 69, last address x.x.x.x:6801/8651
出现down pgs一般是osd挂了导致,peering过程中如果将主osd进程关闭,会出现pg卡在down+peering状态。
解决方法:
确定pg所在主osd,或者说peering被哪个osd阻止了
尝试拉起主osd,如果拉不起来,参考osd故障排查Down osds
8.4. Stale PGs
ceph health detail 命令返回如下类似错误
HEALTH_WARN 24 pgs stale; 3/300 in osds are down
当主OSD没有上报PG状态更新,或其它OSD上报主OSD为down,monitor会标记PG状态为stale。
OSD启动时load_pgs初始状态为stale,当peering完成后转换成active。
但是当peering时间过长,主OSD没有报告PG状态给monitor,这些PG会长时间处于stale更新状态
配置项 | 参数含义 |
---|---|
osd_mon_report_interval | mon_osd_report_timeout |
主OSD向monitor上报PG状态的周期,默认5s | monitor接收OSD上报PG状态的超时时间,默认900s |
解决办法:
找到stale状态PG在哪些OSD上
# ceph health detail
HEALTH_WARN 24 pgs stale; 3/300 in osds are down
...
pg 2.5 is stuck stale+active+remapped, last acting [2,0]
...
osd.10 is down since epoch 23, last address x.x.x.x:6800/11080 osd.11 is down since epoch
13, last address x.x.x.x:6803/11539 osd.12 is down since epoch 24, last address
x.x.x.x:6806/11861
8.5. Inconsistent PGs
当磁盘出现静默错误时,可能会遇到PG状态被标记为active + clean + inconsistent,ceph health detail返回如下类似错误
HEALTH_ERR 1 pgs inconsistent; 2 scrub errors pg 0.6 is active+clean+inconsistent, acting
[0,1,2] 2 scrub errors
当执行scrub或deep-scrub时,多个副本对象数据在磁盘上出现不一致,PG状态会变成inconsistent,常见问题
* object大小不正确
* object元数据不一致(hash值不一致)
* object对象不一致
解决方法:
1. 通过命令ceph health detail找到处于inconsistent状态的pg id
HEALTH_ERR 1 pgs inconsistent; 2 scrub errors pg 0.6 is active+clean+inconsistent, acting
[0,1,2] 2 scrub errors
2. 对不一致PG执行deep-scrub
ceph pg deep-scrub < pgid>
3. 尝试repair修复
ceph pg repair < pgid>
如果repair无法修复,参考下面的文档解决,思路是确保多个副本上object的数据和元数据保持一致。
8.6. Unclean PGs
ceph health detail 返回如下类似错误
HEALTH_WARN 197 pgs stuck unclean
如果PG未在规定的时间内达到active+clean状态,monitor会将其标记为unclean,mon_pg_stuck_threshold=60超时时间默认为60s。
如果PG状态是unclean,通常情况下可能是OSD down了
解决方法:
通过命令ceph osd tree down找到处于down状态的osd
ceph osd tree down
8.7. Inactive PGs
ceph health detail 返回如下类似错误
HEALTH_WARN 197 pgs stuck inactive
如果PG未在规定的时间内达到active+clean状态,monitor会将其标记为inactive,mon_pg_stuck_threshold=60超时时间默认为60s。
如果PG状态是inactive,通常情况下可能是OSD down了
解决方法:
通过命令ceph osd tree down找到处于down状态的osd
ceph osd tree down
8.8. Unfound PGs
ceph health detail 返回如下类似错误,包含unfound
HEALTH_WARN 1 pgs degraded; 78/3778 unfound (2.065%)
当OSD知道它上面的objects对象,但还没有拷贝完成导致找不到该对象,会被标记为unfound。
处于unfound状态的对象无法完成recovery或backfill。
场景举例:
PG在osd.1和osd.2上有数据
1. osd.1 down
2. osd.2 写入一些数据
3. osd.1 up
4. osd.1 和 osd.2 之间开始执行peering流程,osd.1 中缺少的objects正在recovery或backfill队列中还没有恢复完成
5. 在objects拷贝过程中,osd.2 down
osd.1 上存在objects元数据,但对应的数据还没有拷完成,在这种情况下,需要osd.2拉起unfound对象才能正常恢复完成
解决方法:
1. 找到包含unfound对象的PG
might_have_unfound 部分包含尝试查找 unfound 对象的OSD:
* already probed 状态表示无法找到该OSD中的 unfound 对象。
* osd is down 状态表示无法和该OSD通信。
尝试拉起osd,如果拉不起来,参考osd故障排查Down osds
如果确认数据丢失,可以删除该对象后恢复PG状态,具体删除方法待补充.
9. object故障排查
注意:
一般使用ceph-objectstore-tool执行对象级别的操作,该工具能够帮助排查OSD或PG中对象级别问题。
如果操作失误可能会导致数据丢失,除非明确知道要操作的对象以及可能带来的影响,否则不建议直接操作对象。
执行ceph-objectstore-tool命令之前,需要停止osd
systemctl stop ceph-osd@X
9.1. 查询对象列表
查询osd所有objects
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --op list
查询osd指定pg所有objects
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e --op list
9.2. 修复丢失对象
修复osd所有丢失对象
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --op fix-lost --dry-run
修复osd指定pg上丢失对象
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e --op fix-lost
--dry-run
9.3. 修改对象
获取对象数据
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/
--pgid 2.1e
'{
"oid":"rbd_data.86cdfaa5aa97.0000000000000219",
"key":"",
"snapid":-2,
"hash":1973874686,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
get-bytes > rbd_data.86cdfaa5aa97.0000000000000219
修改下载的对象文件,修改内容
重新设置对象内容为更新后的数据
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_data.86cdfaa5aa97.0000000000000219",
"key":"",
"snapid":-2,
"hash":1973874686,
"max":0,"
pool":2,
"namespace":"",
"max":0
}'
set-bytes < rbd_data.86cdfaa5aa97.0000000000000219
9.4. 删除对象
删除pg上所有对象
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e --op remove
删除pg指定对象
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
oid":"rbd_data.86cdfaa5aa97.0000000000000219",
"key":"",
"snapid":-2,
"hash":1973874686,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
remove
9.5. 查询对象OMAP
查询指定对象OMAP数据
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_data.86cdfaa5aa97.0000000000000219",
"key":"",
"snapid":-2,
"hash":1973874686,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
list-omap
9.6. 修改对象OMAP
获取对象omap
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
get-omap size > size.txt
修改后进行设置
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
set-omap size < size.txt
9.7. 查询对象OMAPHDR
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_data.86cdfaa5aa97.0000000000000661",
"key":"",
"snapid":103,
"hash":941573374,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
get-omaphdr
9.8. 查询对象属性
查询对象所有属性列表
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
list-attrs
9.9. 修改对象属性
获取对象属性
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
get-attr "snapset" > snapset.txt
修改后重新设置对象属性
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
set-attr "snapset" < snapset.txt
9.10. 删除对象属性
获取对象属性
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --pgid 2.1e
'{
"oid":"rbd_header.875407e26ca70",
"key":"",
"snapid":-2,
"hash":1522692158,
"max":0,
"pool":2,
"namespace":"",
"max":0
}'
rm-attr "snapset"
9.11. BlueFS挂载
和filestore类似,BlueFS是一个类似xfs格式的文件系统,通过fuse挂载,挂载之前需要先停止osd进程
# 停止osd进程
systemctl stop ceph-osd@0
# 创建临时挂载目录
mkdir /mnt/foo
# 使用fuse挂载BlueFS,挂载成功后会等待
ceph-objectstore-tool --op fuse --data-path /var/lib/ceph/osd/ceph-0 --mountpoint /mnt/foo
mounting fuse at /mnt/foo ...
查看osd挂载空间使用情况
df -Th
foo fuse.foo 5.5T 47G 5.5T 1% /mnt/foo
查看osd上对象数据列表
ls /mnt/foo
10.2_head 1.3_head 1.d_head 2.12_head 2.1_head 2.6_head 3.1_head 3.6_head 4.7_head 8.1_head
9.14_head 9.1b_head 9.1_head 9.25_head 9.2c_head 9.31_head 9.38_head 9.3f_head 9.d_head
10.3_head 1.5_head 1.e_head 2.15_head 2.2_head 2.9_head 3.2_head 3.7_head 5.0_head 9.0_head
9.16_head 9.1c_head 9.20_head 9.27_head 9.2d_head 9.32_head 9.3a_head 9.3_head 9.f_head
11.0_head 1.8_head 1.f_head 2.19_head 2.3_head 2.a_head 3.3_head 4.0_head 5.1_head 9.10_head
9.17_head 9.1d_head 9.21_head 9.28_head 9.2e_head 9.33_head 9.3c_head 9.4_head meta
1.1_head 1.b_head 2.10_head 2.1e_head 2.4_head 2.c_head 3.4_head 4.4_head 6.0_head 9.11_head
9.19_head 9.1e_head 9.23_head 9.2a_head 9.2f_head 9.35_head 9.3d_head 9.a_head type
1.2_head 1.c_head 2.11_head 2.1f_head 2.5_head 2.e_head 3.5_head 4.6_head 8.0_head 9.12_head
9.1a_head 9.1f_head 9.24_head 9.2b_head 9.2_head 9.36_head 9.3e_head 9.c_head
可以看到目录结构和filestore文件系统类似了,查看某个object对象数据,有一些区别是object的attr放在单独的一个目录下,omap数据存放方式一样都是放在rocksdb
ls -alh /mnt/foo/2.1e_head/all/#2:7a9965c8:::rbd_data.7140c800af59.0000000000000204:5a#
total 512K
drwx------ 0 root root 0 Jan 1 1970 attr
-rwx------ 0 root root 9 Jan 1 1970 bitwise_hash
-rwx------ 1 root root 4.0M Jan 1 1970 data
drwx------ 0 root root 0 Jan 1 1970 omap
-rwx------ 0 root root 0 Jan 1 1970 omap_header
10. 常用命令汇总
查询集群状态
ceph -s
查询所有密钥
ceph auth ls
查询osd列表
ceph osd tree [down|up]
查询osd磁盘使用空间
ceph osd df [tree]
查询pool列表,pool参数
cceph osd pool ls [detail]
设置osd状态
ceph osd set
full|pause|noup|nodown|noout|noin|nobackfill|norebalance|norecover|noscrub|nodeep-scrub|notieragent|nosnaptrim|pglog_hardlimit
{--yes-i-really-mean-it}
设置pool参数,副本数,pg_num等
ceph osd pool set size|min_size|pg_num|pgp_num < val>
设置osd权重
ceph osd crush reweight < name>
< float[0.0-]>
设置osd为out状态
ceph osd out < ids>
查询卷状态,被哪些客户端使用
rbd status < image-spec>
查询黑名单列表
ceph osd blacklist ls
添加客户端到黑名单,一般在客户端crash后卷无法删除时使用
ceph osd blacklist add|rm < EntityAddr>
清空黑名单
ceph osd blacklist clear
删除osd
osd purge < osdname (id|osd.id)> {--force} {--yes-i-really-mean-it}
查询osd性能指标
ceph osd perf
查询crushmap
ceph osd crush dump
查询pool使用空间详情(包括pool的quota)
ceph df [detail]
查询stuck状态的PG
ceph pg dump_stuck [unclean|inactive|stale|undersized|degraded]
动态修改运行时参数,支持任意节点操作
ceph tell osd.* injectargs --debug-osd 20/20
动态修改运行时参数,只能在指定节点操作
ceph daemon osd.X config set debug_osd 20/20
获取pg列表
ceph pg dump
查询pg详情
ceph pg < pgid> query
查询pg所在osd
ceph pg map < pgid>
10.1. bcache基本操作
创建bcache设备,默认的block大小是512B、bucket大小是128kB。
block的大小应该与后端设备的sector大小匹配(通常是512或者4k)。
bucket的大小应该与缓存设备的erase block大小匹配(以减少写入放大)
make-bcache --wipe-bcache --block
--bucket 2M -B /dev/sdb -C /dev/nvme0n1p0
查看缓存设备uuid
bcache-super-show /dev/nvme0n1p0 | grep cset.uuid
将缓存设备注册到后端
echo cset.uuid > /sys/block/bcache0/bcache/attach
停止后端bcache设备
echo 1 > /sys/block/sd${i}/bcache/stop;
安全移除缓存设备
echo < cache-set-uuid> > /sys/block/bcache0/bcache/detach
释放缓存设备
echo 1 > /sys/fs/bcache/< cache-set-uuid>/stop
删除缓存设备
echo 1 > /sys/block/nvme1n1/nvme1n1p${i}/bcache/set/unregister;
查询bcache状态
bcache-status
查看脏数据比例
for block_dev in `find /sys/block/bcache*/bcache/cache/cache0/priority_stats`; do cat
$block_dev; done
让缓存设备解除注册
echo 1 > /sys/block/sdX/sdX[Y]/bcache/detach
重新调整水位线
for block_dev in `find /sys/block/bcache*/bcache/writeback_percent` ;do echo 10 > $block_dev
;done
查看脏数据量
for block_dev in `find /sys/block/bcache*/bcache/dirty_data` ;do cat $block_dev ;done
查看缓存模式
for block_dev in `find /sys/block/bcache*/bcache/cache_mode` ;do cat $block_dev ;done
修改缓存模式
# 修改缓存模式为 writeback
for block_dev in `find /sys/block/bcache*/bcache/cache_mode` ;do echo "writeback" >
$block_dev ;done
10.2. N版新增命令
查询进程crash信息
ceph crash ls
查询crash详情
ceph crash info < id>
归档所有crash日志
ceph crash archive-all
查看卷性能监控数据
rbd perf image iostat
根据iops由高到低排序后的卷性能监控数据
rbd perf image iotop
简单测试mon获取其状态信息
ceph ping mon.*
查询mon节点时钟同步信息
ceph time-sync-status
检查osd是否能安全关进程(确保数据安全)
ceph osd ok-to-stop