美文网首页
Redis一个办事很快,但是不靠谱的字典小兄弟

Redis一个办事很快,但是不靠谱的字典小兄弟

作者: 柠檬小猪 | 来源:发表于2022-03-18 19:07 被阅读0次

Redis(Remote Dictionary Server ),即远程字典服务

redis的起源是因为大佬觉得MySql慢,所以就自己弄了一个新数据库,所以有些MySql相似的地方也很正常。

一个有趣的发现,mysql缓存优化上说,最佳的情况就是数据全在缓存中;这样看redis就很符合这点。

既然是缓存数据库,那设计上和那些要写入磁盘的数据库就有很大的区别。

没有使用BTree

跳表:变种二叉树,空间换时间的典型,直接多了一组(或几组)数据。

字典hash(招牌):和hashMap很像,hashMap套hashMap

K-V结构,使用数组和链表保存数据(不会变二叉树);虽然查询快,但是也导致扩容的时候会卡,需要重新hash分配数据;所以注定它的数据量不能很多。

redis中是hashmap套hashmap,这样可以减弱一个过大的hashmap扩容导致的顿卡。

压缩表(ziplist):数组格式

特殊编码的连续内存块组成的顺序型数据结构;

压缩了什么?

数组需要预先申请空间,空间大小是类型的最大值;而压缩表是先知道要存什么,所以空间大小就是数据大小。那它没有修改功能吗?

sorted-set和hash元素个数少且是小整数或短字符串(直接使用);小规模的数据,可能修改的时候会重新生成新数组。

快速列表(quicklist):链表套套数组,和hashMap正好相反

quicklist是一个双向链表,链表中的每个节点时一个ziplist结构。

内容大小不同,储存类型不同会

根据储存内容的大小,自己切换储存类型。

比如:

当元素的个数比较多或元素不是小整数或短字符串时。使用字典

当元素的个数比较少,且元素都是小整数或短字符串时。使用压缩列表

单线程,但是现在有多线程特性

单线程为什么会快呢?第一个想到的是内存数据库不用读磁盘,省去了读盘阻塞时间;但是分布式环境更多的是网络等待。

RedisCluster官方集群解决方案,集群使用传染病协议

Redis3.0之后,Redis官方提供了完整的集群解决方案。

方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移)。称为RedisCluster。

Gossip(流行病)协议:特点是去中心化。感觉是一个弱一致性,又耗资源的协议。

那么RedisCluster是收到新数据后,马上向其他服务器传播,还是定时传播?

Gossip协议基本思想就是:一个节点周期性(每秒)随机选择一些节点,并把信息传递给这些节点。收到信息的节点会把信息继续传下去。

所以是定时传播。

传播哪些信息呢,是增量还是全量?

全量的话明显太慢了,我猜是增量。

节点A收到publish命令,节点A执行该命令,并向集群广播publish命令,收到publish命令的节点都会执行相同的publish命令。

这里看出是增量,只有新增节点会需要全量更新。

传播什么时候停止?

每个节点都会随机选一些节点传播,什么时候知道传播完成了?

Gossip协议并没有说最完美的解决方案;会停止会导致有些节点没更新(因为是随机选),不停止会消耗很多资源。

可以把以传播的节点剔除随机节点池,同时更新信息版本号,版本相同就不用执行更新但可以传播。解决的办法还是有很多的。

节点接收的数据怎么分配?

这里用到了一致性hash;一致性hash环的好处就是增减节点的时候不需要所有的节点都rehash,只需要附件的节点rehash就可以了。

redis-cluster把所有的物理节点映射到[0-16383]个slot上,基本上采用平均分配和连续分配的方式。

每个节点负责一部分slot,比如Redis1 负责接收 0-4000的信息;

哨兵其实就是租期模式

redis不会自己替换坏掉的master节点,需要借助哨兵(sentinel),哨兵会定期用心跳包检查master状态,如果master坏了,就换一个顶上。

没有操作日志

和MySql完全不一样。

不会每一个操作都保持日志,类似的东西是RBD(Redis DataBase),用来数据持久化的东西;定期保存数据库的快照,就是很不安全的样子。

持久化只是恢复备份。

事务和LUA脚本语言操作

redis的事物是弱事务,不能回滚(说白了就是命令集);不推荐用redis来处理事务。

推荐使用脚本来操作redis,脚本操作就等同于Redis的事务了。

Redisson分布式锁

分布式锁说白了就是在Redis中插入一条数据,标明是哪个客户端插入的,这个客户端就拥有了锁;其他客户端要做这个事之前都要去redis看看能不能拿到锁。

一般只有拿锁的客户端可以归还,但是考虑到分布式环境,客户端可能出了意外,所以锁都有超时时间。

本着来都来了的原则,可重入锁出现了,既然这个客户端已经拿到锁了而且还没还,那他还要继续再办一件事也是可以的,锁的计数+1,还锁就变成了锁的计数-1。

但是啊但是,redis集群并不是强一致性啊,我找的redis和你找的redis不是同一个,并且他们还没有同步到数据,以为锁空闲,结果我和你都拿到了锁。根据上面的流行病协议弱一致性AP,在redis集群下分布式锁就不那么好用了。所以还是用zookeeper吧。

淘汰策略

内存总是有限的,这时候需要删除一些不常用的数据,这里的策略和mysql挺像的;

LRU (Least recently used) 最近最少使用:使用链表,新增,更新和查看都会把数据移动到链表头部;超过容量就删除队尾数据。

