Overcommitting Memory (过度使用内存)

前言

本文属于红帽性能调优课程之内存过度使用

如何防止内存被过度使用

许多应用程序相较于她们将实际使用的内存会请求分配更多的内存,另一些程序会请求内核分配超过系统可用内存的内存大小,解决这个问题的一个方法是调节 vm.overcommit_memory 参数,这个值可以是以下3个值
    0:使用启发式算法,如果程序企图申请比可用内存更多的空间,则内核返回拒绝。但是当有大量的小内存申请时,内核依然可能overcommit。
    1:不管系统是否有足够的内存,内核总是会分配内存申请
    2:从不过载,内核只分配 swap 的大小加上物理内存百分比(默认一半)的内存,可以通过修改 vm.overcommit_ratio 修改默认值。
/proc/meminfo 中的 Committed_AS 预估了机器当前负载下可能需要的内存大小可以避免内存缺失(out-of-memory)

调节 swappiness

在内存中寻找不活跃的page( inactive page )会消耗大量 CPU 的时间,在大内存系统中,相较于将不活跃的页写入匿名也,而是找到并取消不活跃的页的映射,将之交换到磁盘会消耗更多的磁盘和 CPU 的资源。


在内存调优的课程中讲过,vm.swapness 值,这个值越大,系统更倾向于将数据 swap 出内存,来释放内存空间,反之越小,系统越倾向于丢弃 cached page ,来释放内存,在数据库场景下应设置 swappiness 以使。机器在大部分系统内存被消耗之前不会交换,vm.swappiness 默认值是60,在数据库场景中这个值建议在1-20之间,有些数据库开发人员会对这个值有一个建议,如果他们给出了参考值,那么应该优先遵循厂商的建议。
 

调节缓存页写入

另一个数据库服务器潜在的瓶颈是服务器磁盘读取数据的能力,如果数据库需要从磁盘读取数据,那么无论程序读取什么数据,该操作都会被阻塞,直到该操作的 I/O 请求返回了中断信号,除了将磁盘 IO 调度算法调节为 deadline ( moving the I/O to deadline ),让系统偏向于磁盘的读操作,管理员还可以修改配置管理系统如何将缓存的数据写入磁盘,缓存写入操作的时间越久意味着磁盘能更好的进行读取操作,但是进行这个配置。必须非常小心,如果机器掉电或者内核崩溃,这些缓存的数据依旧停留在 RAM 中,这些没有写入的数据将会丢失。
缓存文件写入的一些可调参数建议值:

vm.diry_background_ratio=3               #缓存的脏数据超过系统3%的内存,系统开始将脏数据写入到磁盘(不会强制写入)
vm.dirty_ratio=80                                #脏数据超过系统内存80%,开始强制将脏数据写入磁盘       vm.dirty_expire_centisecs=500          #脏数据到期时间5秒
vm.dirty_writeback_centisecs=100      #每0.1秒系统检测一次脏数据是否到期,到期了就把脏数据刷到 I/O 子系统中
 

使用这个配置,缓存的数据会很快到期,但内核会在后台进行将脏数据写入磁盘的操作,除非发生很荒谬的事情,缓存的脏数据到了占到系统内存80%。

参考

/usr/share/doc/kernel-doc-*/Documentation/sysctl/vm.txt

/usr/share/doc/kernel-doc-*/Documentation/vm/overcommit-accounting

 实验1、模拟程序申请大量内存,触发 Overcommitting Memory 查看 Committed_AS 值的变化

1、安装内存测试软件 bigmem

[root@server0 ~]# yum install bigmem -y

2、查看系统当前 Committed_AS 的值

[root@server0 ~]# grep Committed_AS /proc/meminfo 
Committed_AS:    1136968 kB

3、使用 bigmem 申请20G虚拟内存

[root@server0 ~]# bigmem -v 20480
Attempting to allocate 20480 MebiBytes of virtual memory...
Allocated 10000MiB
Allocated 20000MiB
Press <Enter> to exit

4、重新开启一个终端查看内存过载

[root@server0 ~]# grep Commit /proc/meminfo 
CommitLimit:      942588 kB
Committed_AS:   22196280 kB

5、返回上一个终端,按回车结束进程
 

实验2、禁止系统内存过载

