提升CEPH系统对日志的Trim速度

1. CEPH系统 MDSs behind on trimming 的警报

在CEPH系统的MDS服务中,文件系统的元数据以日志形式存放于segment中,每个sgement存放1024个操作记录。当文件系统的数据使用完毕,CEPH系统则会以一定的速度Trim (消除) 元数据信息,此时会将MDS服务器中的数据回写到CEPH的磁盘OSD中,以降低MDS服务器上运行的mds服务的内存消耗。当segment数量超过默认128个时,则CEPH报警,意味着MDS服务器中保存了过量的元数据信息,占用内存可能较多,需要及时注意。

[root@ceph101 ~]# ceph health detail
HEALTH_WARN 2 MDSs behind on trimming
[WRN] MDS_TRIM: 2 MDSs behind on trimming
    mds.cephfs.ceph102.imxzno(mds.1): Behind on trimming (2235/128) max_segments: 128, num_segments: 2235
    mds.cephfs.ceph106.hggsge(mds.2): Behind on trimming (4260/128) max_segments: 128, num_segments: 4260

当遇到以上警告,若发现MDS服务器的内存足够,可以将默认阈值128提高,或加大Trim速度。

2. 解决办法

通过设置mds_log_max_segments参数来提高CEPH的 max_segments 数,在CEPH系统任意主机上运行即可。

ceph config set mds mds_log_max_segments 1024

通过设置参数来提升Trim速度。CEPH系统根据mds_cache_trim_threshold (默认256Ki)和mds_cache_trim_decay_rate (默认1.0)两个参数设置sgements的消除速度。默认设置下,当CEPH系统进行持续且Trim速度达到最大时,每秒钟Trim的记录数量为 ln(0.5)/rate*threshold 。当在CEPH系统中并行化读取或写入文件时,短时间内进行大量的文件操作,极容易导致segments过多,无法及时Trim。因此,需要提高Trim速度,其实也消耗不了太多CPU资源。

mds_cache_trim_threshold 设置了一定时间内能消除的最大文件数量。在进行Trim时,CEPH系统中有一个Counter程序记录了一定时间内被消除的文件数量。mds_cache_trim_decay_rate 参数和Counter程序的半衰期相关,该值越小,则半衰期越短。

默认参数值过于保守,下当为了提高Trim速度,推荐将 mds_cache_trim_threshold 参数提升到100倍,将mds_cache_trim_decay_rate参数降低到100倍。在任意一台CEPH主机中运行命令:

ceph config set mds mds_cache_trim_threshold 25600000
ceph config set mds mds_cache_trim_decay_rate 0.01

提升CEPH系统对PG的Scrub和Backfilling速度

1. 进行PG Srub的参数和原理

对PG进行Scrub,即检测PG分布到各OSDs上的数据是否一致。包含两种算法:第一种为Scrub,即仅检测数据的元信息,例如时间戳和文件大小等信息,速度快且基本不消耗磁盘;第二种为deep Scrub,会额外检测数据的内容是否一致,速度较慢且消耗大量磁盘读取。在CEPH系统进行scrub和deep-scrub的主要参数为:

(1)osd_scrub_begin_hour:设置进行Scrub的起始时间,推荐设置为22,即在晚上10点开始进行Scrub。CEPH系统默认值是0。
(2)osd_scrub_end_hour:设置进行Scrub的结束时间,推荐设置为8,即在早上8点结束scrub。CEPH系统默认值是24。
(3)osd_scrub_auto_repair:设置发现PG在多个OSDs中的数据不一致后,是否进行修复,推荐设置为true,即表示自动进行修复。CEPH系统默认值为false。
(4)osd_max_scrubs:进行Scrub时,设置单个OSD能同时进行Scrub操作数,推荐设置为10。CEPH系统默认值是1,会导致整个系统能同时进行的Scrub操作数很少。提高该值能明显增加Scrub的并行数,增加Scrub速度。否则,可能导致pgs not deep-scrubbed in time的警报。
(5)osd_scrub_min_interval:设置单个PG进行Scrub的最小间隔时间,默认值为86400,一天。
(6)osd_scrub_max_interval:设置单个PG进行Scrub的最大间隔时间,默认值为604800,一周。
(7)osd_scrub_interval_randomize_ratio:设置单个PG进行Scrub时,间隔会额外增加一定的随机时间,该时间为osd_scrub_min_interval*该阈值,默认值为0.5。
(8)osd_deep_scrub_randomize_ratio:在进行Scrub时,随机变更为deep scrub的概率,推荐设置为0.05。CEPH系统默认值为0.15。
(9)osd_deep_scrub_interval:设置进行deep Scrub的时间间隔,推荐设置为259200,即一月30天。CEPH系统默认值为604800,即若有PG没能在一周内进行deep scrub,则导致pgs not deep-scrubbed in time的警报。改变该值应该并不能减慢或加快deep scrub的速度。

