ZFS 调优指南

  • 一旦将一个VDEV设备加入pool后,此装置就无法从VDEV中移除,只能“replace” 或者重新构建zpool1)
  • 目前为止,RAIDZ还不支持 expansion,也就是说如果原来是3盘的RAIDZ,现在add了一个新的盘进去,不会变成4盘的RAIDZ,而是3盘RAIDZ + 单盘;
  • 无法缩小 zpool,只能加大它;2)
  • 速度方面:RAID-0 » RAID-1 » RAIDZ-1 » RAIDZ-2 » RAIDZ-3
  • Hot Spare 的动态替换功能预设是关闭,除非你去开启它;
  • 一个zpool中若使用较大的硬碟来替换原本里面较小的硬碟时,zpool不会自动变更总体容量大小!除非在你建立此Zpool时有开启resize的功能(预设off)
  • 当Fragmentation大量产生时,ZFS 效能会有明显感觉到降低;
  • ZFS 有支援原生加密,但是它不是免费的功能,所有权是属于Oracle的;

一些可能导致性能降低的情况:

  • Workload 和硬件不太兼容;
  • 硬件故障 - disk, controller, SAS cable
  • pool 容量快满了
  • Fragmentation - “zpool get fragmentation pool_name”
  • Background deletion - “zpool get freeing pool_name”
  • 不推荐的pool构成 - mixing RAIDZs, mirrors and drive types

  • Defines the largest block that can be written to the dataset or zvol
  • Is the unit that ZFS compresses and checksums

2.1 recordsize

  • 针对dataset,默认128K,改变仅对新文件写入生效;

Note: 如将kvm虚拟机的磁盘文件放在zfs dataset里,建议将recordsize=4k,并compression=off,这样会提高虚拟机的IOPS !

# 查看
zfs get recordsize sas/test
# 设置
zfs set recordsize=256k sas/test
# 创建时指定
zfs create -o recordsize=64k sas/test

2.2 volblocksize

  • 默认创建的zvol volblocksize=8k,不可更改
# 创建时指定
zfs create -V 5G -o volblocksize=16K sas/test
# 查看
zfs get volblocksize sas/test

3.1 缓存类型

读缓存 ARC / L2ARC:

  • ZFS在 RAM 中提供的读取缓存称为 ARC,可以减少读取延迟;
  • 如果使用 SSD 作为缓存设备,则称为 L2ARC;
  • ARC 之外的读取数据会在 L2ARC 中缓存,由此提高随机读性能;

写缓存 ZIL:

  • ZIL3)用于保证文件系统的一致性,ZIL在真正写数据之前被写入VDEV;
  • ZIL是日志文件,是一个系统对数据写入操作的意图的日志文件,相比于需要写入的数据本身,这个日志文件会小很多很多;
  • 即使在硬件设备中没有SLOG,ZIL仍然会被保存在ZFS文件系统中;
  • SLOG是ZFS文件系统中用于存放ZIL的一个高速存储设备
    • 最佳的SLOG设备是一个小型的基于闪存的设备,比如如SSD或NVMe卡;4)
    • 容量不需要太大,16G足矣,但是应该是写入优化 & 延迟优化的SSD (SLC颗粒 + NVME)
  • SLOG 设备不能在池之间共享,每个池需要一个单独的SLOG设备;
  • SLOG 设备建议是mirror的VDEV;

3.2 调整ARC/L2ARC

Warning: zfs默认ARC使用2/3内存,Linux 上使用ZFS 强烈建议配置!!

针对Ubuntu 18.04:

# 查看当前ARC配置(单位:字节)
cat /sys/module/zfs/parameters/zfs_arc_max
# 临时设置
echo 25769803776 > /sys/module/zfs/parameters/zfs_arc_max
echo 4294967296 > /sys/module/zfs/parameters/l2arc_write_max
echo 4294967296 > /sys/module/zfs/parameters/l2arc_write_boost
# 永久设置
cat >> /etc/modprobe.d/zfs.conf <<'EOF'
# You really have to specify zfs_arc_max IN BYTES ONLY!
# 32GB=34359738368, 24G=25769803776, 16GB=17179869184, 8GB=8589934592, 4GB=4294967296, 2GB=2147483648, 1GB=1073741824, 500MB=536870912, 250MB=268435456
options zfs zfs_arc_max=25769803776
options zfs l2arc_write_max=4294967296
options zfs l2arc_write_boost=4294967296
options zfs l2arc_noprefetch=0
EOF

