本文采用知识共享 署名-相同方式共享 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 只有一次。