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函數

相關文章
相關標籤/搜索