以上参数表示:对每个PG进行清理,每隔1~1.5天即会进行一次Scrub。每次进行Scrub时,有5%的概率变更为deep scrub,这表示平均20~30天会对所有PGs进行一轮deep Scrub。当一个星期后,若有PG未进行scrub,或一个月后,若有PG未进行deep-scrub,则进行报警。进行优化方式:通过增大 osd_max_scrubs 参数值来加快scrub速度;通过减少 osd_deep_scrub_randomize_ratio 参数值来减少deep scrub任务量,减少对磁盘的读取消耗。

2. 进行PG backfilling的参数和原理

当CEPH系统更换硬盘时,会将一些PGs转移到新硬盘做的OSD上,这时需要对数据进行回填。默认情况下,回填速度极慢,需要修改OSD参数增加回填速度。

(10)osd_max_backfills:设置CEPH系统一次最多对指定数量的PGs进行回填,推荐根据需要回填的PGs数量和CEPH系统的整体OSDs数量来设置。默认值为1,过小,会导致回填速度极慢,可能需要数天才能让数据修复完毕。咱们系统有一次更换硬盘后需要对66个PGs进行回填,我直接设置该值为66即可。推荐该值 * PG副本数 / OSDs总数 不要超过 3,即让每个硬盘同时的读和写并发不要过大。
(11)osd_recovery_max_active:进行数据恢复时,设置每个OSD的最大读写请求数,推荐设置为10。CEPH系统默认值为3。
(12)osd_recovery_max_active_hdd:进行数据恢复时,设置每个OSD的机械硬盘最大读写请求数,推荐设置为10。CEPH系统默认值为3。
(13)osd_recovery_max_active_ssd:进行数据恢复时,设置每个OSD的固态硬盘最大读写请求数,推荐设置为100。CEPH系统默认值为10。

3. 通过命令行修改OSD参数

需要在各台CEPH存储服务器上运行程序,对各自的OSDs进行参数修改。且通过命令行修改仅在当前CEPH系统中生效,重启服务器后失效。

ceph tell osd.0 injectargs --osd_scrub_begin_hour=22 --osd_scrub_end_hour=8 --osd_scrub_auto_repair=true --osd_max_scrubs=10 --osd_scrub_min_interval=86400 --osd_scrub_max_interval=604800 --osd_scrub_interval_randomize_ratio=0.5 --osd_deep_scrub_randomize_ratio=0.05 --osd_deep_scrub_interval=259200 --osd_max_backfills=100 --osd_recovery_max_active=10 --osd_recovery_max_active_hdd=10 --osd_recovery_max_active_ssd=100

查看修改后的参数结果:

ceph daemon osd.0 config show | egrep "osd_scrub_begin_hour|osd_scrub_end_hour|osd_scrub_auto_repair|osd_max_scrubs|osd_scrub_min_interval|osd_scrub_max_interval|osd_scrub_interval_randomize_ratio|osd_deep_scrub_randomize_ratio|osd_deep_scrub_interval|osd_max_backfills|osd_recovery_max_active|osd_recovery_max_active_hdd|osd_recovery_max_active_ssd"

