redis学习
redis的五个基本数据类型。
redis字符串(String)
string是redis最基本的类型,一个key对应一个Tvalue。
string类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M
redis列表(List)、
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
它的底层实际是个双端链表,最多可以包含2^32- 1个元素(4294967295,每个列表超过40亿个元素)
redis哈希表(Hash)
Redis hash是一个string类型的field(字段)和 value(值)的映射表,hash 特别适合用于存储对象。
Redis中每个hash可以存储2个32-1键值对(40多亿)
redis集合(Set)
Redis的Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是intset或者hashtable。
Redis中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
集合中最大的成员数为2^32-1(4294967295,每个集合可存储40多亿个成员)
redis有序集合(ZSet、Sorted Set)
Redis zset和 set一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
zset集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。集合中最大的成员数为2^32-1(40亿)
主动更新策略
操作缓存和数据库时有三个问题需要考虑
1.删除缓存还是更新缓存?
? ? ? ? 更新缓存:每次更新数据库都要更新缓存,100个更新操作就要更新100次缓存,可能其中99个中间的数据版本没有一点作用,无效写的操作太多了。
? ? ? ??删除缓存:更新数据库时让缓存失效,查询时再更新缓存,这样子的效果较好,这种方案写的频率会更低,有效更新会更多。
2.如何保证缓存与数据库的操作的同时成功或者失败?
? ? ? ? 单体系统:将缓存与数据库操作放在一个事务
? ? ? ? 分布式系统:利用TCC等分布式事务方案
3.先操作缓存还是先操作数据库?
- 先删除缓存,再操作数据库
这种会出现缓存无效更新的情况,就是再删除缓存之后,更新数据库还未成功的时候,有查询请求查询缓存,未命中,就会查询数据库,此时因为数据库还未更新成功,查询到的值是未更新的值,最后将这个未更新的值写入缓存,最后当数据库更新成功之后,就出现了数据不一致的问题(这种情况出现的概率较高) - 先操作数据库,再删除缓存
这种也会出现缓存无效更新,当我接收到更新数据库的请求的时候,还没有将数据库的数据更新完,此时一条查询语句打到redis,并且此时刚好数据过期,未命中,就会去查询数据库,此时查询到的数据是还未修改的旧数据,然后更新操作结束,删除了缓存,最后查询请求将在数据库中查到的数据写入缓存,这个数据是数据库未更新前的数据,就出现了数据不一致的问题(这种情况出现的概率很小)
缓存面临问题
1.缓存穿透
缓存穿透是指客户端请求的数据再缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。
解决方案
- 缓存空对象
思路就是如果数据库中也没有这个数据,就将null存进redis中,这样后面的请求就不会达到数据库了。
优点:实现简单,维护方便
缺点:1.额外的内存消耗。2.可能造成短期的不一致
简单解决方案,就是对null的数据的TTL设置为很短时间,例如5分钟等 - 布隆过滤
思路就是请求先打到布隆过滤器中判断数据存不存在,存在就放行,不存在就拒绝请求继续下发。
优点:内存占用较少,没有多余的key
缺点:1.实现复杂(redis自带有)2.存在误判可能(不存在就真的不存在,存在不一定真的存在)。
2.缓存雪崩
缓存雪崩是指在同一时段大量的缓存key同时失效或者redis服务宕机,导致大量请求到达数据库,带来巨大压力。
解决方案
- 给不同的key的TTL添加随机值
- 利用redis集群提高服务的可用性
- 给缓存业务添加降级限流策略
- 给业务添加多级缓存
?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!