Redis 分散ロックがキャッシュの破損を防ぐ方法

王林
リリース: 2023-06-03 19:04:37
転載
1284 人が閲覧しました

キャッシュ ブレークダウン

キャッシュ ブレークダウンとの違いは、キャッシュ ブレークダウンは、キャッシュには存在しないがデータベースに存在するホット データを指すことです。

例: ホームページ上のホットなニュース、同時アクセス数が非常に多いホットなデータ、キャッシュの有効期限が切れて失敗すると、サーバーは DB にクエリを実行します。このとき、同時アクセス数が多ければ、 DB に対してクエリが実行されると、DB は即座に圧倒される可能性があります。

以下に示すような簡単な図を描きました:

Redis 分散ロックがキャッシュの破損を防ぐ方法

解決策: DB クエリと分散ロック

ロックが解除された状況

問題を解決する前に、まず未処理のコードと動作状況を確認します。

製品 ID に基づいて製品の詳細コードをクエリします

Redis 分散ロックがキャッシュの破損を防ぐ方法

Redis キャッシュをクリアし、同時アクセス テスト用に 5 つのスレッドを開きます。コードは次のとおりです。

Redis 分散ロックがキャッシュの破損を防ぐ方法


DB へのクエリは 1 回だけ行われ、次の 4 つのクエリは Redis キャッシュからフェッチされると予想していましたが、結果はは:
Redis 分散ロックがキャッシュの破損を防ぐ方法
分散ロックはなく、結果は期待通りですが、コンテナは DB に多大な負荷をかけます。

単一サーバーの場合は、Java の同期ロックを直接使用してください。

Redis 分散ロックがキャッシュの破損を防ぐ方法

残念ながら、通常はクライアントがクラスターをデプロイすると、Java の同期ロックは分散ロックを実装できません。

Redis 分散ロックはキャッシュの故障を解決します

Java の組み込みロックは単一のマシンにのみ適用でき、分散することはできません。これは Redis を使用して実現できます。ロック###。

#分散ロックを追加した後のコード

//根据ID查询商品
@GetMapping("/{id}")
public R id(@PathVariable String id){
	//先查Redis缓存
	Object o = redisTemplate.opsForValue().get(id);
	if (o != null) {
		//命中缓存
		System.err.println("id:"+id+",命中redis缓存...");
		return R.success(o);
	}

	//缓存未命中 查询数据库
	String lockKey = "lock" + id;
	//加锁,10s后过期
	for (;;) {
		if (redisTemplate.opsForValue().setIfAbsent(lockKey, System.currentTimeMillis(), 10L, TimeUnit.SECONDS)) {
			//加锁成功的线程,再次检查
			o = redisTemplate.opsForValue().get(id);
			if (o != null) {
				//命中缓存
				System.err.println("Thread:" + Thread.currentThread().getName() + ",id:"+id+",命中redis缓存...");
				//释放锁
				redisTemplate.delete(lockKey);
				return R.success(o);
			}

			//仍未命中
			System.err.println("Thread:" + Thread.currentThread().getName() + ",id:" + id + ",查询DB...");
			Goods goods = goodsMapper.selectById(id);
			//结果存入Redis
			redisTemplate.opsForValue().set(id, goods);
			//释放锁
			redisTemplate.delete(lockKey);
			return R.success(goods);
		}
		//竞争不到锁,暂时让出CPU资源
		Thread.yield();
	}
}
ログイン後にコピー

同時アクセス用に 5 つのスレッドを開始します。結果は次のとおりです:

以上がRedis 分散ロックがキャッシュの破損を防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!