LFU (Least frequently used) 最不经常使用:这个和次数有关(上面的是跟时间有关),根据使用次数排序,最少的删除。

三个缓存问题

缓存穿透

就是穿过缓存去数据库拿数据;好像也没什么不对呀。

如果一万个人同时要拿这个数据,但是这个数据刚好缓存里没有,这样数据库就有一万个访问了;其实有一个就行了,拿到数据存进缓存,然后其他9999个访问从缓存拿。怎么解决这个问题呢?

使用布隆过滤器:基于hash算法,把查询key散列后会得到一个值,如果数组中这个值的下标值为1,说明缓存中有这个key要查的数据。

看上去不靠谱啊,hash很容易冲突的;所以我们多使用几种hash算法,比如:hashA(key)=1,hashB(key)=5,hashC(key)=8,如果下标1,5,8的值都为1,那这个key要查的数据就在缓存中;根据数据大小可以增加hash算法,虽然做不到100%精确。

怎么使用布隆过滤器呢?

在缓存之前在加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回,存在再查缓存和DB。虽然解决了缓存穿透的问题,但是查不到数据了!不解决问题反而把提出问题的人解决了。

当然只需要简单设计一下就行了,比如设置同一个查询可以穿透的访问数量。

缓存雪崩

突然间大量的key失效了或redis重启;

和上面的危害是一样的,都是大量访问数据库,不过原因不一样,处理手段就不一样了。

解决方案:

1、 key的失效期分散开 不同的key设置不同的有效期(这个比较科学)

2、设置二级缓存(数据不一定一致)

3、高可用(脏读)

缓存击穿

如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题;

热key过期导致的;热key为什么会过期?淘汰策略里怎么也轮不到热key啊!设计有问题才会触发这种事吧。

首先这个布隆过滤器拦不住,因为本来有,但是访问的时候过期了。

1.设置key没有过期时间。(末位淘汰就好了,干嘛要过期时间)

2.设置互斥锁,让其他线程等待

其实这些缓存问题加上熔断器就可以解决了,熔断器的舱壁机制,可以给每个请求设置每秒访问数量;这样无论如何都不会崩溃了。

还有就是幂等处理,穿透和击穿查询的都是同一个key,如果要查询一个缓存里没有的key可以让查询先等待,然后起个线程去数据库里拿,并插入一条带这个查询参数的数据状态是已经在查了,这时候如果还有相同查询进来,检查查询状态,一起等待数据进入缓存,然后在缓存中查询。

延迟双删

保证数据的最终一致性(延时双删),解决缓存和DB的数据不一致

1、先更新数据库同时删除缓存项(key),等读的时候再填充缓存

2、2秒后再删除一次缓存项(key)

3、设置缓存过期时间 Expired Time 比如 10秒 或1小时

4、将缓存删除失败记录到日志中,利用脚本提取失败记录再次删除(缓存失效期过长 7*24)

订阅监听

Redis客户端通过执行MONITOR命令可以将自己变为一个监视器,实时地接受并打印出服务器当前处理的命令请求的相关信息。

127.0.0.1:6379> monitor

可以监听到别的客户端的操作。

Redis怎么做MySql的缓存?

导入maven包,SpringBoot直接配置即可;mybatis二级缓存兼容redis,默认开启,使用redis;redis以查询条件为key,mysql缓存也是以查询条件为key。

相关文章

  • Redis一个办事很快,但是不靠谱的字典小兄弟

    Redis(Remote Dictionary Server ),即远程字典服务 redis的起源是因为大佬觉得M...

  • 心情:不靠谱的飞机

    不靠谱的飞机 老家有一句称呼办事情没有定数人的话叫“不靠谱”,意思是...

  • 亲家办事不靠谱

    大孙子满月,我家举办满月宴。 儿媳娘家人我自是不能怠慢,一周前,我就给亲家打电话,问他们那边能来多少人,我订酒店时...

  • 如何成为靠谱的职场人?

    我们经常说年轻人:嘴边没毛办事不牢。 意思就是说这个人办事不靠谱。 那什么是办事靠谱呢? 所谓的靠谱,用一句话来说...

  • 不靠谱

    看一个企业或者一个公司靠不靠谱,你要看他的人事部门办事能力与责任心 如果一个企业的人事作风很不靠谱,那么这个企业迟...

  • 严肃的爱情不靠谱

    严肃的爱情不靠谱 浪漫的爱情不靠谱 稚嫩的爱情不靠谱 单恋的爱情不靠谱 唐突的爱情不靠谱 爱情不靠谱

  • 你是什么样的人就交什么样的朋友

    一个靠谱的人给你介绍的朋友,合作起来就是人品好办事靠谱而一个不靠谱的人给你介绍一个朋友或者一个同事,也能碰到靠谱的...

  • 靠谱与不靠谱

    从来不觉得自己是一个靠谱的人,我码不靠谱的文字,做不靠谱的事情,谈不靠谱的恋爱,养不靠谱的鱼,种不靠谱的花,甚至开...

  • 靠谱

    这些年体会最深的是, 一个靠谱的人给你介绍的朋友, 合作起来就是人品好, 办事靠谱的人。 而一个不靠谱的人 给你介...

  • 中国式众筹之再谈靠谱

    中国式众筹之再谈靠谱!一个靠谱的人给你介绍的朋友,合作起来就是人品好,办事靠谱的人。而一个不靠谱的人给你介绍一个朋...

网友评论

      本文标题:Redis一个办事很快,但是不靠谱的字典小兄弟

      本文链接:https://www.haomeiwen.com/subject/dyzqlrtx.html