Linux内核参数优化记录

//fs.file-max       最大打开文件数
//fs.nr_open=20480000           单个进程允许打开的文件句柄上限

//信号量及共享内存,可以使用ipcs -l来获取
//kernel.sem        信号量: 每个信号集中最大信号量数目 系统范围最大信号量数目 每个信号发生时的最大系统操作数 系统范围内最大信号集总数目 第一列*第四列=第二列
//                  512G好配置:4096 2147483647 2147483646 512000  1G差配置:250 512000 100 2048

//kernel.shmall     控制全部共享内存页数。系统所有共享内存段相加的大小限制,建议为内存的80%,例如:64G *80%/4k 即是页数
//kernel.shmmax     单个共享内存段大小,建议为内存的一半,9.2之后对共享内存使用降低了,单位是byte
//kernel.shmmni     全部共享内存段的总个数,缺省值为4096就够了,参考的是819200,单个共享段最小大小?

//脏页刷新
//vm.dirty_background_bytes     40960000,系统脏页达到这个值,系统后台刷脏页调度进程自动将dirty_expire_centisecs/100秒前的脏页刷到磁盘,建议设置为内存的2%?
//vm.dirty_expire_centisecs     比这个值老的脏页,将被刷到磁盘,3000表示30秒

//vm.dirty_ratio = 95           如果单个进程产生的脏数据到达系统整体内存的百分比,此时进程自行把脏数据写回磁盘.
//                              如果系统进程刷脏页太慢,使得系统脏页超过内存 95 % 时,则用户进程如果有写磁盘的操作(如fsync, fdatasync等调用),则需要主动把系统脏页刷出。
//                              有效防止用户进程刷脏页,在单机多实例,并且使用CGROUP限制单实例IOPS的情况下非常有效
//vm.dirty_background_ratio     所有全局系统进程的脏页数量到达系统整体内存的百分比,此时触发pdflush进程把脏数据写回磁,默认值为10,注意这里是全局进程的脏页

//Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit
//vm.dirty_writeback_centisecs = 100    pdflush(或其他)后台刷脏页进程的唤醒间隔,缺省值为500,100表示1秒。
//vm.overcommit_memory = 0              在分配内存时,允许少量over malloc, 如果设置为 1, 则认为总是有足够的内存,内存较少的测试环境可以使用 1 .
//                                      0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
//                                      1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。当kernel发现内存使用率接近100%时,就触发OOM,杀掉一些用户态进程,释放内存
//                                      2, 用户一次申请的内存大小不允许超过可用内存的大小。表示内核允许分配超过所有物理内存和交换空间总和的内存(参照overcommit_ratio)。
//vm.overcommit_ratio = 90     默认50,当overcommit_memory = 2 时,用于参与计算允许指派的内存大小。系统可分配内存=交换空间+物理内存*overcommit_ratio/100,超过这个值就拒绝这次内存申请
//vm.swappiness = 0            关闭交换分区
//vm.zone_reclaim_mode = 0      禁用 numa, 或者在vmlinux中禁止.

//nr_pdflush_threads            当前正在运行的pdflush进程数量,在I/O负载高的情况下,内核会自动增加更多的pdflush进程。缺省值2,只读

//vm.extra_free_kbytes = 4096000
//vm.min_free_kbytes = 2097152      Linux VM最低保留多少空闲内存(Kbytes)
//如果是小内存机器,以上两个值不建议设置
//vm.nr_hugepages = 66536    建议shared buffer设置超过64GB时 使用大页,页大小 /proc/meminfo Hugepagesize
//vm.lowmem_reserve_ratio = 1 1 1   对于内存大于64G时,建议设置,否则建议默认值 256 256 32

未完待续:

20190325 对vm.overcommit_memory的新理解:

假如有16G内存、swap为2G为例,加起来18G。0表示会查看18G中剩余的空间大小,如果不够就失败。1表示不会看是否剩下多少,直接分配,出错了再OOM来处理。2表示如果vm.overcommit_ratio为默认的50,则一次申请不能大于2+16*50%=10G。那么设为2的时候,会看总的剩余内存吗?还是说认为总的剩余内存为10G的情况下,减去已占用的内存,来判定是否能申请成功?

不是这样:

vm.overcommit_memory = 2	#0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
							#内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。
							#遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。
							#1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。当kernel发现内存使用率接近100%时,就触发OOM,杀掉占用内存最多的进程,释放内存。
							#2,表示内核允许分配超过所有物理内存和交换空间总和的内存。CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap,超过这个值就拒绝这次内存申请。
vm.overcommit_ratio = 90 	#(mem-swap)/mem*100 这样就不会申请到swap的内存,既CommitLimit=mem,当申请的空间达到了mem就直接不允许申请了。
							#grep -i commit /proc/meminfo
							#CommitLimit:     2537348 kB
							#Committed_AS:    1660900 kB
							#这里的CommitLimit为当前系统可以申请的总内存,Committed_AS为当前已经申请的内存,记住是申请。
							#当你的free查看有很多大量可用的内存的时候,实际Committed_AS可能已经申请了大量的内存了,在vm.overcommit_memory #2模式下,后续的程序可以申请的剩余内存为CommitLimit - Commited_AS了。

  

参考:

https://www.cnblogs.com/ywcz060/p/5566086.html

https://github.com/digoal/blog/blob/master/201611/20161121_01.md?spm=a2c4e.11153940.blogcont80563.13.5c96100aDpE202&file=20161121_01.md#postgresql-on-linux-最佳部署手册---珍藏级

添加在2019-09-22:

vm.dirty_background_ratio=1 #默认10,在数据库系统中最好设置小一点
kernel.sem = 5010 641280 5010 256
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 4294967295
kernel.shmmni = 4096
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
net.core.somaxconn=1024
vm.swappiness=0 #不要走swap,100
vm.overcommit_memory = 2
vm.overcommit_ratio = 90 # mem/(mem+swap)
vm.dirty_background_ratio=1 #要设低一点
vm.dirty_ratio = 2 #低一点
vm.nr_hugepages = 10#还需要确认大页的设置

再次参考:

https://blog.csdn.net/qq_16097611/article/details/52816908

诡异场景:

当你发现程序在申请大段内存的时候,发生申请失败。

这时候你通过查看free -g发现free下的内存还有大量可以使用的内存。

然后你再继续查看ulimit -a的时候,却发现max memroy size为不受限。

这时候你或许会很疑惑,为什么在足够内存的情况下,当申请内存达到一定量的时候,却还是失败呢。

这时候你查看sysctl -a | grep "vm.overcommit_memory",如果你发现值为2,那么问题便是发生在这里了

在我们进行内存申请的时候,如malloc 200m,这时候仅仅是进行内存申请,但实际使用的时候可能仅仅是100m, 意味着有100m并没有真是被分配。

这时候我们通过free 看到使用的也只有100m的内存。但是vm.overcommit_memory其关注的是申请的内存,即200m的内存,这点需要注意。

而vm.overcommit_memory的意思:

0 — 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。
1 — 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。
2 — 内存拒绝等于或者大于总可用 swap 大小以及 overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的
值为2下的场景:

公式:CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap
Physical RAM为当前系统的总物理内存

 vm.overcommit_ratio为物理内存的比例,默认为50

Swap为当前系统的总Swap

可以通过查看

grep -i commit /proc/meminfo
CommitLimit:    73955212 kB
Committed_AS:    kB

这里的CommitLimit为当前系统可以申请的总内存,Committed_AS为当前已经申请的内存,记住是申请。

因此当你的free查看有很多大量可用的内存的时候,实际Committed_AS可能已经申请了大量的内存了,在vm.overcommit_memory 2模式下,后续的程序可以申请的剩余内存

为CommitLimit - Commited_AS了。

而vm.overcommit_memory设置为2一般是建议当Swap大于物理内存的时候才进行设置。

而vm.overcommit_memory一般是设置为0模式的。

因此现在你知道该如何查理这种场景了吧。

再参考:https://www.cnblogs.com/EasonJim/p/7778025.html

2020-02-20:

1) /etc/sysctl.conf
#/proc/sys/kernel/优化
kernel.sem = 5010 641280 5010 256 	#信号量,pv操作,一个pv操作组里面有多少个信号量。 				 
									#第一个是一个组有多少个信号量,最后一个是有多少组,第二个是总共多少,第三个是单次操作能改多少,一般设置为第一个值
									#250 162500 250 650 Oracle要求
									#20  13000  20  650 pg够用了

									#第一个参数要大于17
									#一个连接对应为大概16个信号量,所以一万个连接可以这么算:10000/16=625,就取一个650算了。

kernel.shmall = 2097152		#全部允许使用的共享内存大小页数,推荐设置为内存的90%,缺省设置:2097152 bytes。
							#以16GB内存为例,可设置为:16*1024*1024*1024*0.9/4096=3774873。(单个块大小可通过getconf PAGESIZE获取)
kernel.shmmax = 53687091200 #是单个段允许使用的大小,推荐设置为内存的50%,缺省设置:33554432 bytes。
							#以16GB内存为例,可设置为:16*1024*1024*1024*0.5=8589934592。实际可用最大共享内存段大小=shmmax * 98%,其中大约2%用于共享内存结构。
							#通过ipcs -u查看当前试用情况
kernel.shmmni = 4096		#整个系统的共享内存段的最大数目(个),缺省设置:4096。

#/proc/sys/vm/优化
vm.dirty_background_ratio=2 #表示脏数据到达系统整体内存的百分比,此时触发pdflush进程把脏数据写回磁盘。缺省设置:10,大内存时推荐值为2。内存较小时可以使用默认值,内存较大时,设置为1。
							#例如512GB内存的服务器,10%为51.2GB,这样刷盘的压力太大了,设置为1%,则达到5.12GB就触发刷盘。
vm.dirty_ratio = 40			#如果进程产生的脏数据到达系统整体内存的百分比,此时进程自行把脏数据写回磁盘,缺省设置:40。同样,原理,根据内存总大小来设置。
							#有时候系统进程刷盘太慢,就会触发进程自己的fsync刷盘。
vm.overcommit_memory = 2	#0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
							#内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。
							#遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。
							#1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。当kernel发现内存使用率接近100%时,就触发OOM,杀掉占用内存最多的进程,释放内存。
							#2,表示内核允许分配超过所有物理内存和交换空间总和的内存。CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap,超过这个值就拒绝这次内存申请。
vm.overcommit_ratio = 90 	#(mem-swap)/mem*100 这样就不会申请到swap的内存,既CommitLimit=mem,当申请的空间达到了mem就直接不允许申请了。
							#grep -i commit /proc/meminfo
							#CommitLimit:     2537348 kB
							#Committed_AS:    1660900 kB
							#这里的CommitLimit为当前系统可以申请的总内存,Committed_AS为当前已经申请的内存,记住是申请。
							#当你的free查看有很多大量可用的内存的时候,实际Committed_AS可能已经申请了大量的内存了,在vm.overcommit_memory #2模式下,后续的程序可以申请的剩余内存为CommitLimit - Commited_AS了。
vm.swappiness = 0 			#0的时候表示最大限度使用物理内存,然后才是swap空间,
							#swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。
							#linux的基本默认设置为60就是说,你的内存在使用到100-60=40%的时候,就开始出现有交换分区的使用。
							#大家知道,内存的速度会比磁盘快很多,这样子会加大系统IO,同时造的成大量页的换进换出,严重影响系统的性能,
							#所以我们在操作系统层面,要尽可能使用内存,对该参数进行调整。尽量调低一点,10或者0。
fs.aio-max-nr = 1048576		#文件所允许的并发请求的最大个数, 1024*1024
fs.file-max = 6815744		#最大打开文件数
fs.nr_open = 20480000       #单个进程允许打开的文件句柄上限

net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.ipv4.tcp_fin_timeout = 30
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
net.core.somaxconn=1024

# TCP端口使用范围
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 6000
# 记录的那些尚未收到客户端确认信息的连接请求的最大值
net.ipv4.tcp_max_syn_backlog = 65536
# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_wmem = 8192 436600 873200
net.ipv4.tcp_rmem  = 32768 436600 873200
net.ipv4.tcp_mem = 94500000 91500000 92700000
net.ipv4.tcp_max_orphans = 3276800

  

#/proc/sys/kernel/优化
kernel.sem = 5010 641280 5010 256		 
kernel.shmall = 2097152								
kernel.shmmax = 53687091200 						
kernel.shmmni = 4096		
vm.dirty_background_ratio=2 
vm.dirty_ratio = 40			
vm.overcommit_memory = 2	
vm.overcommit_ratio = 90 	
vm.swappiness = 0 				
fs.aio-max-nr = 1048576		
fs.file-max = 6815744		
fs.nr_open = 20480000       

net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.ipv4.tcp_fin_timeout = 30
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
net.core.somaxconn=1024

# TCP端口使用范围
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 6000
# 记录的那些尚未收到客户端确认信息的连接请求的最大值
net.ipv4.tcp_max_syn_backlog = 65536
# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_wmem = 8192 436600 873200
net.ipv4.tcp_rmem  = 32768 436600 873200
net.ipv4.tcp_mem = 94500000 91500000 92700000
net.ipv4.tcp_max_orphans = 3276800

  

原文地址:https://www.cnblogs.com/kuang17/p/10554320.html