内部存款和储蓄器分配管理,redis品质优化

2019-09-11 作者:yzc216亚洲城   |   浏览(101)

浅谈linux性能调优之十一:内存分配管理

Redis性能优化

/proc/sys/net/core/somaxconn
sysctl vm.overcommit_memory=1
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo 512 > /proc/sys/net/core/somaxconn

 

overcommit_memory参数说明:

设置内存分配策略(可选,根据服务器的实际情况进行设置)
/proc/sys/vm/overcommit_memory
可选值:0、1、2。

  • 0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
  • 1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
  • 2, 表示内核允许分配超过所有物理内存和交换空间总和的内存

    注意:redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用 的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所 以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。

这里又涉及到Overcommit和OOM。

浅谈linux性能调优之十:资源分配规划

什么是Overcommit和OOM?

在Unix中,当一个用户进程使用malloc()函数申请内存时,假如返回值是NULL,则这个进程知道当前没有可用内存空间,就会做相应的处理工作。许多进程会打印错误信息并退出。
Linux使用另外一种处理方式,它对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit。
当内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。

Overcommit的策略

Linux下overcommit有三种策略(Documentation/vm/overcommit-accounting):

    1. 启发式策略。合理的overcommit会被接受,不合理的overcommit会被拒绝。
    1. 任何overcommit都会被接受。
    1. 当系统分配的内存超过swap N%*物理RAM(N%由vm.overcommit_ratio决定)时,会拒绝commit。
      overcommit的策略通过vm.overcommit_memory设置。
      overcommit的百分比由vm.overcommit_ratio设置。

      # echo 2 > /proc/sys/vm/overcommit_memory
      # echo 80 > /proc/sys/vm/overcommit_ratio
      

当oom-killer发生时,linux会选择杀死哪些进程
选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。
点数越高,这个进程越有可能被杀死。
每个进程的点数跟oom_score_adj有关,而且oom_score_adj可以被设置(-1000最低,1000最高)。

 

    linux下内存分配的管理主要通过内核参数来控制:

    1.与容量相关的内存可调参数

      以下参数位于 proc 文件系统的 /proc/sys/vm/ 目录中。

      overcommit_memory :规定决定是否接受超大内存请求的条件。这个参数有三个可能的值:

         * 0 — 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。不让过度使用,直接报错

         * 1 — 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。应用程序在需要时分配,允许过度使用

         * 2 — 内存拒绝等于或者大于总可用 swap 大小以及 overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。 将swap直接使用,使用的内存 = swap ram * 50%

            注意:只为 swap 区域大于其物理内存的系统推荐这个设置

      overcommit_ratio

         将 overcommit_memory 设定为 2 时,指定所考虑的物理 RAM 比例。默认为 50。 

测试程序:

###############################################################################

#include "stdio.h"

#include "stdlib.h"

#include "errno.h"

 

#define maxtimes 1000*1000

#define unit 10485760

int main()

{

    char *q[1000000];

    int i=1;

    char *pc;

    for (i=1; i<=maxtimes;i )

        {

                q[i] = (char *)malloc(unit);

                if ( q[i] == NULL)

                {

                        printf ("malloc errorn");

                }

                printf("%on",q[i]);

                pc = (char*)(q[i]);

                for (int j=0;j<10485760;j )

                {

                        pc[j]='a';

                }

                printf("%sn",pc);

                printf("have been malloc %dMn",i);

        }

    return 0;

}

 

###############################################################################

 

    测试1:overcommit_memory = 0 也是默认的情况,我物理内存2G,开机后查看已使用600M左右,我在这里关闭了swap分区,编译来测试,结果:使用top 查看a.out的RES(物理内存的使用)到达了1.3g   进程被Killed (原因在后面说) 1.3g 600多M = 2G  查看日志:

Jul 16 14:24:48 localhost kernel: Out of memory: kill process 19066 (a.out) score 131753 or a child

Jul 16 14:24:48 localhost kernel: Killed process 19066 (a.out) vsz:8432216kB, anon-rss:1377108kB, file-rss:92kB

 

    测试2:overcommit_memory = 1,情况和测试1一致,

[[email protected] Desktop]# free

             total       used       free     shared    buffers     cached

Mem:       1978696    1873644     105052          0       8268      75012

-/ buffers/cache:    1790364     188332

      我们可以看到:内存在剩100M左右时,a.out先卡住了一会,然后有开始执行了 ,它会一直等待能够使用的资源再执行 (都是别的进程释放的资源),用来不会被杀死,因为这个模式对内存无限制

 

    测试3:overcommit_memory = 2,overcommit_ratio默认,都使用,内存会在一定剩余的情况下不能malloc

程序执行结果:

have been malloc 266M  这里是2660

malloc error

0

Segmentation fault (core dumped)

 

 

  

 

        o: VIRT  --  Virtual Image (kb)

          The total amount of virtual memory used by the  task.   It  includes

          all  code,  data  and  shared  libraries  plus  pages that have been

          swapped out. (Note: you can define the STATSIZE=1 environment  vari-

          able  and  the VIRT will be calculated from the /proc/#/state VmSize

          field.)

 

          VIRT = SWAP RES.

 

       p: SWAP  --  Swapped size (kb)

          The swapped out portion of a task’s total virtual memory image.

 

       q: RES  --  Resident size (kb)

          The non-swapped physical memory a task has used.

 

    2.Out-of-Memory Kill 可调参数

    内存不足(OOM)指的是所有可用内存,包括 swap 空间都已被分配的计算状态。默认情况下,这个状态可造成系统 panic,并停止如预期般工作。但将 /proc/sys/vm/panic_on_oom 参数设定为 0 会让内核在出现 OOM 时调用 oom_killer 功能。通常 oom_killer 可杀死偷盗进程,并让系统正常工作。

    可在每个进程中设定以下参数,提高您对被 oom_killer 功能杀死的进程的控制。它位于 proc 文件系统中 /proc/pid/ 目录下,其中 pid 是进程 ID。

 

oom_adj

    定义 -16 到 15 之间的一个数值以便帮助决定某个进程的 oom_score。oom_score 值越高,被 oom_killer 杀死的进程数就越多。将 oom_adj 值设定为 -17 则为该进程禁用 oom_killer。

 

    注意:

    由任意调整的进程衍生的任意进程将继承该进程的 oom_score。例如:如果 sshd 进程不受 oom_killer 功能影响,所有由 SSH 会话产生的进程都将不受其影响。这可在出现 OOM 时影响 oom_killer 功能救援系统的能力。

 

浅谈linux性能调优之十:资源分配规划 linux下内存分配的管理主要通过...

本文由yzc216亚洲城发布于yzc216亚洲城,转载请注明出处:内部存款和储蓄器分配管理,redis品质优化

关键词: yzc216亚洲城