実用的なアプリケーションでのデータキャッシュのRedisの原理

Redisの:MySQLはあなたがいると思いますか? 

MySQLの私はまだ彼を無視し、彼はのTomcatの非常に良いベースフレンズではないことを、私は目に喜ば見ていないではない知っていますか?これは私を責めることができますか?誰が彼はとても遅い作ったのですか?

私Redisの張大きな脂肪は、過去にこのシステムを配置し、それがシステムの応答速度を向上させることである、私は一時的にそれは、MySQLに接触しない、Tomcatは直接必要奪うしたい時はいつでも、メモリ内のデータを入れています。私はここにいるだけと言うだろうMySQLのTomcatにデータがないとき:「!男、ああ、データが教えて何のこのSQLの実装は」

MySQLは汚いトリックをプレイし続け、あきらめなかった、私はいつも彼のかつての栄光と状態を復元するために、殺したいと思いました。歴史のホイールは潮に対して行ってみたい、上ロールすることができ、Tangbidangcheああに等しいです!

時々私は本当に高いの同時アクセスが彼にダウンしているように、私は、キャッシュを削除したデータを配置する、彼を排出!それは彼らの職業倫理、特に大きな脂肪チャンが悪い種類の考え、またはそれを我慢することができます。

ハッカーの攻撃?

正午、Tomcatのスポットトラフィックいくつかの例外は、私が対処することができます前に、データのほとんどでその日は、この時間は、多数の要求は、ここでもRedisの中に自分のデータを取得することはできません!Tomcatのは、ヘルプMySQLを求めることを余儀なくされました:「デュードは、ここではSQLああだ、ここで再び1、そこにある......」

MySQLはとても、幸せ実行する喜びに満ち始め、彼はすぐに物事が右でないことを発見し、あなたがこれらのSQLを実行し、データベース内のデータを見つけることができません。彼は、Tomcatの不満は言った:「ブラザーは、あなたがたID = xxxxのSQLで見て、私を入れている、これらはデータベースIDの事には存在しません?。」

見上げなしのTomcat:「ここにはあり、SQLが来る......」

私は、MySQLは恨みにもかかわらず、非常に専門的であることを賞賛し、彼はの彼はすぐに疲れて、手紙に実装されています。

そのようなカタツムリ、できていない通常の要求処理として、システム全体を遅らせます。

張大きな脂肪急いではいくつかの調査の後、彼は高流量、MySQLのでは、確かにキャッシュに、その要求は実行するための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 意识到了我的价值,也不再唠唠叨叨了。

我这个缓存的容量是有限的,不可能无限制地增加,所以张大胖添加到缓存的数据有一个有效期,过了有效期,我就会把他删除,腾出空间,让别的数据使用。

如果是普通的缓存数据失效,那就罢了,大不了从数据库中再去一次就是了。

可是这一次,有个超级热门的数据失效了,Tomcat 组成的集群中有无数的线程都问我要数据,当我告诉他们这个数据已经失效以后,他们扭头便转向 MySQL,疯狂地发出 SQL 语句,问 MySQL 要数据。

MySQL 傻眼了,这么多的线程,每个要发出的 SQL 都是相同的,可是又不得不执行。

MySQL 又一次累倒了,我想他再次体会到了我的重要性。

他对 Tomcat 说道:“兄弟,给我发这么多的一模一样的 SQL,你想累死我啊! 你就不能控制一下?只让一个线程发查询过来,让其他的等待一下? 那个线程取到数据以后,其他线程就可以从缓存取了!”

Tomcat 觉得很有道理,可是现在系统中有多个 Tomcat,每个都是平等的,怎么去选出那个唯一的线程呢?

如果是在同一个 JVM 中还好办,轻轻松松用一把进程内的锁搞定, 可是这分布式的 Tomcat,每个都是一个 JVM,每个都是一个进程, 怎么搞?

我说:“这很简单,我 Redis 这里可以提供一个分布式的锁,谁获得了这把锁,谁就可以访问数据库。”

MySQL 佩服地说:“老弟真是不错,我服了你了,以后你一定要尽可能的把流量都给挡住,别往我这里发了,实在是太可怕了!”

Tomcat 补充到:“是啊,这 Redis 缓存太重要了!”

突然间他注意到了我还只有一台机器: “你现在怎么还是单台机器? 一个实例? 万一挂了怎么办? 一定得像我一样,搞集群,提高可用性啊!”

MySQL 说:“啊? 这多吓人,从今天开始,我将时时刻刻为你祈祷,上帝保佑,你千万别挂掉。”

与此同时,张大胖开始着手 Redis 集群了......

おすすめ

転載: www.cnblogs.com/tian20180415/p/11319895.html