Redis:MySQL算老几?

作者:网友投稿 时间:2018-11-05 16:22

字号

前言:上一篇《MySQL:缓存算什么东西?》里挖了一个坑,也有很多人说没看过瘾,今天接着写,把坑填上,不过得把视角换一下,让Redis上台发言。

我知道MySQL看我不顺眼,不就是他的好基友Tomcat不怎么搭理他了吗? 这能怪我? 谁让他那么慢?

张大胖把我Redis安排到这个系统中来,那就是为了提升系统的响应速度,我把数据都暂时放到了内存中,每当Tomcat需要的时候直接拿走就是了,都不用联系MySQL。只有我这里没有数据的时候Tomcat才会给MySQL说一句:“哥们,把这个SQL执行一下啊,把数据告诉我!”

Redis:MySQL算老几?

MySQL不死心,不断使坏,总想着把我给干掉,恢复他昔日的荣耀和地位。可历史的车轮滚滚向前,想逆潮流而动,无异于螳臂挡车啊!

有时候我真想把我缓存中的数据删除,让高并发的访问都压到他那里去, 累死他! 可一想到自己的职业道德,尤其是张大胖那可怜样,还是忍了吧。

黑客攻击?

这一天中午,Tomcat发现流量有些异常,之前大部分的数据我都可以处理,这一次大量的请求在我Redis这里竟然获取不到数据! Tomcat被迫向MySQL求援:“哥们,这儿有一个SQL啊, 这儿还有一个, 又来一个......”

MySQL刚开始非常高兴,满心欢喜地去执行,可是他很快就发现事情不对, 执行完这些SQL,在数据库中也查不到数据。他不满地对Tomcat说:“兄弟,你这是在折腾我吗? 你看看你这个SQL中where ID = xxxx, 这些ID在数据库都不存在嘛。”

Tomcat头也不抬:“又来一个SQL, 还有一个......”

让我比较佩服的是, MySQL还是比较职业的,尽管有怨气,他还是不折不扣地执行,很快他就累到了。

整个系统慢如蜗牛,连正常的请求也处理不了。

张大胖赶紧介入,经过一番调查,他发现很多请求故意去查询那些一定不存在的数据,缓存中肯定没有,于是请求一定会发到MySQL去执行,在流量大时,MySQL就挂掉了。

换句话说:在黑客的精心算计之下,我这个缓存成了摆设,缓存被穿透了!

Redis:MySQL算老几?


Redis:MySQL算老几?

张大胖把此事定性为黑客攻击。

缓存空值

这一次,MySQL终于意识到了我的价值,他出了一个主意:“Redis同学,你把那些不存在的key和对应的空值也缓存下来不就行了?下次访问,就直接返回一个null给这些黑客,别再来找我了。”

我一听就知道这是个馊主意:“这些key在你那里都不存在,还让我缓存,那不就是要浪费我的空间吗? 张大胖给我分配的空间是有限的啊。”

“你不是可以设定数据的有效期嘛,比如过3分钟就过期,删除它,空间不就腾出来了。”

“那在这三分钟内,如果这个key对应的数据真的被加入到了你MySQL当中,那岂不就不一致了?!” 我问道。

MySQL说道:“如果发生这种情况,就可以想办法清除掉缓存中的数据,只是程序逻辑就变得复杂了......”

“退一步来说,假设我缓存了他们,那黑客完全可以换一些新的key来攻击啊!缓存中还是没有,还得去你那里查,这个办法不妥!” 我下了结论。

布隆过滤器

MySQL说:“如果能事先得知这个key是不是在数据库存在就好了,可是想知道是否存在,那就得把所有的key都放到缓存中,Redis,你能受得了吗?”

我当然受不了。

Tomcat眼前一亮:“你们听说过布隆过滤器没有?”

我说:“当然知道了,这是个神奇的数据结构,只需要极少的空间就可以判断一个元素是不是在一个集合之内,这正好是我们所需要的场景啊:判断key是否存在。”

(码农翻身注:布隆过滤器大家可以参考相关资料,这里不再展开。)

Tomcat说:“对,比如我们可以把所有的用户ID建立一个布隆过滤器,这样当那些黑客的请求过来以后,先用这个过滤器拦截一下,如果黑客要访问的用户ID不在这个过滤器中,我们就直接把他踢出去了。”

MySQL也是经验丰富:“可是这个Bloom Filter有误报啊,即使某个用户ID不在集合中,他也可能报告说在集合中。这个时候Tomcat就认为这是一个合法的用户ID,就去Redis中查,不存在,然后到我这里查,还是不存在。”

我说:“哎呀,一定的误报也是允许的,没有完美的事情,总要付出代价不是?”

大家都表示同意。

数据失效

黑客的攻击的威胁解除了,日子又恢复了平静,MySQL意识到了我的价值,也不再唠唠叨叨了。

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>Redis MySQL Tomcat
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接