1、安装内存测试软件 bigmem

[root@server0 ~]# yum install bigmem -y

2、允许程序最多申请2倍于物理内存+swap空间的内存

[root@server0 home]# sysctl -w vm.overcommit_ratio=200
vm.overcommit_ratio = 200          

 3、禁止操作系统实现内存过载

[root@server0 ~]# sysctl -w vm.overcommit_memory=2
vm.overcommit_memory = 2

4、查看 swap 与 RAM 空间的大小,计算出虚拟内存的阈值

[root@server0 home]# free
             total       used       free     shared    buffers     cached
Mem:       1885180     651660    1233520      17144        688     321584
-/+ buffers/cache:     329388    1555792
Swap:            0          0          0

5、查看当前系统允许申请的最大虚拟内存数量

[root@server0 home]# grep Commit /proc/meminfo 
CommitLimit:     3770360 kB               # swap 的空间为0 所以这个值为1885180*2
Committed_AS:    1150016 kB           

 6、用 bigmem 测试超过虚拟内存限制阈值的情况

[root@server0 ~]# bigmem -v 20450
Attempting to allocate 20450 MebiBytes of virtual memory...
Error allocating page, exiting

7、用 bigmem 测试临界与阈值的情况

[root@server0 ~]# bigmem -v 2457 
Attempting to allocate 2457 MebiBytes of virtual memory...
Press <Enter> to exit

8、重新开启一个终端查看,查看 Committed_AS 与 CommitLimit 的值

[root@server0 home]# grep Commit /proc/meminfo 
CommitLimit:     3770360 kB
Committed_AS:    3676032 kB

9、让系统尽可能将数据写入交换分区查看 Committed_AS 与 commitLimit 的变化

[root@server0 home]# sysctl -w vm.swappiness=100
vm.swappiness = 100

由于交换空间为0,所以不会有任何变化
10、创建一个1G交换分区观察 CommitLimit 的变化

[root@server0 home]# free
            total       used       free     shared    buffers     cached
Mem:       1885180    1818360      66820      17152        692     312392
-/+ buffers/cache:    1505276     379904
Swap:      1048572          0    1048572
[root@server0 home]# grep Commit /proc/meminfo 
CommitLimit:     4818932 kB
Committed_AS:    1150320 kB

注意:如果发生过载系统将不能进行任何操作,因为不能再分配内存空间,reboot操作都执行不了,只能强制关机重启电脑,如果将此配置写入开机启动文件,同时将 commitLimit 值限制的非常小,将导致
系统不能正常启动,只能进入单用户模式修复。

[root@server0 ~]# ls
-bash: fork: Cannot allocate memory
[root@server0 ~]# reboot
-bash: fork: Cannot allocate memory

实现3:为数据库服务器创建一个调优文件

要求:

1、该文件的名称为 enterprise-database 并启用这个文件
2、这个文件要基于 throughput-performance 文件系统,确保标准大页可用
3、I/O 调度器设置为 deadline
4、脏页占据系统3%的内存后开始后台同步到磁盘
5、脏页占据系统80%的内存后,要强制写入磁盘
6、每100厘秒检测一次脏页是否到期
7、用默认的大页大小分配256MiB的大页空间
8、禁用透明大页分配
9、激活 tcp_fastopen 并设置为3
10、共享内存段的总大小为2TiB
11、单个信号的操作数量设置为100,其余的信号用默认值
12、禁止系统内存过度使用不能超过2倍的 RAM 加上 swap 的大小
13、机器可以使用swap,但应该尽可能的少用

参考答案

[root@server0 home]# mkdir /etc/tuned/enterprise-database
[root@server0 ~]# cat /etc/tuned/enterprise-database/tuned.conf
#
# tuned configuration
#

[main]
include=throughput-performance

[vm]
transparent_hugepages=never

[sysctl]
vm.dirty_background_ratio=3
vm.dirty_ratio=80
vm.dirty_writeback_centisecs=100
vm.nr_hugepages=128
vm.overcommit_ratio=200
vm.swappiness=1

kernel.shmall="536870912"
kernel.sem="250 32000 100 128"

net.ipv4.tcp_fastopen=3

[primary]
type=disk
elevator=deadline

[root@server0 ~]# tuned-adm profile enterprise-database

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值