提升CEPH PG scrub的速度

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

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

  cluster:
    id:     8f1c1f24-59b1-11eb-aeb6-f4b78d05bf17
    health: HEALTH_ERR
            6 scrub errors
            Possible data damage: 5 pgs inconsistent
            1497 pgs not deep-scrubbed in time
            1466 pgs not scrubbed in time

  services:
    mon: 5 daemons, quorum ceph101,ceph103,ceph107,ceph109,ceph105 (age 5d)
    mgr: ceph107.gtrmmh(active, since 9d), standbys: ceph101.qpghiy
    mds: cephfs:3 {0=cephfs.ceph106.hggsge=up:active,1=cephfs.ceph104.zhkcjt=up:active,2=cephfs.ceph102.imxzno=up:active} 1 up:standby
    osd: 360 osds: 360 up (since 5d), 360 in (since 5d)

  data:
    pools:   4 pools, 10273 pgs
    objects: 331.80M objects, 560 TiB
    usage:   1.1 PiB used, 4.2 PiB / 5.2 PiB avail
    pgs:     10261 active+clean
             7     active+clean+scrubbing+deep
             5     active+clean+inconsistent

  io:
    client:   223 MiB/s rd, 38 MiB/s wr, 80 op/s rd, 12 op/s wr

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

osd_max_scrubs参数用于设置单个OSD同时进行的最大scrub操作数量;osd_scrub_load参数设置负载阈值。主要修改以上两个参数来提高scrub速度,其默认值为1和0.5。

例如,对ceph101主机中的所有OSDs进行参数修改:

首先,获取ceph101中所有的OSD信息:

ceph osd dump | grep `grep ceph101 /etc/hosts | perl -ne 'print $1 if m/(\d\S*)/'` | perl -ne 'print "$1\n" if m/(osd.\d+)/' > /tmp/osd.list

然后,对所有OSD的参数进行批量修改:

for i in `cat /tmp/osd.list`
do
    ceph tell $i injectargs --osd_max_scrubs=10 --osd_scrub_load_threshold=10
done

检查修改后的效果

for i in `cat /tmp/osd.list`
do
    echo $i
    ceph daemon $i config show | egrep "osd_max_scrubs|osd_scrub_load"
done

对所有的CEPH主机进行上述修改后,同时进行scrub的数量提高了30倍,并且使用top命令可以看到ceph-osd进程对CPU的资源消耗明显上升。

  cluster:
    id:     8f1c1f24-59b1-11eb-aeb6-f4b78d05bf17
    health: HEALTH_ERR
            6 scrub errors
            Possible data damage: 5 pgs inconsistent
            1285 pgs not deep-scrubbed in time
            1208 pgs not scrubbed in time
            1 slow ops, oldest one blocked for 37 sec, daemons [osd.124,osd.352] have slow ops.

  services:
    mon: 5 daemons, quorum ceph101,ceph103,ceph107,ceph109,ceph105 (age 5d)
    mgr: ceph107.gtrmmh(active, since 9d), standbys: ceph101.qpghiy
    mds: cephfs:3 {0=cephfs.ceph106.hggsge=up:active,1=cephfs.ceph104.zhkcjt=up:active,2=cephfs.ceph102.imxzno=up:active} 1 up:standby
    osd: 360 osds: 360 up (since 5d), 360 in (since 5d)

  data:
    pools:   4 pools, 10273 pgs
    objects: 331.80M objects, 560 TiB
    usage:   1.1 PiB used, 4.2 PiB / 5.2 PiB avail
    pgs:     10041 active+clean
             152   active+clean+scrubbing+deep
             75    active+clean+scrubbing
             3     active+clean+scrubbing+deep+inconsistent+repair
             2     active+clean+inconsistent

  io:
    client:   65 MiB/s rd, 4.2 MiB/s wr, 21 op/s rd, 2 op/s wr

此外,注意:(1)提高scrub的并行数可能对CEPH集群内网的网速要求较高,推荐使用10GE以上交换机。(2)条scrub的并行数,会导致一个OSD对应的硬盘同时并行读取的操作数量较高,当导致磁盘100%被使用时,可能磁盘的利用效率并不高,因此不推荐将 osd_max_scrubs参数调节到10以上。

对两个星期内(当前时间2022-08-03)未进行deep-scrubbed,已经有报警信息的PGs进行操作。

ceph pg dump | perl -e 'while (<>) { @_ = split /\s+/; $pg{$_[0]} = $1 if ($_[22] =~ m/2022-07-(\d+)/ && $1 <= 21); } foreach ( sort {$pg{$a} <=> $pg{$b}} keys %pg ) { print "ceph pg deep-scrub $_; sleep 30;\n"; }' > for_deep_scrub.list

sh for_deep_scrub.list