本文采用知识共享 署名-相同方式共享 4.0 国际 许可协议进行许可。
访问 https://creativecommons.org/licenses/by-sa/4.0/ 查看该许可协议。

Redis 优化方案

1) 缓存穿透

一般发生在系统被 CC 攻击时, 反复请求一条 DB 中没有的数据, 代码无法将此数据缓存, 导致大并发的请求直接打在 DB 上, 引起 DB 宕机, 即缓存穿透.

1.1) Redis 填充空数据(推荐)

原理是在 Redis 中插入一条空值数据, 将数据库压力转移到 Redis 上, 直接上伪代码:

int requestId = -1;

String cacheValue = redis.get(requestId);
if(null == cacheValue) { // 只作 null 判断
    if (DB 有数据) {
        redis.put(requestId, DB 数据);
        return DB 数据;
    } else {
        redis.put(requestId, ""); // Put 一个空数据
        return "";
    }
}

1.2) 布隆过滤器

百度 Google 吧这边不献丑了

2) 缓存雪崩

Redis 瞬时大面积 Key 过期, 同时客户端产生大量并发, 会导致并发直接打在 DB 上引起宕机, 即缓存雪崩.
方案:

  • Key 永不过期
  • 多层缓存: 如 Redis + Memcached, 获取数据顺序: Redis -> Memcached -> DB
  • 分散过期时间
  • 第三方 Redis: 如阿里云 Redis, 也算是一种永不过期方案

3) 批量查询 multi 和 pipeline

multi 和 pipeline 的区别在于 multi 会将操作都即刻的发送至 redis 服务端 queued 起来,每条指令 queued 的操作都有一次通信开销,执行 exec 时 redis 服务端再一口气执行 queued 队列里的指令,pipeline 则是在客户端本地 queued 起来,执行 exec 时一次性的发送给 redis 服务端,这样只有一次通信开销。比如我有 5 个 incr 操作,multi 的话这 5 个 incr 会有 5 次通信开销,但 pipeline 只有一次。