ZFSのscrubが異常に遅い(Extremely slow zpool scrub performance)

PC

自動修復機能のあるZFSとて、デバイスのエラーがバラバラと出てきたら早めに手を打たないと、データの修復ができなくなることもあり得るので、scrubを実行してみた。
いざ実行してみたら異常に遅かったのだが調べてみたところ、速度を上げるパラメータがあった。

foo@myhost:~$ sudo zpool scrub pool

しばらく放置してみて様子を見ると、

foo@myhost:~$ sudo zpool status
[sudo] password for foo: 
  pool: pool
 state: ONLINE
 scan: scrub in progress since Sat Mar 31 20:36:28 2012
    9.66G scanned out of 2.82T at 1.00M/s, (scan is slow, no estimated time)
    0 repaired, 0.33% done
config:

    NAME                           STATE     READ WRITE CKSUM
    pool                           ONLINE       0     0     0
      raidz1-0                     ONLINE       0     0     0
        ata-ST31500341AS_9Vxxxx0W  ONLINE       0     0     0
        ata-ST31500341AS_9Vxxxx53  ONLINE       0     0     0
        ata-ST31500341AS_9VxxxxY3  ONLINE       0     0     0

errors: No known data errors
foo@myhost:~$ 

「scan is slow, no estimated time」って何!!
1M/sなんてありえない。。

foo@myhost:~$ sudo zpool iostat pool
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
pool        2.82T  1.24T     34    295   359K  31.7M

て感じです。

scrub速度を上げるためのパラメータ

色々調べてみたところ、zfs-discuss(ZFS on LinuxプロジェクトのディスカッションML)での情報を発見。

Re: [zfs-discuss] Extremely slow zpool scrub performance -- zfs-discuss, Wed, 18 May 2011 18:20:53 -0700
曰く、scrubの速度をあげるには、
・zfs_scrub_delayを1に
・zfs_top_maxinflightを64に
するとよいとのこと。

こんな設定をしている人もいた。
Re: Speed up a scrub -- zfs-discuss, 29 Sep 22:01 2011

root@density:/sys/module/zfs/parameters# cat zfs_top_maxinflight
2147483647
root@density:/sys/module/zfs/parameters# cat zfs_scrub_delay
0
root@density:/sys/module/zfs/parameters# cat zfs_resilver_delay
0
root@density:/sys/module/zfs/parameters# cat zfs_scan_idle
0
root@density:/sys/module/zfs/parameters# cat zfs_scrub_limit
2147483647

今回はこの値を拝借して試してみることにした。

ZFS on Linuxでのscrub関連パラメータ変更

と言うことで、/sys/module/zfs/parameters上で設定すればいいらしい。
早速、パラメータを変えてみる。ついでにどんなパラメータがあるか確認してみる。

foo@myhost:/sys/module/zfs/parameters$ ls
l2arc_feed_again     zfs_arc_min               zfs_scan_min_time_ms        zfs_write_limit_inflated
l2arc_feed_min_ms    zfs_arc_p_min_shift       zfs_scrub_delay             zfs_write_limit_max
l2arc_feed_secs      zfs_arc_shrink_shift      zfs_scrub_limit             zfs_write_limit_min
l2arc_headroom       zfs_dedup_prefetch        zfs_top_maxinflight         zfs_write_limit_override
l2arc_noprefetch     zfs_flags                 zfs_txg_synctime_ms         zfs_write_limit_shift
l2arc_norw           zfs_free_min_time_ms      zfs_txg_timeout             zfs_zevent_cols
l2arc_write_boost    zfs_no_scrub_io           zfs_vdev_aggregation_limit  zfs_zevent_console
l2arc_write_max      zfs_no_scrub_prefetch     zfs_vdev_cache_bshift       zfs_zevent_len_max
spa_config_path      zfs_no_write_throttle     zfs_vdev_cache_max          zil_replay_disable
zfetch_array_rd_sz   zfs_nocacheflush          zfs_vdev_cache_size         zio_bulk_flags
zfetch_block_cap     zfs_pd_blks_max           zfs_vdev_max_pending        zio_delay_max
zfetch_max_streams   zfs_prefetch_disable      zfs_vdev_min_pending        zio_injection_enabled
zfetch_min_sec_reap  zfs_read_chunk_size       zfs_vdev_ramp_rate          zio_requeue_io_start_cut_in_line
zfs_arc_grow_retry   zfs_recover               zfs_vdev_read_gap_limit     zvol_major
zfs_arc_max          zfs_resilver_delay        zfs_vdev_scheduler          zvol_threads
zfs_arc_meta_limit   zfs_resilver_min_time_ms  zfs_vdev_time_shift
zfs_arc_meta_prune   zfs_scan_idle             zfs_vdev_write_gap_limit
foo@myhost:/sys/module/zfs/parameters$ 

