Redis与Memcache对比
| 工作 | Memcache | Redis |
|---|---|---|
| 数据类型 | 简单 key-value 结构 | 丰富的数据结构 |
| 持久化 | 不支持 | 支持 |
| 分布式存储 | 客户端哈希分片/一致性哈希 | 多种方式,主从 |
| 多线程支持 | 支持 | Redis5.0 以及以前不支持 |
| 内存管理 | 私有内存池 | 无 |
| 事务支持 | 不支持 | 有限支持 |
| 容灾 | 不支持,不能数据恢复 | 支持,恢复数据 |
Redis常见难题
缓存雪崩
大部分缓存失效 —> 数据库奔溃
解决方案
- 使用锁或队列:确保不会有大量线程对数据库进行一次性读写,从而避免失效时大量的并发请求落到底层存储系统上
- 为 Key 设置不同的缓存失效时间:在一个固定的缓存时间的基础上+随机一个时间作为缓存失效时间
- 二级缓存:设置一个有时间限制的缓存+一个无时间限制的缓存
缓存穿透
查询无数据返回 —> 直接查询数据库
解决方案
- 如果查询结果为空,直接设置一个默认值存放到缓存
- 设置布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截
缓存预热
系统上线后,将相关需要缓存数据直接加到缓存系统中
解决方案
- 缓存刷新页面,上线手工操作
- 数据量不大,项目启动时自行加载
- 定时刷新缓存
缓存更新
- 定期清理过期缓存
- 判断请求是否过期,过期就到底层系统得到新数据并更新缓存
缓存击穿
某一热点数据过期 —> 大量并发请求直接查找数据库
解决方案
- 设置热点数据永不过期
- 设置逻辑过期时间:异步线程检查过期键,更新后重置过期时间
- 加互斥锁:只有一个线程查询数据