redis常用5种数据类型及其常见问题(缓存穿透,缓存击穿,缓存雪崩)
1.字符串(String)
2.哈希(hash):redis hash是一个string类型的字段和value的映射表,hash特别适合存储对象
3.列表(List):字符串列表,按照插入的顺序。可以添加一个元素到列表的头部或尾部
4.集合(set):String类型的无序集合。集合成员不可重复,redis中集合通过哈希表实现的,添加,删除,查找复杂度为O(1)
5.有序集合(sorted set):每个元素会关联一个double类型分数,redis通过分数进行从小到大的排序
redis缓存穿透
- 缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这导致不存在的数据每次请求都到存储去查询,失去缓存的意义
- 解决办法:接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截。从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写成key-null,缓存有效时间可以设置短点,这样可以防止攻击用户反复用同一个id暴力攻击
缓存击穿
- 指缓存中没有但数据库中有的数据(一般是缓存时间到期),这是由于并发用户特别多,同时读缓存没读到数据,同时去数据库中取数据,引起数据库压力瞬间增大,造成过大压力
- 解决办法
- 设置热点数据永远不过期
- 接口限流与熔断,降级。重要的接口做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用,进行熔断,失败快速返回机制
- 布隆过滤器。boolmfilter就是类似hash set,用于快速判断某个元素是否存在于集合中,其经典的应用场景就是快速判断一个key是否在某容器,不存在就直接返回。布隆过滤器的关键在于hash算法和容器大小
- 互斥锁:缓存中有数据,直接返回,缓存中没有数据,第一个进入的线程,获取锁并进入数据库取数据,在没释放锁之前,其他线程等待,防止都去数据库重复取数据
缓存雪崩
- 指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同,缓存击穿是并发查同一条数据,缓存雪崩是不同的数据都过期,很多数据库都查不到从而查询数据库
- 解决办法:
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中
- 设置热点数据永不过期