Redis的一些常见题
redis数据类型及应用场景 见 Redis的五种数据类型及使用场景
redis持久化及过期策略 见 Redis持久化及过期删除策略
redis 常见问题及解决方案
缓存雪崩:同一时间大量缓存失效,导致请求直接查询数据库,数据库内存和CPU压力增加甚至宕机
解决:
热点数据永不过期或者分布到不同实例,降低单机故障问题
缓存时间添加随机数,防止大量缓存同时失效
做二级缓存或者双缓存,A为原始缓存 短时效,B为备份缓存 ,长期有效。更新时候双写缓存缓存穿透:缓存和数据库都没有数据,大量请求下,所有请求直接击穿到数据库,导致宕机。
解决:
布隆过滤器:长度为m的位向量或者位列表组成(仅包含0或1位值的列表)
使用多个不用的hash函数,产生多个索引值,填充对应多个位置的值为1
布隆过滤器可以检查值是 “可能在集合中” 还是 “绝对不在集合中”
可能误判但是基础过滤效率高
极端情况,当布隆过滤器没有空闲位置的时候每次查询返回true
空缓存(短时效)
业务层参数过滤缓存击穿:数据库中有数据,但是缓存突然失效之后发生大量请求导致数据库压力增加甚至打垮宕机
解决: 热点数据永不过期
互斥锁:获取锁之后不管成功还是失败都要释放锁
Redis主从复制原理 Redis 在复制时底层采用的是 psync 命令完成的数据主从同步,同步主要分为:全量复制和增量复制两种
- 全量复制:顾名思义也就是一次性把主节点数据全部发送给从节点,所以这种情况下,当数据量比较大时,会对主节点和网络造成很大的开销。
- 部分复制:用于处理主从复制时因网络中断等原因造成数据丢失的场景。当从节点再次和主节点连接时,主节点会补发丢失的数据。因为是补发,所以在发送的数据量一定是小于全量的数据。
详细见 Redis的一些常见题
Redis缓存和数据库数据一致性问题:
- 读数据
- 尝试查询缓存,存在缓存则直接返回数据
- 缓存不存在时则查询数据库,并保存到缓存(合适设置过期时间),返回数据
- 写数据
- 先更新缓存再更新数据库 或者 先删除缓存再更新数据库
- 先更新数据库再更新缓存 或者 先更新数据库再删除缓存
- 使用删除还是更新?
- 这里无非是删除还是更新Redis,直接删除的方式比较简单,在下一次查询时会生成缓存(更推荐);更新缓存则相较复杂
- 先操作Redis还是先操作数据库?
- 先操作数据库 (推荐)
- 流程:先更新数据库,再删除缓存
- 问题:比如线程1执行写操作(修改数据库->删除缓存),线程2执行读操作(查询缓存->旧数据),就会出现旧数据返回,或者删除缓存失败也会返回旧数据
- 先操作缓存
- 流程:修改操作先删除缓存再修改数据库
- 问题: 比如线程1去执行写操作: (删除缓存->更新数据库)同时有线程2执行读操作(查询缓存(未查到缓存)->查数据库->保存到缓存)因为数据库更新有可能网络延迟等问题,这里保存到缓存的数据就是旧的数据,只有再过期之后才会读到新数据
- 解决方案: (延迟双删)在数据库更新之后再进行一次缓存删除(加适当延迟,比如延迟500ms),这时再有查询过来也会查询到数据库并保存到缓存。但是线程2在这个删除缓存500ms内请求仍然可能会出现一次获取到旧数据 (推荐方式)
- 先操作数据库 (推荐)
- 读数据