我有八个 3TB Western Digital Red SATA 硬盘 sdb 至 sdi,用于我的池中。
我的启动和操作系统驱动器是 sda 上的 850 EVO SSD。
八个 WD 硬盘安装在 Supermicro AOC-SAS2LP-MV8 附加卡上,这是 8 通道 SAS/SATA 适配器,每通道 600 Mbyte/s,安装在 PCIE 3.0 x16 中,以 x8 的速度运行在 Supermicro ATX DDR4 LGA 1151 C7Z170-OCE-O 主板上。
我的服务器和 ZFS 设置如下:
[root@nas ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@nas ~]# uname -a
Linux nas.whittenberg.domain 3.10.0-327.28.2.el7.x86_64 #1 SMP Wed Aug 3 11:11:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
[root@nas ~]# cat /var/log/dmesg | grep ZFS
[ 0.793572] ZFS: Loaded module v0.6.5.7-1, ZFS pool version 5000, ZFS filesystem version 5
[root@nas ~]# cat /var/log/dmesg | grep SPL
[ 0.777144] SPL: Loaded module v0.6.5.7-1
[root@nas ~]# cat /etc/modprobe.d/zfs.conf
# disable prefetch = 1
options zfs zfs_prefetch_disable=0
# set arc max to 48GB. I have 64GB in my server
options zfs zfs_arc_max=51539607552
# set size to 128k same as file system block size
options zfs zfs_vdev_cache_size=1310720
options zfs zfs_vdev_cache_max=1310720
options zfs zfs_read_chunk_size=1310720
options zfs zfs_vdev_cache_bshift=12
options zfs zfs_read_chunk_size=1310720
# Set thes to 10 so we get better IO at cost of banwidth
options zfs zfs_vdev_async_read_max_active=10
options zfs zfs_vdev_async_read_min_active=10
options zfs zfs_vdev_async_write_max_active=10
options zfs zfs_vdev_async_write_min_active=10
options zfs zfs_vdev_sync_read_max_active=10
options zfs zfs_vdev_sync_read_min_active=10
options zfs zfs_vdev_sync_write_max_active=10
options zfs zfs_vdev_sync_write_min_active=10
[root@nas ~]# zpool status
pool: myraid
state: ONLINE
scan: scrub repaired 0 in 0h16m with 0 errors on Sun Aug 7 01:40:49 2016
config:
NAME STATE READ WRITE CKSUM
myraid ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
mirror-2 ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
mirror-3 ONLINE 0 0 0
sdh ONLINE 0 0 0
sdi ONLINE 0 0 0
errors: No known data errors
[root@nas ~]# zpool iostat -v
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
myraid 382G 10.5T 119 35 14.0M 606K
mirror 95.5G 2.63T 29 8 3.49M 149K
sdb - - 28 8 3.50M 153K
sdc - - 28 8 3.50M 153K
mirror 95.5G 2.63T 29 8 3.49M 151K
sdd - - 28 8 3.50M 155K
sde - - 28 8 3.50M 155K
mirror 95.5G 2.63T 29 8 3.49M 152K
sdf - - 28 8 3.50M 156K
sdg - - 28 8 3.50M 156K
mirror 95.5G 2.63T 29 9 3.49M 155K
sdh - - 28 9 3.50M 159K
sdi - - 28 9 3.50M 159K
---------- ----- ----- ----- ----- ----- -----
[root@nas ~]# zfs get all
NAME PROPERTY VALUE SOURCE
myraid type filesystem -
myraid creation Sat Aug 6 21:01 2016 -
myraid used 382G -
myraid available 10.2T -
myraid referenced 382G -
myraid compressratio 1.05x -
myraid mounted yes -
myraid quota none default
myraid reservation none default
myraid recordsize 128K local
myraid mountpoint /myraid default
myraid sharenfs off default
myraid checksum fletcher4 local
myraid compression lz4 local
myraid atime off local
myraid devices on default
myraid exec on default
myraid setuid on default
myraid readonly off default
myraid zoned off default
myraid snapdir hidden default
myraid aclinherit restricted default
myraid canmount on default
myraid xattr on default
myraid copies 1 default
myraid version 5 -
myraid utf8only off -
myraid normalization none -
myraid casesensitivity sensitive -
myraid vscan off default
myraid nbmand off default
myraid sharesmb off default
myraid refquota none default
myraid refreservation none default
myraid primarycache all local
myraid secondarycache all default
myraid usedbysnapshots 0 -
myraid usedbydataset 382G -
myraid usedbychildren 1.98M -
myraid usedbyrefreservation 0 -
myraid logbias latency local
myraid dedup off local
myraid mlslabel none default
myraid sync disabled local
myraid refcompressratio 1.05x -
myraid written 382G -
myraid logicalused 403G -
myraid logicalreferenced 403G -
myraid filesystem_limit none default
myraid snapshot_limit none default
myraid filesystem_count none default
myraid snapshot_count none default
myraid snapdev hidden default
myraid acltype off default
myraid context none default
myraid fscontext none default
myraid defcontext none default
myraid rootcontext none default
myraid relatime off default
myraid redundant_metadata all default
myraid overlay off default
[root@nas ~]# zpool get all
NAME PROPERTY VALUE SOURCE
myraid size 10.9T -
myraid capacity 3% -
myraid altroot - default
myraid health ONLINE -
myraid guid 1068639342092444414 default
myraid version - default
myraid bootfs - default
myraid delegation on default
myraid autoreplace off default
myraid cachefile - default
myraid failmode wait default
myraid listsnapshots off default
myraid autoexpand off default
myraid dedupditto 0 default
myraid dedupratio 1.00x -
myraid free 10.5T -
myraid allocated 382G -
myraid readonly off -
myraid ashift 0 default
myraid comment - default
myraid expandsize - -
myraid freeing 0 default
myraid fragmentation 1% -
myraid leaked 0 default
myraid feature@async_destroy enabled local
myraid feature@empty_bpobj enabled local
myraid feature@lz4_compress active local
myraid feature@spacemap_histogram active local
myraid feature@enabled_txg active local
myraid feature@hole_birth active local
myraid feature@extensible_dataset enabled local
myraid feature@embedded_data active local
myraid feature@bookmarks enabled local
myraid feature@filesystem_limits enabled local
myraid feature@large_blocks enabled local
[root@nas ~]# zdb | grep ashift
ashift: 12
ashift: 12
ashift: 12
ashift: 12
[root@nas ~]# lsblk -t -e 11,1
NAME ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED RQ-SIZE RA WSAME
sda 0 512 0 512 512 0 cfq 128 128 0B
+-sda1 0 512 0 512 512 0 cfq 128 128 0B
+-sda2 0 512 0 512 512 0 cfq 128 128 0B
+-sda3 0 512 0 512 512 0 cfq 128 128 0B
+-centos_nas-swap 0 512 0 512 512 0 128 128 0B
+-centos_nas-root 0 512 0 512 512 0 128 128 0B
+-centos_nas-home 0 512 0 512 512 0 128 128 0B
sdb 0 4096 0 4096 512 1 noop 128 128 0B
+-sdb1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdb9 0 4096 0 4096 512 1 noop 128 128 0B
sdc 0 4096 0 4096 512 1 noop 128 128 0B
+-sdc1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdc9 0 4096 0 4096 512 1 noop 128 128 0B
sdd 0 4096 0 4096 512 1 noop 128 128 0B
+-sdd1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdd9 0 4096 0 4096 512 1 noop 128 128 0B
sde 0 4096 0 4096 512 1 noop 128 128 0B
+-sde1 0 4096 0 4096 512 1 noop 128 128 0B
+-sde9 0 4096 0 4096 512 1 noop 128 128 0B
sdf 0 4096 0 4096 512 1 noop 128 128 0B
+-sdf1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdf9 0 4096 0 4096 512 1 noop 128 128 0B
sdg 0 4096 0 4096 512 1 noop 128 128 0B
+-sdg1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdg9 0 4096 0 4096 512 1 noop 128 128 0B
sdh 0 4096 0 4096 512 1 noop 128 128 0B
+-sdh1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdh9 0 4096 0 4096 512 1 noop 128 128 0B
sdi 0 4096 0 4096 512 1 noop 128 128 0B
+-sdi1 0 4096 0 4096 512 1 noop 128 128 0B
+-sdi9 0 4096 0 4096 512 1 noop 128 128 0B
我的问题是,当我第一次通过 10 Gbit/s 连接(DAC PC 到服务器)读取文件时,或者rsync
从池到服务器中的 SSD 使用时,我获得的速度刚好超过 100 Mbyte/s。如果我第二次读取同一个文件,通过 10 Gbit/s DAC 连接我获得 1.2 Gbyte/s,从池到 SSD 我获得 380 Mbyte/s。
我重新启动服务器并运行从池到 SSD 的测试读取:
[root@nas ~]# rsync -h --progress /myraid/testmovie.avi /home/samba/testmovie.avi
testmovie.avi
1.08G 100% 79.59MB/s 0:00:12 (xfer#1, to-check=0/1)
sent 1.08G bytes received 31 bytes 80.21M bytes/sec
total size is 1.08G speedup is 1.00
然后我在读取一次后执行相同的操作:
[root@nas ~]# rsync -h --progress /myraid/testmovie.avi /home/samba/testmovie.avi
testmovie.avi
1.08G 100% 394.54MB/s 0:00:02 (xfer#1, to-check=0/1)
sent 1.08G bytes received 31 bytes 433.13M bytes/sec
total size is 1.08G speedup is 1.00
有什么提示吗?第一次读取时我不应该获得四个驱动器的读取速度吗?
答案1
从理论上讲
在一个非常理论化的世界,从您的池配置(四个 vdev,每个都是双磁盘镜像)来看,您可以预期读取带宽相当于一个磁盘速度的八倍。这是因为:
- 在镜像 vdev 中,虚拟文件系统能够同时从两个磁盘读取不同的数据块
- 在多 vdev 池中,ZFS 会自动对数据进行条带化,这样它就可以同时从多个 vdev 读取数据
西部数据声称 3 TB Red 硬盘的读取速度可以超过 140 MB/s。这不会发生,至少不会一直发生。因此,我们假设您可以从其中一个硬盘获得 100 MB/s。当它们在您的池配置中组合时,您可以理论上获得高达 800 MB/s 的读取带宽。
欢迎来到真实的世界
现在让我明确一点:800 MB/s,这可能不会发生!这并不是因为 ZFS 欺骗了你,而是因为带宽计算是基于硬件不会妨碍你的假设。但事实确实如此,所以在实际工作负载下你无法获得理论速度。
当然,我知道您仍然希望通过将多个磁盘组合成一个更大的池来实现一些合理的性能改进。
然后发生了什么?
让我们看看你的测试:第一次复制大文件时,速度为 80 MB/s同步,那么第二次执行相同操作时,速度为 400 MB/s。差异的解释是自适应替换缓存(ARC)我相信你已经知道了。为了完整起见,我只会说这些。
ZFS ARC 提供了一种将经常访问的数据存储在 RAM 中的机制。
第一次从 ZFS 数据集读取文件时,ZFS 必须实际从磁盘读取数据;与此同时,它会填充其读取缓存。第二次读取同一个文件时,您会直接从 RAM 获取数据 - 并且您说您的系统上有足够的空间来容纳整个 1.08 GB 的文件。这意味着您再次使用 rsync (400 MB/s) 复制文件时看到的速度与 ZFS 池中的物理磁盘无关。我们可以将其视为您的固态硬盘 sda
驱动。准确地说,不是生的SSD 的写入速度:这是使用 rsync 从延迟极低、带宽极高的介质(RAM 内存)读取数据并写入 SSD 驱动器(延迟也极低)时获得的速度。另外,我认为我们应该考虑到 Linux 可能正在使用所有可用的 RAM 内存来缓存异步写入(此处做出假设!)到 SSD 驱动器分区。
因此,在这一点上,出现一个问题:如果您的 RAM 到 SSD 的写入速度似乎为 400 MB/s,那么当 ZFS 实际从磁盘读取时,为什么只有 80 MB/s?这比单个磁盘的速度还慢!显然,不能怪罪 SSD 本身,我们对 ZFS 池中所有这些驱动器的期望要高得多!
所以,说实话,我没有完整的答案。在考虑了我到目前为止所说的一切之后,我的部分回答你的问题是:
- 在我看来,带宽低是因为 I/O 活动较多,这意味着 rsync 实际上并不允许直接顺序读取大文件,而是生成大量 I/O,如果驱动器在大量 I/O 中存在延迟,这可能会严重影响流式传输性能。让我们记住,Western Digital Red 磁盘用于网络存储应用程序,这意味着它们旨在实现不错的带宽和良好的每 GB 价格比,而不是高 IOPS。当您从 RAM(低延迟媒体)执行完全相同的操作时,整体流媒体性能还不错。
- rsync 不是一个好方法基准测试您的 ZFS 池 - 或其他任何东西。如果您在 Google 中搜索rsync 性能你会看到它比普通文件复制慢的证据——我认为有充分的理由:速度不是你使用 rsync 的目的。我会寻找其他基准测试方法。即使只是
dd
或者cp
可能是顺序读/写测试的更好选择。你可以看看本文寻找一些灵感。 - 此外,我会尝试找出真实的单磁盘读取性能,在磁盘添加到 ZFS 池之前运行测试。销毁池(您将丢失数据:如有必要,请先备份!),在每个磁盘上运行测试,然后再次定义池并进行更多测试。然后,您可以根据观察到的实际速度应用数学,并再次对理论读取带宽,根据您的 ZFS 池配置(4 vdevs * 2 个磁盘镜像 = 单磁盘带宽 * 8)。
- 如果您在池中使用每个磁盘之前对其进行测试,您可能会发现一个或多个磁盘状况不佳。如果您刚刚购买了磁盘,请退回有问题的磁盘并要求更换。
- 如果您对每个磁盘运行测试并发现它们的性能一直很慢,那么您可能遇到了硬件相关的问题 - 配置、驱动程序支持或其他类似问题。
- 我会尝试不同的硬件配置(如果可能)并针对每个配置运行测试。使用单个镜像 vdev 池运行测试,然后尝试将更多 vdev 组合在一起。看看这是否能给你带来预期的结果。
总结:您需要有条不紊地找出瓶颈所在。不要假设它是 ZFS 本身;它可能不是。尝试不同的配置,并使用适合该工作的工具运行测试。
我不是基准测试或测试专家,所以我不会在这方面给你建议。互联网上有很多关于这个主题的精彩资料。我只是想谈谈 ZFS 特有的一些方面,希望能给你一个方向。