游戏迷提供最新游戏下载和手游攻略!

Linux虚拟内存参数配置

发布时间:2024-10-06浏览:71

6 月1 日10:30:21audit1kernel:swapper: 页面分配失败。 order:1,mode:0x20 Jun 1 10:30:21 Audit1 kernel: Pid: 0,comm:交换器Tainted: G -------------- T 2.6.32- 431.20.3.el6 .x86_64 #1 Jun 1 10:303 336021 审核1 内核: 六月1 10:30:21audit1kernel:[]? __alloc_pages_nodemask+0x74a/0x8d0 Jun 1 10:30:21audit1内核:[]? kmem_getpages+0x62/0x170 六月1 日10:30:21 Audit1 kernel: [] ? Fallback_alloc+0x1ba/0x270 六月1 日10:30:21audit1 kernel: [] ? ____cache_alloc_node+0x99/0x160 六月1 日10:30:21audit1 kernel: [] ? kmem_cache_alloc+0x11b/0x190 6 月1 日10:303336 021 Audit1 kernel: [] ? sk_prot_alloc+0x48/0x1c0 6月1日10:30:21audit1kernel:[]? sk_clone+0x22 /0x2e0 Jun 1 10:30:21audit1kernel:[]? inet_csk_clone+0x16/0xd0 6月1日10:30:21audit1kernel:[]? tcp_create_openreq_child+0x23/0x470

监控中发现messages日志中出现了失败错误信息,并且发现了上述内存堆栈错误。

2.虚拟内存简介

1.虚拟内存

毫无疑问,虚拟内存绝对是操作系统中最重要的概念之一。我想这主要是由于内存的重要“战略地位”。 CPU速度太快,但容量小,功能单一。其他I/O 硬件支持各种奇特的功能,但与CPU 相比速度太慢。因此需要润滑剂作为它们之间的缓冲区,这就是内存发挥作用的地方。

在现代操作系统中,多任务处理是标准的。多任务并行大大提高了CPU利用率,但也导致了多个进程之间内存操作的冲突。虚拟内存的概念就是为了解决这个问题而提出的。

上图是对虚拟内存最简单、最直观的解释。

操作系统有一块物理内存(中间部分)和两个进程(实际上更多)P1和P2。操作系统分别偷偷告诉P1和P2,我的整个内存都是你的,随意使用,爱护它。但事实上,操作系统只是为他们分了一大块蛋糕而已。这些记忆据说是给予P1和P2的,但实际上只是给予了一个序列号。只有当P1 和P2 实际开始使用这些内存时,系统才会开始移动并将该过程的各个块拼凑在一起。 P2以为自己正在使用A内存,但实际上它已经被系统悄悄重定向到了真正的B内存。即使P1 和P2 共享C 内存,他们也不知道。

操作系统这种欺骗进程的方法就是虚拟内存。对于P1、P2这样的进程,它们都认为自己占用了整个内存,它们不知道也不需要关心它们使用的是物理内存的哪个地址。

2. 分页和页表

虚拟内存是操作系统中的一个概念。对于操作系统来说,虚拟内存就是一张对照表。当P1获取内存A中的数据时,应该去物理内存的地址A,而要找到内存B中的数据,则应该去寻找。转到物理内存的C地址。

我们知道系统中的基本单位是Byte。如果将虚拟内存的每个Byte映射到物理内存的地址,则每个条目至少需要8个字节(32位虚拟地址-32位物理地址)。在4G内存的情况下,需要32GB的空间来存储比较表,这样表就太大了,甚至无法容纳真实的物理地址,所以操作系统引入了页的概念。

系统启动时,操作系统将整个物理内存以4K为单位划分为页。以后分配内存时,单位是页,因此虚拟内存页对应物理内存页的映射表大大减少。 4G内存只需要8M映射表。有些进程不使用虚拟内存。不需要保存映射关系,而且Linux还针对大内存设计了多级页表,可以提前一页,减少内存消耗。操作系统虚拟内存到物理内存的映射表称为页表。

3. 内存寻址与分配

我们知道,通过虚拟内存机制,每个进程都认为自己占用了所有的内存。当进程访问内存时,操作系统将进程提供的虚拟内存地址转换为物理地址,然后在对应的物理地址处获取数据。 CPU中有一个硬件,就是内存管理单元MMU(Memory Management Unit),专门用来翻译虚拟内存地址的。 CPU还为页表寻址设置了缓存策略。由于程序的局部性,其缓存命中率可以达到98%。

上面的情况就是页表内存中虚拟地址到物理地址的映射。如果进程访问的物理地址尚未分配,系统将产生页错误中断。在中断处理过程中,系统切换到内核态并使用进程虚拟地址。分配物理地址。

4. 区域