一块Intel s3710 200G划分了大概180G做L2ARC,经过上面的调优后,反复几次copy同样的文件的效果:

  • L2ARC的读取速度达到了intel s3710 200G本身的极限;
  • tank pool本身没有读取数据了,都是从cache中读取的;
  • L2ARC hit ratio 显著提升了;


3.3 L2ARC/Zil 设备

Note: 建议ZiL设备设置为mirror类型以增强数据安全性,大小≤16G,SLC等低延迟类型颗粒,有条件强烈推荐上NVME SSD !

L2ARC设备一般的SSD就可以了,容量40G以上吧!

# 增加Zil设备
zpool add tank log mirror /dev/sdd /dev/sde
# 移除Zil设备
zpool status tank
zpool remove tank /dev/sdx
# 增加L2ARC设备
zpool add tank cache /dev/sdx
# 移除L2ARC设备
zpool status tank
zpool remove tank /dev/sdx

临时生效:

echo 0 > /sys/module/zfs/parameters/zfs_scan_idle
echo 5000 > /sys/module/zfs/parameters/zfs_scan_min_time_ms
echo 0 > /sys/module/zfs/parameters/zfs_scrub_delay
echo 0 > /sys/module/zfs/parameters/zfs_resilver_delay
echo 512 > /sys/module/zfs/parameters/zfs_top_maxinflight

查看:

cat /sys/module/zfs/parameters/{zfs_scan_idle,zfs_scan_min_time_ms,zfs_scrub_delay,zfs_resilver_delay,zfs_top_maxinflight}

写入配置:

cat >> /etc/modprobe.d/zfs.conf <<'EOF'
# scrub tune
options zfs zfs_scan_idle=0
options zfs zfs_scan_min_time_ms=5000
options zfs zfs_scrub_delay=0
options zfs zfs_resilver_delay=0
options zfs zfs_top_maxinflight=512
EOF

  • ashift 主要是用于设置最小 block size,建议是ashift都设为12(2^12=4K bytes),一旦设置就不能更改,一般是建议在创建zpool的时候指定ashift=12,见 zpool_管理
# 查看ashift
zdb | grep ashift

atime=off可以设置到zpool上,这个属性会被dataset所继承:

zfs set atime=off tank

删除重复资料功能(Deduplication)是一个非常耗资源的功能,它会严重降低效能,强烈建议关闭。

属性可被dataset所继承:

zfs set dedup=off tank/test

zfs/zpool支持的压缩类型可以是off5),lz4(默认)等:

zfs set compress=[off|lz4|gzip] tank

下面是off和lz4的2次测试结果6)

off lz4
第一次 3m25.619s 2m56.767s
第二次 3m16.834s 2m49.488s

zfs send、recv的时候 sed会在syslog产生大量无用日志,处理方式为在’zed_exit_if_ignoring_this_event’前面插入一行判断:

sed -i '/^.*zed_exit_if_ignoring_this_event/i\if [ "${ZEVENT_SUBCLASS}" = "history_event" ]; then exit 0; fi' /etc/zfs/zed.d/all-syslog.sh

1)
zol 0.8可以remove单个或者镜像类型的vdev了,但是raidz的还是不行
3)
ZFS Intent Log
4)
他们的特点是具有的高性能,低延迟以及发生断电时数据的持久性。
5)
关闭后,后端磁盘的负载一下就上来了
6)
HUS726040ALE610 * 6做raidz-1,从Intel s3710 200G拷贝一个100G的文件到zfs
  • storage/zfs/zfs调优.txt
  • 最后更改: 2019/09/19 16:11
  • 由 mrco