使用场景
1、缓存:加速数据的访问,减少对后端数据库的负载。
2、会话管理:存储用户会话信息。
3、排行榜:处理诸如点击量、评分等数据的排名。
4、发布/订阅:实现消息的发布和订阅。
5、计数器:用于计数,如文章的阅读量等。
redis数据类型
- 5 种基础数据类型:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
- 4 种特殊数据类型:HyperLogLog(基数统计)、Bitmap (位图)、Geospatial (地理位置)、Stream(消息队列)。
缓存击穿
举个例子:查询某个热点商品的折扣,redis缓存过期,导致大量请求访问数据库。
方案1:热点数据不设置过期时间
热点数据不设置过期时间,当后台更新热点数据数需要同步更新缓存中的数据,这种解决方式适用于不严格要求缓存一致性的场景。
方案2:使用互斥锁
如果是单机部署的环境下可以使用synchronized或lock来处理,保证同时只能有一个线程来查询数据库,其他线程可以等待数据缓存成功后在被唤醒,从而直接查询缓存即可。如果是分布式部署,可以采用分布式锁来实现互斥。
缓存穿透
举个例子:查询一些不存在的商品折扣,redis缓存中没有,导致大量请求访问数据库。
方案1:缓存空值(不推荐)
当查询一条不存在的数据时,在缓存中存储一个空对象并设置一个过期时间(设置过期时间是为了避免出现数据库中存在了数据但是缓存中仍然是空数据现象),这样可以避免所有请求全部查询数据库的情况。
方案2:布隆过滤器
布隆过滤器可以简单的理解为由一个很长的二进制数组结合n个hash算法计算出n个数组下标,将这些数据下标置为1。在查找数据时,再次通过n个hash算法计算出数组下标,如果这些下标的值为1,表示该值可能存在(存在hash冲突的原因),如果为0,则表示该值一定不存在。
缓存雪崩
与缓存击穿不同的是,缓存击穿是单个热点数据过期,而缓存雪崩是大批量热点数据过期。
举个例子:高并发查询商品折扣时,大量商品折扣redis缓存同时过期、redis服务器故障、缓存过载,导致大量请求访问数据库。
方案1:设置随机的过期时间
方案2:不设置过期时间
方案3:搭建高可用redis集群
数据一致性问题
当一条数据存入缓存后,立刻又被修改了,那么这个时候缓存该如何更新呢。不更新肯定不行,这样导致了缓存中的数据与数据库中的数据不一致。一般情况下对于缓存更新有下面这几种情况:
- 先更新缓存,再更新数据库
- 先更新数据库,再更新缓存
- 先删除缓存,再更新数据库
- 先更新数据库,再删除缓存
方案:延时双删
延时双删,即在写数据库之前删除一次,写完数据库后,再删除一次,在第二次删除时,并不是立即删除,而是等待一定时间在做删除。
大key、热key问题
参考:
《我们一起进大厂》系列-Redis哨兵、持久化、主从、手撕LRU