zl程序教程

您现在的位置是:首页 >  其他

当前栏目

关于NAS你必须知道的坑

2023-02-26 12:28:09 时间

NFS和脏页

问题

拥有大量 RAM 和大量处理能力的计算机可以在 RAM 中快速创建出许多的脏页(最终会被写入文件系统的数据)。当需要将这些脏页刷新到对应的文件系统(称为回写Writeback)时,NFS 可能会出现很多阻塞。 通过网络传输的数据吞吐量比写入 RAM 要小得多。试想一下,如果拥有10条车道的道路突然减少到2条车道会对道路交通带来何种影响。

人们可能认为这只会影响 NFS 的挂载,但是,允许的脏页数量是一个系统范围级的值。一旦达到此阈值,系统上的每个进程在尝试分配内存时都要去释放页面。如果只有几个脏页,那还好,但是如果有40GB的脏页,那么所有进程都会被阻塞很长时间。

(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>

处理方式

有多种方法可以解决此问题。它们的范围从仅影响进程和正在写入的文件,一直到影响所有进程和所有文件系统。

文件级别的影响

Direct I/O

打开文件进行写入时,使用 O_DIRECT 标志以完全绕过 Page Cache。这也可以通过使用 dd 和带有 oflag=direct 的选项将文件复制到 NFS 来实现。

消减 I/O

下一个选项是限制读取数据的速率以匹配 NFS 的写入速率。例如 使用 rsync 和选项 –bwlimit。

更加频繁的刷写脏页

如果有权重新编译源代码,请定期调用 fsync()。如果无法重新编译源代码,请定期运行以下命令:

ls -l /nfsmount/dir_containing_files

写入较小的文件

如果可能,请尝试将单个大文件分解为多个较小的文件。与每个文件相关联的脏页在关闭时会被刷出。这会导致刷新脏页的频率变大。

NFS挂载的影响

只使用同步IO

通常情况下,每个 I/O 在 NFS 客户端上异步地完成,这意味着应用写入到Page cache,然后 NFS 客户端延迟将数据发送到 NFS 服务器。每个 I/O 可以强制同步完成,这意味着在 NFS 客户端将数据发送到 NFS 服务器并且 NFS 服务器已确认接收数据之前,应用程序不会认为写入完成。在 NFS 客户端挂载时指定sync选项会强制所有写入都同步完成。但是,它也会严重降低 NFS 客户端的写入性能。

rsize/wsize (NFS客户端挂载项)

rsize/wsize 是每次网络读/写请求的最大字节数。根据工作负载类型和网络性能,增加这些值有可能增加吞吐量。默认的 rsize/wsize 由 NFS 客户端与 NFS 服务器协商。 如果工作负载是流式读取/写入的工作负载,将 rsize/wsize 增加到 1048576 (1MiB) 可以提高吞吐量性能。

操作系统级的影响

限制系统范围脏页的数量

从 RHEL 5.6(kernel 2.6.18-238)开始(包括 RHEL 6.0),可以调整参数 vm.dirty_background_bytes 和 vm.dirty_bytes。这些可调参数可提供更精细的粒度调整,尤其是在系统含有大量 RAM 的情况下。在 RHEL 5.6 之前,参数 vm.dirty_background_ratio 和 vm.dirty_ratio 可用于实现相同的目标。

  1. 将 vm.dirty_expire_centisecs (/proc/sys/vm/dirty_expire_centisecs) 从默认值 3000 调整为 500
  2. 将 vm.dirty_background_bytes (/proc/sys/vm/dirty_background_bytes) 限制为 500MiB
  3. 将 vm.dirty_bytes (/proc/sys/vm/dirty_bytes) 限制为不超过 1 GiB

确保 /proc/sys/vm/dirty_background_bytes 始终是比 /proc/sys/vm/dirty_bytes 更小的一个非零值。更改这些值会对吞吐量产生负面影响,同时提高延迟。要改变吞吐量和延迟之间的平衡,请稍微调整这些值并度量其影响,特别是dirty_bytes.

可以通过以下命令来观察脏页和回写的行为:

$ watch -d -n 1 cat /proc/meminfo

文档/sysctl/vm.txt:

dirty_expire_centisecs  This tunable is used to define when dirty data is old enough to be eligible for writeout by the kernel flusher threads.  It is expressed in 100'ths of a second.  Data which has been dirty in-memory for longer than this interval will be written out next time a flusher thread wakes up.  dirty_bytes  Contains the amount of dirty memory at which a process generating disk writes will itself start writeback.  Note: dirty_bytes is the counterpart of dirty_ratio. Only one of them may be specified at a time. When one sysctl is written it is immediately taken into account to evaluate the dirty memory limits and the other appears as 0 when read.  Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any value lower than this limit will be ignored and the old configuration will be retained.  dirty_ratio  Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which a process which is generating disk writes will itself start writing out dirty data.  The total available memory is not equal to total system memory.  dirty_background_bytes  Contains the amount of dirty memory at which the background kernel flusher threads will start writeback.  Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only one of them may be specified at a time. When one sysctl is written it is immediately taken into account to evaluate the dirty memory limits and the other appears as 0 when read.  dirty_background_ratio  Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which the background kernel flusher threads will start writing out dirty data.  The total available memory is not equal to total system memory.

Environment-wide impact

提高网络性能(iperf 基准测试)

网络性能的好坏对 NFS 有着重大影响。通过运行 iperf 检查网络是否运行良好。它可用于测量 NFS 客户端和另一个系统之间的网络吞吐量,比如 NFS 服务器。

接收端:

$ iperf -s -f M

发送端:

$ iperf -c RECEIVER-IP -f M -t 60

进行几次迭代并尝试使每个测试运行至少 60 秒。同时还应该了解基线网络吞吐量。NFS 的执行速度不会比基线快。

小结

整理(翻译)此篇的缘由是,线上碰到了好几次由于备份导致的主机夯死案例,原因有三:

  1. 调大了segsize,PostgreSQL默认是1G,意味着单个文件更大了,Dirty Pages associated with each file will be flushed when it is closed. ,而越大的文件其所占的脏页只有被flush后才会释放,所以这也是拆分为多个小文件的原因
  2. 很多个上TB的大库,同时进行备份,没有错开,进一步加剧了内存压力
  3. swappness设置为了0,在kernel 3.5-rc1以后的版本,swappiness如果等于0的话,哪怕匿名页占据的内存很大,swap分区还有很多的剩余空间,除非恶劣情况发生,都不会交换匿名页

后续使用dd进行实测,开多个进程进行dd往NAS写入,同时NAS采用默认的异步模式,能够稳定复现,将主机打死。

所以,我们可以:

  1. 调整NAS的挂载方式,指定async/sync,正如前文所述,对于异步挂载,客户端下发的写数据会先缓存在内存中,达到一定大小或者其他条件,再一起发往服务端。而同步挂载,每次下发的写数据马上发到服务端,当然代价是吞吐量变低。
  2. 在同城或者备库做备份,非exclusive的备份的是可以在备机做的
  3. 调整page cache的写出策略,linux默认值都太保守了
  4. scale up,提升网络IO性能
  5. 定期监控NAS的脏页数量

关于NAS你必须知道的坑


本站部分内容转载自网络,版权属于原作者所有,如有异议请联系QQ153890879修改或删除,谢谢!
转载请注明原文链接:关于NAS你必须知道的坑

你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:

1、点击这里立即申请成为腾讯云VIP客户

2、点击这里立即注册成为天翼云VIP客户

3、点击这里立即申请成为华为云VIP客户

4、点击这里立享阿里云产品终身VIP优惠价

喜欢 (0)
[[email protected]]
分享 (0)