我在使用 MongoDB(我相信它是 mmapped DB)和 ZFSonlinux 时遇到了很大的性能问题。
我们的 Mongodb 几乎只进行写入。在没有 ZFS 的副本上,当应用程序每 30 秒写入数据库一次,磁盘完全处于繁忙状态,持续约 5 秒,中间没有磁盘活动,因此我将其作为比较的基准行为。
在具有 ZFS 的副本上,磁盘完全处于繁忙状态全部时间,副本很难与 MongoDB 主数据库保持同步。我已在所有副本上启用 lz4 压缩,节省了大量空间,因此应该会有更少的数据到达磁盘
因此在这些 ZFS 服务器上,我首先使用默认的 recordsize=128k。然后我擦除数据并在重新同步 Mongo 数据之前设置 recordsize=8k。然后我再次擦除并尝试 recordsize=1k。我还尝试了 recordsize=8k 而不使用校验和
尽管如此,它并没有解决任何问题,磁盘始终保持 100% 繁忙状态。只有一次,在一台服务器上,recordsize=8k,磁盘的繁忙程度比任何非 ZFS 副本都要低得多,但在尝试不同的设置,并使用 recordsize=8k 再次尝试后,磁盘仍为 100%,我看不到之前的良好行为,在任何其他副本上也看不到它。
此外,应该几乎只有写入,但在不同设置下的所有副本上看到,磁盘非常繁忙,读取率为 75%,写入率为 25%
(注意,我相信 MongoDB 是 mmapped DB。有人告诉我在 AIO 模式下尝试 MongoDB,但我不知道如何设置它,并且在另一台运行 MySQL InnoDB 的服务器上,我意识到 ZFSonLinux 无论如何都不支持 AIO。)
我的服务器是 CentOS 6.5 内核 2.6.32-431.5.1.el6.x86_64。spl-0.6.2-1.el6.x86_64 zfs-0.6.2-1.el6.x86_64
#PROD 13:44:55 root@rum-mongo-backup-1:~: zfs list
NAME USED AVAIL REFER MOUNTPOINT
zfs 216G 1.56T 32K /zfs
zfs/mongo_data-rum_a 49.5G 1.56T 49.5G /zfs/mongo_data-rum_a
zfs/mongo_data-rum_old 166G 1.56T 166G /zfs/mongo_data-rum_old
#PROD 13:45:20 root@rum-mongo-backup-1:~: zfs list -t snapshot
no datasets available
#PROD 13:45:29 root@rum-mongo-backup-1:~: zfs list -o atime,devices,compression,copies,dedup,mountpoint,recordsize,casesensitivity,xattr,checksum
ATIME DEVICES COMPRESS COPIES DEDUP MOUNTPOINT RECSIZE CASE XATTR CHECKSUM
off on lz4 1 off /zfs 128K sensitive sa off
off on lz4 1 off /zfs/mongo_data-rum_a 8K sensitive sa off
off on lz4 1 off /zfs/mongo_data-rum_old 8K sensitive sa off
那里可能发生了什么?我应该查看什么才能确定 ZFS 正在做什么或哪个设置不正确?
EDIT1:
硬件:这些是租用的服务器,Xeon 1230 或 1240 上有 8 个 vcore,16 或 32GB RAM,zfs_arc_max=2147483648
使用 HP 硬件 RAID1。因此 ZFS zpool 位于 /dev/sda2 上,并且不知道存在底层 RAID1。即使对于 ZFS 来说这是一个次优设置,我仍然不明白为什么磁盘在读取时会阻塞,而 DB 只进行写入。
我理解很多原因,我们不需要在这里再次阐述,这对 ZFS 来说很糟糕,而且我很快就会有一个 JBOD/NORAID 服务器,我可以使用 ZFS 自己的 RAID1 在 sda2 分区上实现进行相同的测试,使用 /、/boot 和 swap 分区使用 mdadm 执行软件 RAID1。
答案1
这听起来可能有点疯狂的,但我支持另一个受益于 ZFS 卷管理属性但在本机 ZFS 文件系统上表现不佳的应用程序。
我的解决方案?!?
启用 XFS顶部的ZFS 卷。
为什么?!?
因为 XFS 性能良好,并且消除了我在使用原生 ZFS 时遇到的特定于应用程序的问题。ZFS zvols 允许我精简配置卷、添加压缩、启用快照并高效利用存储池。对我的应用程序来说更重要的是,zvol 的 ARC 缓存减少了磁盘上的 I/O 负载。
看看你是否能理解这个输出:
# zpool status
pool: vol0
state: ONLINE
scan: scrub repaired 0 in 0h3m with 0 errors on Sun Mar 2 12:09:15 2014
config:
NAME STATE READ WRITE CKSUM
vol0 ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
scsi-SATA_OWC_Mercury_AccOW140128AS1243223 ONLINE 0 0 0
scsi-SATA_OWC_Mercury_AccOW140128AS1243264 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
scsi-SATA_OWC_Mercury_AccOW140128AS1243226 ONLINE 0 0 0
scsi-SATA_OWC_Mercury_AccOW140128AS1243185 ONLINE 0 0 0
ZFS zvol,创建方式:(zfs create -o volblocksize=128K -s -V 800G vol0/pprovol
请注意,已启用自动快照)
# zfs get all vol0/pprovol
NAME PROPERTY VALUE SOURCE
vol0/pprovol type volume -
vol0/pprovol creation Wed Feb 12 14:40 2014 -
vol0/pprovol used 273G -
vol0/pprovol available 155G -
vol0/pprovol referenced 146G -
vol0/pprovol compressratio 3.68x -
vol0/pprovol reservation none default
vol0/pprovol volsize 900G local
vol0/pprovol volblocksize 128K -
vol0/pprovol checksum on default
vol0/pprovol compression lz4 inherited from vol0
vol0/pprovol readonly off default
vol0/pprovol copies 1 default
vol0/pprovol refreservation none default
vol0/pprovol primarycache all default
vol0/pprovol secondarycache all default
vol0/pprovol usedbysnapshots 127G -
vol0/pprovol usedbydataset 146G -
vol0/pprovol usedbychildren 0 -
vol0/pprovol usedbyrefreservation 0 -
vol0/pprovol logbias latency default
vol0/pprovol dedup off default
vol0/pprovol mlslabel none default
vol0/pprovol sync standard default
vol0/pprovol refcompressratio 4.20x -
vol0/pprovol written 219M -
vol0/pprovol snapdev hidden default
vol0/pprovol com.sun:auto-snapshot true local
ZFS zvol 块设备的属性。900GB 卷(磁盘上的实际大小为 143GB):
# fdisk -l /dev/zd0
Disk /dev/zd0: 966.4 GB, 966367641600 bytes
3 heads, 18 sectors/track, 34952533 cylinders
Units = cylinders of 54 * 512 = 27648 bytes
Sector size (logical/physical): 512 bytes / 131072 bytes
I/O size (minimum/optimal): 131072 bytes / 131072 bytes
Disk identifier: 0x48811e83
Device Boot Start End Blocks Id System
/dev/zd0p1 38 34952534 943717376 83 Linux
ZFS 块设备上的 XFS 信息:
# xfs_info /dev/zd0p1
meta-data=/dev/zd0p1 isize=256 agcount=32, agsize=7372768 blks
= sectsz=4096 attr=2, projid32bit=0
data = bsize=4096 blocks=235928576, imaxpct=25
= sunit=32 swidth=32 blks
naming =version 2 bsize=4096 ascii-ci=0
log =internal bsize=4096 blocks=65536, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
XFS 挂载选项:
# mount
/dev/zd0p1 on /ppro type xfs (rw,noatime,logbufs=8,logbsize=256k,nobarrier)
注意:在某些情况下,我也会在 HP Smart Array 硬件 RAID 上执行此操作。
池创建如下:
zpool create -o ashift=12 -f vol1 wwn-0x600508b1001ce908732af63b45a75a6b
结果如下:
# zpool status -v
pool: vol1
state: ONLINE
scan: scrub repaired 0 in 0h14m with 0 errors on Wed Feb 26 05:53:51 2014
config:
NAME STATE READ WRITE CKSUM
vol1 ONLINE 0 0 0
wwn-0x600508b1001ce908732af63b45a75a6b ONLINE 0 0 0
答案2
首先,值得一提的是,Linux 上的 MongoDB 不支持 ZFS 文件系统 - 推荐的文件系统是 ext4 或 XFS。因为 Linux 上甚至没有检查 ZFS(请参阅服务器-13223例如)它不会使用稀疏文件,而是尝试预分配(用零填充),这将意味着在奶牛文件系统。在修复此问题之前,添加新数据文件将对 ZFS 造成巨大的性能影响(您将尝试频繁执行写入操作)。虽然您没有这样做,但性能应该会有所改善,但如果您添加数据的速度足够快,您可能永远无法在分配命中之间恢复。
此外,ZFS 不支持直接 IO,因此您将多次将数据复制到内存中(mmap、ARC 等)——我怀疑这是您读取的来源,但我必须进行测试才能确定。上次我看到在 Linux 上使用 MongoDB/ZFS 进行测试时,性能很差,即使在 SSD 上使用 ARC 也是如此——ext4 和 XFS 的速度要快得多。ZFS 将来可能适用于 Linux 上的 MongoDB 生产使用,但现在还没有准备好。
答案3
我们研究了在 ZFS 上运行 Mongo,发现这篇文章提出了关于性能的重大担忧。两年后,我们想看看使用 WiredTiger 而不是 mmap 的新版 Mongo 在最新版 Ubuntu Xenial 附带的现在正式支持的 ZFS 上的表现如何。
总而言之,很明显 ZFS 的性能不如 EXT4 或 XFS,但是性能差距并不大,尤其是当您考虑到 ZFS 提供的额外功能时。
我做了一个博客文章关于我们的发现和方法。希望您觉得有用!
答案4
您的 ZFS 设置是什么,特别是 primarycache、logbias 和 sync?
确保 primarycache=all,logbias=throughput。
sync=disabled 会显著加快写入速度,但如果发生崩溃,可能会丢失最多 5 秒的最近写入数据。鉴于您描述的症状,您可能还想禁用 ZFS 预取。
我根据前段时间关于跑步的演讲写了一篇文章ZFS 上的 MySQL你可能会觉得有帮助。