内訳: は、キャッシュ内で見つからない単一のキーを指します。データベースにアクセスしてクエリを実行するため、データ量が大きくない場合や、同時実行性は大きくないので、何が問題なのかという問題は発生しません。
データベースのデータ量が大きく同時実行性が高い場合、データベースが過負荷になり崩壊する可能性があります。
注: これは高を指します。同時実行は 1 つのキーに対して発生します!!! (推奨される学習: Redis ビデオ チュートリアル )
解決策:
1) 同期された二重チェックを通じてメカニズム: 特定のキーは 1 つのスレッドのみにクエリを許可し、他のスレッドをブロックします。
同期ブロックでは、DB をチェックする前に、そのキーが存在しないことを確認し続けます。
例:
private static volaite Object lockHelp=new Object(); public String getValue(String key){ String value=redis.get(key,String.class); if(value=="null"||value==null||StringUtils.isBlank(value){ synchronized(lockHelp){ value=redis.get(key,String.class); if(value=="null"||value==null||StringUtils.isBlank(value){ value=db.query(key); redis.set(key,value,1000); } } } return value; }
欠点: 他のスレッドをブロックします
2 ) 値を無期限に設定します
この方法は最も信頼性が高く安全であると言えますが、スペースを占有し、大量のメモリを消費し、データを維持できません。現在までです。これは特定のビジネス ロジックに基づく必要があります。
# を行うには、データを最新の状態に保ちたい場合は、これを試してみてください。参考のみ:
3) 相互排他ロック (ミューテックス キー) を使用します
public String get(key) { String value = redis.get(key); if (value == null) { //代表缓存值过期 //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表设置成功 value = db.get(key); redis.set(key, value, expire_secs); redis.del(key_mutex); return value; } else { //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可 sleep(10); get(key); //重试 } } else { return value; } }
Redis データベース使用法チュートリアル を参照してください。学習のために!
以上がRedis の故障を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。