当前位置: 首页 > 科技观察

我是Redis,我的兄弟MySQL被我干掉了!

时间:2023-03-16 16:39:41 科技观察

我是Redis大家好,我是Redis,一个叫Antirez的人把我带到了这个世界。说起我的出生,和关系型数据库MySQL有很大的关系。在我来到这个世界之前,MySQL的日子不好过,互联网发展的越来越快,它容纳的数据越来越多,用户请求也暴增,每一个用户请求都变成了对它的一次读写操作,MySQL很惨。尤其是“双十一”和“618”这几天全民疯狂购物的日子,MySQL更是苦不堪言。据MySQL后来告诉我的,其实超过一半的用户请求都是读操作,他们经常重复查询一件事情,浪费了大量的磁盘I/O时间。后来有人疑惑,是不是可以学习CPU,给数据库加个缓存呢?于是我诞生了!出生后不久,我就和MySQL成了好朋友,我们经常携手出现在后端服务器。应用程序向MySQL查询的数据要在我这里注册,以后要用到的时候先问我,我不会再问MySQL了。为了方便使用,我支持几种数据结构的存储:StringHashListSetSortedSetBitmap······因为我把注册的数据全部记录在内存中,没有执行慢速的I/O操作,所以节省了很多找我的时间比找MySQL还多。别小看这个简单的改动,我可以减轻MySQL的负担!随着程序的运行,我缓存的数据越来越多,相当一部分时间我都阻塞了用户的请求,这回真是太好玩了!随着我的加入,Web服务的性能有了很大的提高,这要归功于我对数据库进行了大量的测试。CacheExpiration&&CacheRetirement但是很快我发现事情不妙。我缓存的数据是在内存中的,但是即使在服务器上,内存空间资源还是很有限的,不能这样毫无节制的保存。我得想办法,不然我就吃枣丸了。很快,我想到了一个办法:给缓存的内容设置一个超时时间,具体的设置交给应用程序。我所要做的就是删除我的过期内容并及时腾出空间。.有了超时,我应该什么时候进行清理?最简单的方法是定期删除。我决定每100ms做一次,也就是每秒10次!清理的时候无法清除所有过期的我这里存了很多数据,如果要全部扫描一遍不知道要多久,会严重影响接收新的客户要求!时间紧,任务重,只好随机抽取一些。清理可以缓解内存压力。就这样过了一段时间,发现有些key值是幸运的,每次都没有被我的随机算法选中,每次都活下来了。内存空间小!震撼而冰冷!眼睛里的沙子我擦都擦不掉!所以在原来定时删除的基础上,我又加了一个技巧:那些逃过我的随机选择算法的键值,一旦遇到查询请求,删除我发现它已经过期了,所以我会毫不犹豫地立即删除它.因为这个方法是被动触发的,不查询就不会发生,所以也叫懒删除!但是还是有一些键值逃过了我的随机选择算法,没有被查询到,导致一直逍遥法外!与此同时,可用的内存空间越来越少。而且我就算退一步说,我可以删除所有过期的数据,那么如果过期时间设置的时间长了,还没来得及清理,内存就满了,我还是得吃枣丸,所以我得想个办法。苦思冥想半天,终于想出了一个大招:内存淘汰策略,这次我要彻底解决问题!我提供了8种策略供应用选择,用于遇到内存不足时如何决策:noeviction:返回错误,不会删除任何key值allkeys-lru:使用LRU算法删除最近最少使用的keyvaluevolatile-lru:使用LRU算法,从有过期时间的key集合中删除最近最少使用的keyvalueallkeys-random:随机删除所有key中的volatile-random:随机删除具有anexpirationtimeset:从设置过期时间的keys中删除剩余时间最短的keyvolatile-lfu:从配置过期时间的key中删除allkeys中最不常用的keys-lfu:删除最不常用的keysfromallkeys有了上面的组合拳,再也不用担心过期数据太多填满空间的问题了~缓存穿透&&Bloomfilter的生活还是挺惬意的ble,不过小弟MySQL没有我舒服。有时候会遇到一些烦人的请求,查询的数据不存在,MySQL会白忙活!不仅如此,因为它不存在,我也无法缓存它。结果每次来同样的请求,都得让MySQL白忙活。我作为缓存的价值还没有体现出来!这就是人们常说的缓存穿透。一来二去,MySQL大哥就忍不住了:“哎,大哥,能不能帮我想办法屏蔽掉那些我知道不会有结果的查询请求?”这时,我想到了我的另一个好朋友:Bloomfilter这位朋友没有别的技能,但是擅长从一个大数据集中快速告诉你你要找的数据是否存在(悄悄告诉你,我朋友是有点不靠谱,它告诉你它是否存在你不能全部相信,事实上它可能不存在,但如果它告诉你它不存在,它一定不存在)。给这位朋友介绍了应用程序,再也不用用不存在的数据去烦MySQL了,轻松帮助解决了缓存穿透的问题。Cachebreakdown&&cacheavalanche之后,有一段平静的生活,直到那天...有一次,MySQL小哥悠闲的钓鱼,突然一大堆请求找上门来,他叫我措手不及。忙活了一会儿,MySQL气呼呼地找到我,“哥,怎么回事,怎么来的这么突然?”我查看了日志,连忙解释道:“大哥,真的很抱歉,刚来了一个热点数据,过期时间被我删掉了,可惜后来有大量查询这个数据的请求,我这里删了,所以所有的请求都发送给你。”“你干什么?,下次注意点”,MySQL小哥一脸不爽的离开了。这件小事本来也没怎么放在心上,后来也就抛在脑后了,没想到几天后,我又捅了一个更大的筐。那天又向MySQL发送了大量的网络请求,比之前的多了很多。MySQL哥过段时间宕机了好几次!这一波流量过了很久才过去。MySQL松了一口气。“哥,这次是什么原因?”,MySQL哥累得没力气了。“这一次比上次倒霉,这一次大量的数据几乎同时过了有效期,然后对这些数据的请求也很多,所以比上次大。”MySQL小哥听了,皱起了眉头。皱纹,“那你就想办法隔两天折磨我一次,谁受得了?”让他均匀设置缓存过期时间?至少不要让大量数据集体失效。”“走吧,我们一起走。”后来,我们去申请讨论。热点数据设置为永不过期,缓解了很多这个问题。哦,对了,我们还把这两个问题分别命名为缓存击穿和缓存雪崩。我们终于又过上了舒适的生活……本文转载自微信公众号“编程技术宇宙”,可以通过以下二维码关注。转载本文请联系编程技术宇宙公众号。