redis是什么
redis是key-value数据库, 支持数据持久化, 支持list、hash、set数据结构
使用场景
a. 削峰
常见的秒杀活动中并发请求量会非常大,为了防止我们DB宕机,需要通过中间件进行削峰限流。很简单一个应用方法,前端接受10000/s的并发请求,而后端接口只能处理100/s并发请求,那么将前端的并发请求扔到redis队列中缓存起来,最大不超过100个
b. 热数据
一些系统频繁请求的数据存放到redis中减少DB压力。举个例子:每个系统中都会有字典数据,这些数据不会经常变但是访问特别频繁,将这些数据存放到redis中加快访问速度减少DB压力
c. 计数器
利用redis提供的递增和递减命令实现计数器功能, 例如:计算用户请求某个接口次数
d. 分布式锁
分布式服务中需要对某个资源进行保护,保证不会产生并发,通过redis的分布式锁实现
redis功能
a. 数据缓存
b. 数据持久化
c. 哨兵、复制
高可用,主从同步,主库挂了哨兵自动切换备库
d. 集群
redis优劣势
a. 优势
- 因为redis为单线程,不存在多进程或者多线程导致的切换而消耗CPU
- 直接读取内存, 性能快
d. 劣势
- 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善
redis 常用问题
缓存穿透
介绍
缓存穿透是指缓存服务器中没有缓存数据,数据库中也没有符合条件的数据,导致业务系统每次都绕过缓存服务器查询下游的数据库,缓存服务器完全失去了其应用的作用, 下游的数据库很容易宕机
解决方案
- 当查询数据库没有数据默认给缓存value设置 null 过期时间为5s或者2s具体看场景。
- 布隆过滤器(Bloom Filter):可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。
缓存击穿
介绍
缓存击穿是指当某一key的缓存过期时大并发量的请求同时访问此key,瞬间击穿缓存服务器直接访问数据库,让数据库处于负载的情况。解决方案
- 异步定时更新:某一个热点数据的过期时间是1小时,那么每59分钟,通过定时任务去更新这个热点key,并重新设置其过期时间
- 互斥锁:在缓存处理上,通常使用一个互斥锁来解决缓存击穿的问题。简单来说就是当Redis中根据key获得的value值为空时,先锁上,然后从数据库加载,加载完毕,释放锁。若其他线程也在请求该key时,发现获取锁失败,则先阻塞。
缓存雪崩
介绍
缓存数据在相近时间大量过期或者缓存服务宕机,导致并发请求在某一时刻全部落到DB,导致DB宕机。解决方案
- 过期时间随机生成
- 热点数据永不过期
- 缓存服务集群化部署,避免服务单机故障
缓存更新策略
- 对一致性要求不高就设置缓存过期时间, 根据业务具体情况设置5分钟等
对一致性要求非常高:
先删除缓存,再更新数据库。 解决方案延时双删,步骤:
- 线程1删除缓存,然后去更新数据库
- 线程2来读缓存,发现缓存已经被删除,所以直接从数据库中读取,这时候由于线程1还没有更新完成,所以读到的是旧值,然后把旧值写入缓存
- 线程1,根据估算的时间,sleep,由于sleep的时间大于线程2读数据+写缓存的时间,所以缓存被再次删除
- 如果还有其他线程来读取缓存的话,就会再次从数据库中读取到最新值
先更新数据库,再删除缓存。
- 解决方案引入消息队列(太复杂,不推荐)
redis常用命令
链接远程redis
1
redis-cli -h 主机 -p 端口 -a 密码
选择具体数据库, 一共有16个
1
select 0
获取key value
1
get key ---> get NODE_BIGOLIVEE_BFF:abcdc
获取hash value
1
hmget key NODE_BIGOLIVEE_BFF:abcdc
获取redis key 过期时间
1
ttl NODE_BIGOLIVEE_BFF:abcdc
设置redis key 过期时间
1
expire NODE_BIGOLIVEE_BFF:abcdc 30 // 设置30秒后过期