zoukankan      html  css  js  c++  java
  • REdis之maxmemory解读

     

    redis.conf中的maxmemory定义REdis可用最大物理内存,有多种书写方式,以下均为合法:

    maxmemory 1048576

    maxmemory 1048576B

    maxmemory 1000KB

    maxmemory 100MB

    maxmemory 1GB

    maxmemory 1000K

    maxmemory 100M

    maxmemory 1G

     

    没有带单位尾巴的为字节数,以B结尾的表示相应的大小。但需要注意KBKMBMGBG是不同的,如1K表示1000字节,而1KB则为1024字节。如果maxmemory值为0,表示不做限制。

    如果是32位系统,当maxmemory值为0时,redis启动时会记录WARN日志:

    Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.

     

    并强制将最大内存设置为3GB,同时将内存策略设置为MAXMEMORY_NO_EVICTION(超出maxmemory后,所有写操作失败,读操作成功):

    server.maxmemory = 3072LL*(1024*1024); /* 3 GB */

    server.maxmemory_policy = MAXMEMORY_NO_EVICTION;

     

    如果设置的maxmemory小于1MB,则redis启动时记录如下日志:

    WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want?

     

    相关的源代码如下:

    /* Convert a string representing an amount of memory into the number of

     * bytes, so for instance memtoll("1Gb") will return 1073741824 that is

     * (1024*1024*1024).

     *

     * On parsing error, if *err is not NULL, it's set to 1, otherwise it's

     * set to 0. On error the function return value is 0, regardless of the

     * fact 'err' is NULL or not. */

    long long memtoll(const char *p, int *err) {

        const char *u;

        char buf[128];

        long mul; /* unit multiplier */

        long long val;

        unsigned int digits;

     

        if (err) *err = 0;

     

        /* Search the first non digit character. */

        u = p;

        if (*u == '-') u++;

        while(*u && isdigit(*u)) u++;

        if (*u == '' || !strcasecmp(u,"b")) { // 调用strcasecmp不区分大小比较

            mul = 1;

        } else if (!strcasecmp(u,"k")) {

            mul = 1000; // 不带尾巴B或b的

        } else if (!strcasecmp(u,"kb")) {

            mul = 1024; // 带尾巴B或b的

        } else if (!strcasecmp(u,"m")) {

            mul = 1000*1000; // 不带尾巴B或b的

        } else if (!strcasecmp(u,"mb")) {

            mul = 1024*1024; // 带尾巴B或b的

        } else if (!strcasecmp(u,"g")) {

            mul = 1000L*1000*1000; // 不带尾巴B或b的

        } else if (!strcasecmp(u,"gb")) {

            mul = 1024L*1024*1024; // 带尾巴B或b的

        } else {

            if (err) *err = 1;

            return 0;

        }

     

        /* Copy the digits into a buffer, we'll use strtoll() to convert

         * the digit (without the unit) into a number. */

        digits = u-p;

        if (digits >= sizeof(buf)) {

            if (err) *err = 1;

            return 0;

        }

        memcpy(buf,p,digits);

        buf[digits] = '';

     

        char *endptr;

        errno = 0;

        val = strtoll(buf,&endptr,10);

        if ((val == 0 && errno == EINVAL) || *endptr != '') {

            if (err) *err = 1;

            return 0;

        }

        return val*mul;

    }

     

    // 有关REdis内存策略的实现,请参见REdis源码文件evict.c。

     

    如果没有禁用config命令,则可用它动态实时修改maxmemory的值,如将maxmemory设置为15GB

    redis-cli -h 192.168.31.8 -p 6379 config set maxmemory 15GB

     

    如果要查看maxmemory的值,有如下两种方法:

    redis-cli -h 192.168.31.8 -p 6379 config get maxmemory

    redis-cli -h 192.168.31.8 -p 6379 info memory | grep maxmemory

     

    由于REdis一般占大内存,所以通常需要关闭系统的OOM,方法为将“/proc/sys/vm/overcommit_memory”的值设置为1(通常不建议设置为2),也可以使用命令sysctl设置,如:sysctl vm.overcommit_memory=1,但注意一定要同时修改文件/etc/sysctl.conf,以便得系统重启后仍然生效:

    # vi /etc/sysctl.conf

    vm.overcommit_memory=1

     

    修改sysctl.conf后,需要执行“sysctl -p”以使生效。

     

  • 相关阅读:
    2021-6-3 日报博客
    2021-6-2 日报博客
    2021-6-1 日报博客
    2021-5-31 日报博客
    团队博客——十日冲刺结束
    团队博客——十日冲刺9
    团队博客——十日冲刺8
    团队博客——十日冲刺7
    周总结9
    团队博客——十日冲刺6
  • 原文地址:https://www.cnblogs.com/aquester/p/10907301.html
Copyright © 2011-2022 走看看