おぉ、あるある。
既存の設定を調べてみる。

foo@myhost:/sys/module/zfs/parameters$ cat zfs_top_maxinflight 
32
foo@myhost:/sys/module/zfs/parameters$ cat zfs_scrub_delay 
4
foo@myhost:/sys/module/zfs/parameters$ cat zfs_resilver_delay
2
foo@myhost:/sys/module/zfs/parameters$ cat zfs_scan_idle
50
foo@myhost:/sys/module/zfs/parameters$ cat zfs_scrub_limit
10

実際にパラメータを変えてみる

前出の設定値を使用してパラメータを変えてみる。
設定する値は、

zfs_top_maxinflight 2147483647
zfs_scrub_delay     0
zfs_resilver_delay  0
zfs_scan_idle       0
zfs_scrub_limit     2147483647

とする。

foo@myhost:/sys/module/zfs/parameters$ sudo sh
# pwd
/sys/module/zfs/parameters
# cat > zfs_top_maxinflight
2147483647
# cat > zfs_scrub_delay 
0
# cat > zfs_resilver_delay
0
# cat > zfs_scan_idle
0
# cat > zfs_scrub_limit
2147483647

# exit
foo@myhost:~$ sudo zpool scrub pool

再度調べてみる。

foo@myhost:~$ sudo zpool status
  pool: pool
 state: ONLINE
 scan: scrub in progress since Sat Mar 31 23:53:31 2012
    9.75G scanned out of 2.82T at 26.4M/s, 31h0m to go
    0 repaired, 0.34% done
config:

    NAME                           STATE     READ WRITE CKSUM
    pool                           ONLINE       0     0     0
      raidz1-0                     ONLINE       0     0     0
        ata-ST31500341AS_9Vxxxx0W  ONLINE       0     0     0
        ata-ST31500341AS_9Vxxxx53  ONLINE       0     0     0
        ata-ST31500341AS_9VxxxxY3  ONLINE       0     0     0

errors: No known data errors
foo@myhost:~$ 

foo@myhost:/sys/module/zfs/parameters$ 

おぉ見違えるように早くなりました。(^^

固定化するため、以下の内容で/etc/modprobe.d/zfs.confを作成。

options zfs zfs_vdev_max_pending=1
options zfs zfs_top_maxinflight=2147483647
options zfs zfs_scrub_delay=0
options zfs zfs_resilver_delay=0
options zfs zfs_scan_idle=0
options zfs zfs_scrub_limit=2147483647

こんな書き込みもあった。
Re: [zfs-discuss] Extremely slow zpool scrub performance

> You mentioned that the pool was somewhat full, can you send the output
> of 'zpool iostat -v pool0'? You can also try doing the following to
> reduce 'metaslab_min_alloc_size' to 4K:
>
> echo "metaslab_min_alloc_size/Z 1000" | mdb -kw
So just changing that setting moved my write rate from 40MB/s to 175MB/s.

参考URL

Google Groupszpool scrub speed - zfs-discuss

[OpenIndiana-discuss] slow zfs scrub, fixed after reboot?

The FreeBSD Forums
Severe performance problems with ZFS scrub under some conditions

Richard EllingHow to manage scrub priority or defer scrub?

Last Updated on 2024-08-13 by spicebeat

タイトルとURLをコピーしました