内存管理的相关逻辑是基于zone的。这里zone的意思是指内存的分区管理。 Linux将内存划分为多个区域,主要是直接存取区(DMA)、普通区(Normal)和高端内存区(HighMemory)。由于硬件结构因素,内核对不同区域内存的访问会在寻址和效率上存在差异。如果是NUMA架构,不同CPU管理的内存也是在不同的zone。

5.NUMA

在NUMA中,虽然内存是直接在CPU上访问的,但是内存是均匀分布在每个CPU上的。只有CPU访问本身直接访问内存对应的物理地址时,才会有较短的响应时间(以下简称Local Access)。如果需要访问附加在其他CPU上的内存数据,则需要通过互连通道来访问,响应时间会比以前慢(以下简称远程访问)。 NUMA(非统一内存访问)因此得名。

3. 分析

1.Red Hat官方解释(Root Cause):

在RHEL 6.4 之前,kswapd 不会尝试释放连续页面。当系统中没有其他碎片整理内存时,这可能会导致GFP_ATOMIC 分配请求重复失败。使用RHEL 6.4 及更高版本时,kswapd 将在必要时压缩(碎片整理)可用内存。

请注意,分配失败仍然可能发生。例如,当出现大量GFP_ATOMIC 分配时,kswapd 可能无法跟上。然而,这些分配最终应该会成功。

2. 回复危险信号电子邮件

建议设置以下内核参数:

1) vm.min_free_kbytes

系统默认:

[root@localhost ~]# cat /proc/sys/vm/min_free_kbytes 45056 [root@node1 log]# sysctl -a |grep vm.min vm.min_free_kbytes=45056

推荐设置为:

vm.min_free_kbytes=450560

即增大该值的设置。

2) vm.zone_reclaim_mode

系统默认为0:

[root@localhost ~]# sysctl -a |grep vm.zone_reclaim_mode vm.zone_reclaim_mode=0

建议在/etc/sysctl.conf 文件中设置vm.zone_reclaim_mode=1。

详情如下:

#vim /etc/sysctl.conf #打开文件,追加或修改以下设置(其他参数不变); vm.min_free_kbytes=450560 vm.zone_reclaim_mode=1

设置完成后,保存退出。

写入该文件的参数可以通过执行sysctl -p立即生效。下次重新启动时将读取此文件中的设置。

3.虚拟内存相关参数介绍

3.1.vm.swappiness

控制换出的运行时内存的相对权重。 swappiness参数值可以设置在0到100之间。较低的参数值将导致内核尽可能少地使用交换空间,较高的参数值将导致内核使用更多的交换空间。默认值为60(参考网络信息:当剩余物理内存小于40%(40=100-60)时,交换空间开始使用)。对于大多数操作系统,设置为100 可能会影响整体性能,而设置为较低的值(甚至0)可能会减少响应延迟。

swappiness值的大小与如何使用swap分区有很大关系。以前,建议将vm.swainess 设置为0,这意味着“除非出现内存效益,否则不要交换内存”。这个值的含义直到Linux内核3.5-rcl版本发布才改变。此更改已应用于其他发行版,包括RedHat Enterprise 内核2.6.32-303。更改后,0 表示“在任何情况下都不要交换”。所以现在建议将该值设置为1。当swappiness=100时,表示主动使用交换分区,及时将内存中的数据移动到交换空间。

推荐值:vm.swappiness=10

3.2.vm.min_free_kbytes

用于强制Linux VM 保留最小千字节数。 VM 使用此数字来计算系统中每个低内存区域的水印[WMARK_MIN] 值。每个lowmem 区域都会获得与其大小成比例的保留空闲页面数量。需要一些最小内存来满足PF_MEMALLOC 分配;如果该值设置为小于1024KB,系统将被损坏,并且在重负载下容易出现死锁。设置得太高会立即让你的机器OOM。

该参数本身决定系统中每个区域的watermark[min] 值。然后内核根据min的大小和每个区域的内存大小计算每个区域的低水位和高水位值。

从上面的解释来看,主要有两点:

1. 表示系统保留的最小可用内存量。

2.用于计算影响内存回收的三个参数watermark[min/low/high]

当系统的空闲内存低于watermark[low]时,内核线程kswapd开始启动进行内存回收,直到zone中的空闲内存量达到watermark[high]时停止回收。

如果上层申请内存过快,导致空闲内存下降到watermark[min],内核会进行直接回收(direct reclaim),即直接在应用程序的进程上下文中进行回收,然后使用回收的空闲页面。为了满足内存请求,实际上会阻塞应用程序,带来一定的响应延迟,并可能触发系统OOM。这是因为watermark[min]以下的内存属于系统自行保留的内存,用于特殊用途,所以在用户态下不会被普通应用程序使用。

三种水印的计算方法:

watermark[min]=min_free_kbytes 可以转换为页单位,假设为min_free_pages。水印[低]=水印[最小值] * 5/4 水印[高]=水印[最小值] * 3/2

定义百分比值。当脏数据占总内存的百分比时,脏数据的写出会在后台开始(通过pdflush)。默认值为10。对于数据库工作负载,红帽建议使用较低的值3。

min_free_kbytes 设置得太高会导致系统挂起,特别是在i386 arch 中,使用少于总内存的5% 可以避免它,因此选择%5 的可用内存或总内存的2%。

推荐值:vm.min_free_kbytes=内存值* 2%(上限5G)

3.3.vm.zone_reclaim_mode

zone_reclaim_mode模式是在2.6后期版本中添加到内核中的模式。它可用于管理当内存耗尽时是否从内存区域(zone)内回收内存或从其他区域回收内存的选项。

申请内存时,如果内核在当前zone中没有足够的可用内存,则会根据zone_reclaim_mode的设置来决定是从下一个zone中寻找空闲内存还是在zone内回收内存。

当这个值为0时,表示可以从下一个zone中找到可用内存,如果不为0,则表示在本地回收。

默认情况下,zone_reclaim 模式处于关闭状态。这在很多应用场景下可以提高效率,比如文件服务器,或者依赖内存中大量缓存的应用场景。

如果您确定应用场景需要的内存多于缓存,并且希望避免跨NUMA节点访问内存而导致性能下降,则可以开启zone_reclaim模式。

这时,页面分配器会优先分配容易回收的可回收内存(主要是当前未使用的页面缓存页面),然后再回收其他内存。

(如果读写量大,应该关闭,命中率低,因为缓存意义不大。

目前mongoDB官方文档建议关闭NUMA并关闭vm.zone_reclaim_mode。 )

在本地回收模式下开启回写可能会触发其他内存节点上的大量脏数据回写处理。 (首次打开会导致脏数据回写,操作时间需与应用协商,建议重启服务);

如果内存区域满了,脏数据的写回也会影响进程的处理速度,形成处理瓶颈。 (进程所在CPU可用内存减少,直接导致脏数据回写频率增加,回写的影响也加大。缓存回写肯定对读有短期影响以及缓存的写入性能。)

这会降低与内存节点关联的进程的性能,因为这些进程不再能够使用其他节点上的内存。但节点之间的隔离性会增加,其他节点上运行的相关进程的性能不会因为另一个节点上的内存回收而下降。

推荐值:vm.zone_reclaim_mode=1

(当内存分配不足且内存需求较多时,建议关闭,以加快缓存回收速度!)

3.4.vm.dirty_ratio

是可以填充脏数据的系统内存的绝对最大量,以系统可用内存的百分比表示。当系统达到这一点时,所有脏数据都必须提交到磁盘,并且所有新的I/O 块都将被阻塞。直到脏数据写入磁盘。

这通常是长时间I/O 停顿的原因,但它也是一种保护机制,以确保内存中不会有太多脏数据。

指示在开始将数据写入磁盘之前,写入缓冲区使用了多少系统内存。增加它只会使用更多的系统内存用于磁盘写缓冲,可以大大提高系统的写性能。但是,当您需要持续不断的书写情况时,您应该降低该值。

推荐值:vm.dirty_ratio=30(保持默认)

3.5.vm.dirty_background_ratio

开始回写的内存脏数据上限。以系统空闲内存的百分比表示,脏数据稍后会写入磁盘,pdflush/flush/kdmflush等后台进程稍后会清理脏数据。

控制文件系统的pdflush进程,何时刷新磁盘,脏数据是否达到系统空闲内存的百分比,pdflush开始将内存中的内容与文件系统同步。例如,当内存中的文件被修改时,pdflush 负责将其写回硬盘。每当内存中的垃圾页(脏页)数量超过10%时,pdflush就会将这些页备份回硬盘。增加的系统内存将更多地用于磁盘写缓冲,这也可以大大提高系统的写性能。但是,当您需要持续、持续的写入活动时,您应该降低其值:

推荐值:vm.dirty_background_ratio=10

场景1:减少缓存您可以为您想要执行的操作设置适当的值。在某些情况下,我们有快速磁盘子系统,它们有自己的电池支持的NVRAM 缓存,将数据放在操作系统级别是相对危险的。所以我们希望系统能够更及时地将数据写入磁盘。可以将以下两行添加到/etc/sysctl.conf中,并执行'sysctl -p'vm.dirty_background_ratio=5vm.dirty_ratio=10。这是虚拟机的典型应用。不建议设置为0,毕竟一些后台IO可以提高一些程序的性能。

场景二:添加Cache 在某些场景下添加Cache是有好处的。例如,如果数据不重要,丢失也没关系,还有程序会重复读写文件。通过允许更多缓存,您可以在内存中读写更多内容,从而提高速度。 vm.dirty_background_ratio=50vm.dirty_ratio=80 有时会增加vm.dirty_expire_centisecs的值以允许脏数据停留更长时间。

场景3:增加和减少的混合有时系统需要应对数据的突然激增,这可能会减慢磁盘速度。 (比如每小时一开始的批量操作等)这时候就需要让更多的脏数据存放在内存中,让后台进程慢慢地将数据异步写入磁盘。 vm.dirty_background_ratio=5vm.dirty_ratio=80 此时后台进程在脏数据达到5%时开始异步清理,但在80%之前系统不会强制同步写盘。这使得IO更加流畅。可以从/proc/vmstat、/proc/meminfo、/proc/sys/vm获取更多信息来进行调整。

参考

红帽官方网站:配置系统内存容量https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuration_tools-configuring_system_memory_capacity#sect-Red_Hat_Enterprise_Linux-Perform ance_Tuning_Guide -Configuring_system_memory_capacity-Virtual_Memory_parameters

用户评论

非想

我也是在搞 Linux 内存优化,这个参数配置真的挺难理解啊。我之前一直跟着教程调,感觉效果不明显,后来发现文档里解释得并不清楚,还是要多看点资料才行。

    有8位网友表示赞同!

遗憾最汹涌

我最近换了新的一台服务器,配置都比以前好很多,但是虚拟内存的使用情况却让我很疑惑。看来这个参数配置确实很重要,我得好好学习一下了。

    有7位网友表示赞同!

她最好i

终于找到一篇关于 Linux 虚拟内存参数配置的文章了!我一直想了解下这些参数怎么调设置,现在看起来还是比较详细的。我得试试看能不能优化一下服务器性能~

    有9位网友表示赞同!

泪湿青衫

这篇博文讲得挺不错的,把那些复杂的内核参数都解释得很清晰,很容易理解。对我这种 Linux 新手来说简直是福音!

    有20位网友表示赞同!

青瓷清茶倾城歌

这个配置真的需要根据实际情况来调整啊,我之前按照默认值就一直在测结果不太理想,后来试着调了下虚拟内存参数才发现效果好太多了!真要感谢博主分享的经验。

    有15位网友表示赞同!

一别经年

说的是,虚拟内存配置确实是需要谨慎调整的。调整太大可能会导致系统不稳定或者资源消耗过多。关键是要找到一个平衡点才是最重要的。

    有12位网友表示赞同!

風景綫つ

我觉得这篇文章没有提到很多细节,比如不同场景下参数的最佳设置,以及一些常见的问题解决方案。还有很多地方需要补充完善...

    有16位网友表示赞同!

寂莫

我试着用这个配置方法调了虚拟内存的参数,但是系统跑起来之后反而更卡了是怎么回事呢?难道是配置错误?还是说我的硬件无法支撑?

    有16位网友表示赞同!

限量版女汉子

Linux 系统的虚拟内存管理确实挺复杂的,这些参数设置对我来说难度还不低。不过我还是希望能够彻底了解,这样才能更好地利用 Linux 的资源。

    有5位网友表示赞同!

她的风骚姿势我学不来

虽然这个博文讲得不错,但是我个人更喜欢直接查阅内核文档学习虚拟内存参数配置。有时候一些博客的文章解释不够全面,或者说风格过于主观。

    有13位网友表示赞同!

Edinburgh°南空

我一直觉得 Linux 的虚拟内存配置参数太繁琐了,希望能有更好的图形化工具来帮助我们调整这些参数,这样会更加方便快捷。

    有10位网友表示赞同!

病态的妖孽

我一直在学习 Linux 内存管理,这个博文对我来说很有用,至少能让我了解一些基本的知识。我还是想要了解更多关于各种优化策略的详细介绍,比如 swap 设置、 page cache 等等。

    有9位网友表示赞同!

淡抹丶悲伤

虚拟内存参数确实关系到性能表现,但我更看重的是系统稳定性和安全性。我希望能够找到一个平衡点,既保证资源充分利用,又不至于导致系统宕机或数据丢失。

    有20位网友表示赞同!

傲世九天

我之前也遇到过类似的问题,后来发现是虚拟内存配置出现问题了导致的。调整好参数之后系统运行流畅了很多,建议你仔细阅读这篇文章看看能否帮到你的解决问题吧!

    有16位网友表示赞同!

tina

虚拟内存调节太考验技术的理解力了,很多时候还是需要实际操作和记录来总结经验。博主分享了很多实用细节,希望能帮助更多人快速掌握这些技巧!

    有13位网友表示赞同!

那伤。眞美

Linux 虚拟内存参数配置确实是一个挺难的事情,这篇文章虽然解释得不错,但是我仍然感觉有很多地方不够深入,比如对于不同的系统环境和应用场景,应如何进行合理的配置呢?

    有11位网友表示赞同!

热点资讯