Heim  >  Artikel  >  Datenbank  >  Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

王林
王林nach vorne
2023-06-03 19:04:371406Durchsuche

Cache-Aufschlüsselung

Anders als die Cache-Penetration bezieht sich die Cache-Aufschlüsselung auf heiße Daten, die sich nicht im Cache, sondern in der Datenbank befinden.

Zum Beispiel: Heiße Nachrichten auf der Homepage, heiße Daten mit einer sehr großen Anzahl gleichzeitiger Besuche. Wenn der Cache abläuft und ausfällt, fragt der Server zu diesem Zeitpunkt die Datenbank ab Wenn gleichzeitig Anfragen an die Datenbank gestellt werden, kann es sein, dass diese sofort überlastet ist.

Zeichne ein einfaches Diagramm, wie unten gezeigt:

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

Lösung: DB-Abfrage plus verteilte Sperre #🎜 🎜#.

Entsperrte Situation

Bevor Sie das Problem lösen, werfen Sie zunächst einen Blick auf den unverarbeiteten Code und die Funktionsweise.

Produktdetailcode basierend auf der Produkt-ID abfragen

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

Leeren Sie den Redis-Cache und öffnen Sie ihn 5 Threads werden auf gleichzeitigen Zugriff getestet. Der Testcode lautet wie folgt:

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

Wir gehen davon aus, dass die Datenbank nur einmal abgefragt wird. und die nächsten vier Abfragen werden aus dem Redis-Cache abgerufen, aber das Ergebnis ist:

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert Es wird auch keine verteilte Sperre hinzugefügt, aber dieser Container wird gesetzt Großer Druck auf die DB.

Wenn es sich um einen einzelnen Server handelt, verwenden Sie einfach direkt die Synchronisierungssperre von Java

Wie die verteilte Redis-Sperre einen Cache-Ausfall verhindert

# 🎜🎜# Leider stellt das Backend normalerweise einen Cluster bereit und die Synchronisierungssperre von Java kann keine verteilte Sperre implementieren.

Redis verteilte Sperre behebt Cache-Ausfälle

Die in Java integrierte Sperre kann nur auf einer einzelnen Maschine angewendet und nicht verteilt werden,

Das können Sie Verwenden Sie Redis, um verteilte Sperren zu implementieren

.

Code nach dem Hinzufügen einer verteilten Sperre

//根据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();
	}
}

Starten Sie 5 Threads und greifen Sie gleichzeitig darauf zu:# 🎜 🎜#

Das obige ist der detaillierte Inhalt vonWie die verteilte Redis-Sperre einen Cache-Ausfall verhindert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen