//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