前言
ZFS使用也有一年多的时间了,每次新配置的时候都要去找一下各种教程,太麻烦了。这次整理一下写出来,做笔记用。
方案简述
我们新的芬兰计算集群配置了一台12核CPU+128G DDR4内存+1T数据中心级NVME+10*10TB企业级机械硬盘
的机器作为存储节点。
用NVME盘做系统盘,10块10TB的机械盘组ZFS-RAIDZ,用96G内存作为ZFS缓存,ZFS的性能对比可以看这个:
文章目录[隐藏] 前言 ZFS的特性 不同等级Level的ZFS阵列 前言 ZFS被称为是世界上最后一个存储系统(emm),还有人说"完全填充ZFS的128位存储池所需的能量,实际上比煮沸海洋需要的更多"。不论是从扩展性还是从性能上讲ZFS都有着独特的优势,在用了几年ZFS之后,现在已经离不开这个文件系统了。 其实想整理这篇文章已经很久了,但是一直懒的动笔,今天终于下定决心来写一下了,整理了网上一些比较权威的实测数据,同时也从原理上来讲讲到底如何选择ZFS的阵列等级。 ZFS简介 以下内容直接摘抄自维基百科 ZFS是一个拥有逻辑卷管理功能的文件系统,最早源自于Oracle为Solaris操作系统开发的文件系统。ZFS具有可扩展性,并且包括大量保护措施防止数据损坏,支持高存储容量、高效数据压缩、集成文件系统、卷管理、快照和写时复制、连续完整性检查与自动修复、RAID-Z、原生NFSv4 ACL等功能,并且能被精确配置。ZFS有两个主要实现,分别来自Oracle和OpenZFS,它们之间极度相似,这使得ZFS在类Unix系统中广泛可用。 ZFS的特性 存储池 Pooled-storage 写入时复制 Copy-on-write 快照 Snapshots 数据完整性验证和自动修复 RAID-Z 最大单个文件大小为 16 EB(1 EB = 1024 PB) 最大 256 千万亿(256*1015 )的 ZB(1 ZB = 1024 EB)的存储 不同等级Level的ZFS阵列 在谈论RAID阵列的时候,最常被问到的问题是:“哪个等级的阵列是最好的?”实际上没有最好的选择,如何选择完全取决于想要实现的特性和愿意放弃的特性。 实际上我们最应该问自己的问题是:“我们的数据有多重要?” 不管是ZFS阵列还是常规的RAID阵列,都有三个非常重要的指标:性能、容量以及数据完整性(Performance, capacity and data integrity),脱离了任何一个指标的阵列都是无意义的。 但是对于不同盘位下的推荐ZFS等级,可以参考一下这个: ZFS与RAID阵列等级划分 我们经常把ZFS阵列和RAID阵列的各个等级划等号,这里给尚不了解RAID阵列的同学补个课 ZFS不同磁盘数量 x 阵列等级下的性能对比 这里我们会给出性能实测,并在测试结果前面列出磁盘数量,RAID类型,容量和性能指标,以便于比较。速度显示“ w”表示写入,“ rw”表示重写,“ r”表示读取,吞吐量以兆字节/秒为单位。 下表是不同ZFS阵列等级在未压缩的条件下测速结果。 […]
但是在高读写负载下依旧出现了超过30%的IO delay,因此考虑使用闲置的NVME空间作为读(cache)+写(ZIL log)缓存。
数据安全提醒
其实这是一个性价比很高的方案,近百TB的大容量+最热文件内存机读取速度+较热文件nvme的读取速度+nvme的写入速度。
但是作为写入缓存的ZIL(log)坏了比较麻烦,不过也只影响坏之前没有来得及写回ZFS阵列的内容(在非连续高负载下问题不大),根据数据的重要程度选择要不要做成raid1的缓存:
zpool add tank log mirror /dev/zil-cache1 /dev/zil-cache2
而cache和内存的效果一样,只是作为L2ARC加速读取,内存还是一级ARC,作为最热的文件缓存,L2作为沉淀层。
新建loop虚拟盘
本地磁盘就是NVME的,如果可以重新分区那是最好,不过我这里嫌麻烦就直接用loop虚拟盘了,性能会差一点点但是不会太多(毕竟本地已经格式化为Ext4了)。
创建镜像文件
大家都喜欢用dd,不过fallocate我觉得更舒服。这里新建两个镜像文件,分别是读缓存和写缓存的:
root@HPC-HEL1-S101 /home # fallocate -l 300G zfs-log-cache.img root@HPC-HEL1-S101 /home # fallocate -l 300G zfs-read-cache.img
要注意的是,读缓存损坏后数据不会丢失,写缓存损坏的话会导致数据丢失,慎用!
挂载为loop
这个没啥好说的,用losetup即可:
root@HPC-HEL1-S101 /home # losetup -fP zfs-log-cache.img root@HPC-HEL1-S101 /home # losetup -fP zfs-read-cache.img
检查挂载情况
root@HPC-HEL1-S101 /home # losetup -a /dev/loop1: [66306]:37691140 (/home/zfs-log-cache.img) /dev/loop2: [66306]:37691139 (/home/zfs-read-cache.img) /dev/loop0: [66306]:52272397 (/var/lib/vz/images/100/vm-100-disk-0.raw) root@HPC-HEL1-S101 /home # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 64G 0 loop loop1 7:1 0 300G 0 loop loop2 7:2 0 300G 0 loop
添加到zpool
查看zpool
首先检查一下zpool的情况:
root@HPC-HEL1-S101 /home # zpool status pool: Hel1-S101 state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM Hel1-S101 ONLINE 0 0 0 raidz1-0 ONLINE 0 0 0 sda ONLINE 0 0 0 sdb ONLINE 0 0 0 sdc ONLINE 0 0 0 sdd ONLINE 0 0 0 sde ONLINE 0 0 0 sdf ONLINE 0 0 0 sdg ONLINE 0 0 0 sdh ONLINE 0 0 0 sdi ONLINE 0 0 0 sdj ONLINE 0 0 0 errors: No known data errors
添加缓存
分别添加读缓存和写缓存:
root@HPC-HEL1-S101 /home # zpool add Hel1-S101 log /dev/loop1 root@HPC-HEL1-S101 /home # zpool add Hel1-S101 cache /dev/loop2
检查缓存情况
root@HPC-HEL1-S101 /home # zpool status pool: Hel1-S101 state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM Hel1-S101 ONLINE 0 0 0 raidz1-0 ONLINE 0 0 0 sda ONLINE 0 0 0 sdb ONLINE 0 0 0 sdc ONLINE 0 0 0 sdd ONLINE 0 0 0 sde ONLINE 0 0 0 sdf ONLINE 0 0 0 sdg ONLINE 0 0 0 sdh ONLINE 0 0 0 sdi ONLINE 0 0 0 sdj ONLINE 0 0 0 logs loop1 ONLINE 0 0 0 cache loop2 ONLINE 0 0 0 errors: No known data errors
缓存效果
用zpool iostat -v
可以明显看到SSD的读写缓存已经生效了,后续热文件将直接从cache中读取,降低机械盘的负载。
root@HPC-HEL1-S101 ~ # zpool iostat -v capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- Hel1-S101 132G 90.8T 0 89 3.30K 1.91M raidz1 132G 90.8T 0 81 3.30K 991K sda - - 0 8 333 99.5K sdb - - 0 7 315 98.6K sdc - - 0 8 349 99.6K sdd - - 0 7 334 98.7K sde - - 0 8 362 99.7K sdf - - 0 8 326 98.7K sdg - - 0 8 354 99.6K sdh - - 0 8 328 98.6K sdi - - 0 8 349 99.6K sdj - - 0 8 322 98.5K logs - - - - - - loop1 11.8M 298G 0 10 8 1.21M cache - - - - - - loop2 224M 300G 0 0 49 81.3K ---------- ----- ----- ----- ----- ----- -----
fio测试-16k小文件随机
测试代码:fio -filename=/Hel1-S101/fiotest.bin -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=10G -numjobs=30 -runtime=10 -group_reporting -name=zfs-cache-test
Jobs: 30 (f=30): [w(30)][100.0%][w=153MiB/s][w=9782 IOPS][eta 00m:00s] zfs-cache-test: (groupid=0, jobs=30): err= 0: pid=21034: Thu Jun 4 18:49:56 2020 write: IOPS=11.1k, BW=173MiB/s (182MB/s)(1734MiB/10002msec); 0 zone resets clat (usec): min=5, max=88218, avg=2700.66, stdev=2176.33 lat (usec): min=6, max=88218, avg=2700.98, stdev=2176.36 clat percentiles (usec): | 1.00th=[ 10], 5.00th=[ 45], 10.00th=[ 52], 20.00th=[ 816], | 30.00th=[ 1696], 40.00th=[ 2311], 50.00th=[ 2737], 60.00th=[ 3130], | 70.00th=[ 3556], 80.00th=[ 3982], 90.00th=[ 4883], 95.00th=[ 6063], | 99.00th=[ 7373], 99.50th=[ 8291], 99.90th=[18220], 99.95th=[26346], | 99.99th=[53740] bw ( KiB/s): min= 3552, max=40271, per=3.33%, avg=5913.96, stdev=4550.90, samples=592 iops : min= 222, max= 2516, avg=369.60, stdev=284.39, samples=592 lat (usec) : 10=1.10%, 20=0.79%, 50=7.09%, 100=5.98%, 250=2.23% lat (usec) : 500=0.92%, 750=1.26%, 1000=3.18% lat (msec) : 2=11.54%, 4=46.17%, 10=19.38%, 20=0.29%, 50=0.07% lat (msec) : 100=0.01% cpu : usr=0.16%, sys=2.21%, ctx=205649, majf=0, minf=0 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=0,110988,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=173MiB/s (182MB/s), 173MiB/s-173MiB/s (182MB/s-182MB/s), io=1734MiB (1818MB), run=10002-10002msec
fio测试-大文件1G连续
测试代码:fio -filename=/Hel1-S101/fiotest.bin -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=1G -size=20G -numjobs=30 -runtime=10 -group_reporting -name=zfs-cache-test
zfs-cache-test: (groupid=0, jobs=30): err= 0: pid=6117: Thu Jun 4 18:52:20 2020 write: IOPS=0, BW=785MiB/s (823MB/s)(30.0GiB/39131msec); 0 zone resets clat (msec): min=14642, max=38803, avg=24851.81, stdev=8958.50 lat (msec): min=14770, max=39124, avg=25138.77, stdev=8987.50 clat percentiles (msec): | 1.00th=[14697], 5.00th=[14697], 10.00th=[14832], 20.00th=[15771], | 30.00th=[16174], 40.00th=[16845], 50.00th=[17113], 60.00th=[17113], | 70.00th=[17113], 80.00th=[17113], 90.00th=[17113], 95.00th=[17113], | 99.00th=[17113], 99.50th=[17113], 99.90th=[17113], 99.95th=[17113], | 99.99th=[17113] cpu : usr=0.54%, sys=1.83%, ctx=264186, majf=0, minf=0 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=0,30,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=785MiB/s (823MB/s), 785MiB/s-785MiB/s (823MB/s-823MB/s), io=30.0GiB (32.2GB), run=39131-39131msec