2020-08 from--https://wiki2.xbits.net:4430/storage:zfs:zfs%E8%B0%83%E4%BC%98
- zfs_storage_pool_layout_white_paper_web.pdf (zpool的布局,性能白皮书)
1. zpool的注意事项
- 一旦将一个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
2. zpool vdev
上文提到,根据不同的数据保护级别,磁盘个数,可用容量等因素进行综合考虑.
3. Recordsize / Volblocksize
- Defines the largest block that can be written to the dataset or zvol
- Is the unit that ZFS compresses and checksums
3.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
3.2 volblocksize
- 默认创建的zvol volblocksize=8k,不可更改
# 创建时指定 zfs create -V 5G -o volblocksize=16K sas/test # 查看 zfs get volblocksize sas/test
4. ZFS 缓存
4.1 缓存类型
读缓存 ARC / L2ARC:
- ZFS在 RAM 中提供的读取缓存称为 ARC,可以减少读取延迟;
- 如果使用 SSD 作为缓存设备,则称为 L2ARC;
- ARC 之外的读取数据会在 L2ARC 中缓存,由此提高随机读性能;
写缓存 ZIL:
4.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 显著提升了;
4.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
5. scrub
临时生效:
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
6. ashift
- ashift 主要是用于设置最小 block size,建议是ashift都设为12(2^12=4K bytes),一旦设置就不能更改,一般是建议在创建zpool的时候指定ashift=12,见 zpool_管理
# 查看ashift zdb | grep ashift
7. atime
atime=off可以设置到zpool上,这个属性会被dataset所继承:
zfs set atime=off tank
8. deduplication
删除重复资料功能(Deduplication)是一个非常耗资源的功能,它会严重降低效能,强烈建议关闭。
属性可被dataset所继承:
zfs set dedup=off tank/test
9. compress
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 |
10. syslog优化
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