文章的翻译是在课程开始前夕准备的
定期地,在这里和那里,会出现关于 Gluster 关于内核调整的建议以及是否需要这样做的问题。
这种需求很少出现。 在大多数工作负载上,内核的性能都非常好。 虽然有一个缺点。 从历史上看,如果有机会,Linux 内核一直愿意消耗大量内存,包括将缓存作为提高性能的主要方式。
在大多数情况下,这工作正常,但在重负载下可能会导致问题。
我们对 CAD、EDA 等内存密集型系统有很多经验,这些系统在重负载下开始变慢。 有时我们会在 Gluster 中遇到问题。 仔细观察了多天的内存使用和磁盘延迟,我们得到了它们的过载、巨大的iowait、内核错误(kernel oops)、冻结等。
本文是在各种情况下进行的许多调优实验的结果。 由于这些参数,不仅整体响应能力有所提高,而且集群也显着稳定。
说到内存调优,首先要看的是虚拟内存子系统(VM,virtual memory),它有大量的选项,会让你一头雾水。
虚拟机交换性
参数 vm.swappiness
确定内核与 RAM 相比使用多少交换(swap,paging)。 它在源代码中也被定义为“窃取映射内存的倾向”。 高 swappiness 意味着内核将更倾向于交换映射页面。 低 swappiness 值意味着相反:内核将从内存中减少分页。 换句话说,价值越高 vm.swappiness
,系统将使用交换越多。
大量使用交换是不可取的,因为巨大的数据块被加载和卸载到 RAM 中。 许多人认为 swapiness 值应该很大,但根据我的经验,将其设置为“0”会带来更好的性能。
你可以在这里阅读更多 -
但是,同样,应谨慎应用这些设置,并且只能在测试特定应用程序之后使用。 对于高负载流式应用程序,此参数应设置为“0”。 当更改为“0”时,系统响应能力会提高。
vm.vfs_cache_压
此设置控制内核用于缓存目录和 inode 对象(dentry 和 inode)所消耗的内存。
默认值为 100,内核将尝试在“公平”的基础上将 dentry 和 inode 缓存释放给 pagecache 和 swapcache。 降低 vfs_cache_pressure 会导致内核保留 dentry 和 inode 缓存。 当值为“0”时,由于内存压力,内核永远不会刷新dentry和inode缓存,这很容易导致内存不足的错误。 将 vfs_cache_pressure 增加到 100 以上会导致内核优先刷新 dentry 和 inode。
使用 GlusterFS 时,由于 inode/dentry 缓存,许多拥有大量数据和许多小文件的用户可以轻松使用服务器上的大量 RAM,这可能导致性能下降,因为内核必须处理系统上的数据结构具有 40 GB 的内存。 将此值设置为 100 以上已帮助许多用户实现更公平的缓存和改进的内核响应能力。
vm.dirty_background_ratio 和 vm.dirty_ratio
第一个参数 (vm.dirty_background_ratio
) 确定脏页内存的百分比,达到后有必要开始在后台将脏页刷新到磁盘。 在达到此百分比之前,不会将任何页面刷新到磁盘。 当重置开始时,它会在后台运行而不会中断正在运行的进程。
第二个参数(vm.dirty_ratio
) 定义在强制闪存开始之前脏页可以占用的内存百分比。 一旦达到这个阈值,所有进程都变成同步的(阻塞的)并且不允许继续,直到它们请求的 I/O 实际完成并且数据在磁盘上。 对于繁重的 I/O,这会导致问题,因为没有数据缓存,并且所有执行 I/O 的进程都被阻塞以等待 I/O。 导致大量hung进程,负载高,系统不稳定,性能差。
减少这些设置会导致数据更频繁地刷新到磁盘而不是存储在 RAM 中。 这可以帮助内存密集型系统,在这些系统中通常会将 45-90 GB 页面缓存刷新到磁盘,从而导致前端应用程序出现巨大延迟,从而降低整体响应性和交互性。
“1” > /proc/sys/vm/pagecache
页面缓存是存储文件和可执行程序数据的缓存,也就是说,这些是具有文件或块设备实际内容的页面。 此缓存用于减少磁盘读取次数。 值“1”表示 1% 的 RAM 用于缓存,从磁盘读取的次数将多于从 RAM 读取的次数。 没有必要更改此设置,但如果您对控制页面缓存偏执狂,则可以使用它。
“截止日期” > /sys/block/sdc/queue/scheduler
I/O 调度器是一个处理读写队列的 Linux 内核组件。 从理论上讲,智能 RAID 控制器最好使用“noop”,因为 Linux 对磁盘的物理几何结构一无所知,因此让熟悉磁盘几何结构的控制器尽可能快地处理请求会更有效率。可能的。 但看起来“截止日期”提高了性能。 您可以在 Linux 内核源代码文档中阅读有关调度程序的更多信息: linux/Documentation/block/*osched.txt
. 而且我还看到在混合操作(许多写操作)期间读取吞吐量有所增加。
“256” > /sys/block/sdc/queue/nr_requests
缓冲区中的 I/O 请求在传递给调度程序之前的数量。 某些控制器的内部队列大小 (queue_depth) 大于 I/O 调度程序的 nr_requests,因此 I/O 调度程序几乎没有机会正确排列请求的优先级和合并请求。 对于 deadline 和 CFQ 调度器,当 nr_requests 是控制器内部队列的 2 倍时会更好。 合并和重新排序请求有助于调度程序在重负载下响应更快。
echo "16" > /proc/sys/vm/page-cluster
page-cluster 参数控制一次写入交换的页数。 在上面的示例中,根据 16 KB 的 RAID 条带大小将值设置为“64”。 swappiness = 0 没有意义,但是如果您将 swappiness 设置为 10 或 20,那么在 RAID 条带大小为 64K 时使用此值将对您有所帮助。
区块开发 --setra 4096 /dev/<
开发名称>
(-sdb、hdc 或 dev_mapper)
许多 RAID 控制器的默认块设备设置通常会导致糟糕的性能。 添加上述选项可设置 4096 * 512 字节扇区的预读。 至少,对于流式操作,通过在内核准备 I/O 期间使用预读填充片上磁盘缓存来提高速度。 缓存可以包含将在下一次读取时请求的数据。 过多的预取可能会导致大文件的随机 I/O 失效,如果它耗尽了可能有用的磁盘时间或将数据加载到缓存之外。
以下是文件系统级别的更多建议。 但他们还没有经过测试。 确保您的文件系统知道条带的大小和阵列中的磁盘数量。 例如,这是一个 5K 条带 raid64 阵列,有六个磁盘(实际上是五个,因为一个磁盘用于奇偶校验)。 这些建议基于理论假设,并由 RAID 专家从各种博客/文章中汇编而成。
-> ext4 fs, 5 disks, 64K stripe, units in 4K blocks
mkfs -text4 -E stride=$((64/4))
-> xfs, 5 disks, 64K stripe, units in 512-byte sectors
mkfs -txfs -d sunit=$((64*2)) -d swidth=$((5*64*2))
对于大文件,请考虑增加上面列出的条带大小。
警告! 对于某些类型的应用程序,上面描述的一切都是非常主观的。 未经用户事先对相关应用程序进行测试,本文不保证任何改进。 仅当有必要提高系统的整体响应能力或解决当前问题时才应使用它。
其他材料:
dom.as/2008/02/05/linux-io-调度程序 www.nextre.it/oracledocs/oraclemyths.html lkml.org/lkml/2006/11/15/40 isterd77.blogspot.com/2007/11/3ware-hardware-raid-vs-linux-software.html
阅读更多
来源: habr.com