redis 忽然大量逐出致使读写请求block

现象

redis做为缓存场景使用,内存耗尽时,忽然出现大量的逐出,在这个逐出的过程当中阻塞正常的读写请求,致使 redis 短期不可用;git

背景

redis 中的LRU是如何实现的?github

  1. 当mem_used内存已经超过maxmemory的设定,对于全部的读写请求,都会触发redis.c/freeMemoryIfNeeded(void)函数以清理超出的内存。
  2. 这个清理过程是阻塞的,直到清理出足够的内存空间。
  3. 这里的LRU或TTL策略并非针对redis的全部key,而是以配置文件中的maxmemory-samples个key做为样本池进行抽样清理。
    maxmemory-samples在redis-3.0.0中的默认配置为5,若是增长,会提升LRU或TTL的精准度,redis做者测试的结果是当这个配置为10时已经很是接近全量LRU的精准度.

缘由

逐出qps突增很是大的缘由:一次须要逐出释放太多的空间会致使阻塞;具体的缘由是 mem_tofree 的计算逻辑有问题;
mem_tofree 统计的是:实际已分配的内存总量 - AOF 缓冲区相关的内存;
若是这时候有rehash,会临时分配一个桶来作rehash,这部份内存未排除,因此在rehash阶段,算出来的mem_tofree 就会很大,形成一个时刻须要逐出大量的key,逐出的loop是阻塞的,这个阶段会block redis的请求;redis

逐出qps的计算:算法

freeMemoryIfNeeded(...)
    // 计算出 Redis 目前占用的内存总数,但有两个方面的内存不会计算在内:
    // 1)从服务器的输出缓冲区的内存
    // 2)AOF 缓冲区的内存
    // 3)AOF 重写缓冲区中的内存
    mem_used = zmalloc_used_memory();
    if (slaves) {
        listIter li;
        listNode *ln;

        listRewind(server.slaves,&li);
        while((ln = listNext(&li))) {
            redisClient *slave = listNodeValue(ln);
            unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
            if (obuf_bytes > mem_used)
                mem_used = 0;
            else
                mem_used -= obuf_bytes;
        }
    }
    if (server.aof_state != REDIS_AOF_OFF) {
        mem_used -= sdslen(server.aof_buf);
        mem_used -= aofRewriteBufferSize();
    }
    // 计算须要释放多少字节的内存
    mem_tofree = mem_used - server.maxmemory;
    propagateExpire(db,keyobj);
    // 计算删除键所释放的内存数量
    delta = (long long) zmalloc_used_memory();
    dbDelete(db,keyobj);
    delta -= (long long) zmalloc_used_memory();
    mem_freed += delta;
    // 对淘汰键的计数器增一
    server.stat_evictedkeys++;

解决方案

github上 @Rosanta 给出的解决方案:释放内存的循环逻辑中最多执行必定次数,达到阈值了就再也不逐出,到下个请求来时再释放一点空间;这个方案的好处是不会 block 整个进程,正常的业务读写请求无影响;潜在问题是可能单次写入的数据比释放的空间还大,致使总的内存是一直上升,而不是降低;缓存

@antirez 给的方案:一样是迭代删除,但会加个标志,保证在迭代删除的逻辑下内存是逐渐降低的,而若是是上升的,仍是会block住正常的请求(要控制主总的内存大小);
详见:
https://github.com/antirez/redis/pull/4583服务器

ref

关于 redis 4.0的逐出算法优化
http://antirez.com/news/109函数

相关文章
相关标签/搜索