Heim >Datenbank >Redis >Die Prinzipien und Implementierung gemeinsamer verteilter Sperren in Redis (Zusammenfassungsfreigabe)

Die Prinzipien und Implementierung gemeinsamer verteilter Sperren in Redis (Zusammenfassungsfreigabe)

WBOY
WBOYnach vorne
2022-08-25 11:53:502473Durchsuche

Empfohlenes Lernen: Redis-Video-Tutorial

Sperren in Java umfassen hauptsächlich synchronisierte Sperren und Sperren im JUC-Paket und sind für verteilte Umgebungen ungültig verteilte sperrenbasierte Implementierung?

Die Implementierung gängiger verteilter Sperren ist wie folgt:

Basierend auf der Datenbank

Pessimistische Sperre

Pessimistische Sperre (Pessimistische Sperre) ist, wie der Name schon sagt, eine sehr pessimistische Sperre, und das wird auch so sein wird bei jedem Datenabruf gesperrt. Auf diese Weise werden andere, die die Daten abrufen möchten, blockiert, bis die pessimistische Sperre aufgehoben wird. Die gemeinsam genutzten Ressourcen werden jeweils nur von einem Thread verwendet, und andere Threads werden blockiert In Bezug auf die Effizienz und Verarbeitung erzeugt der Sperrmechanismus jedoch zusätzlichen Overhead und ist anfällig für Deadlocks.

Implementierungsprinzip

Pessimistische Parallelitätskontrolle ist eigentlich eine konservative Strategie „Erst die Sperre und dann Zugriff erhalten“, die eine Garantie für die Sicherheit der Datenverarbeitung bietet.

Spezifische Implementierung

Zum Beispiel Inventar Der Abzug wird durch pessimistisches Sperren erreicht. Der Pseudocode lautet wie folgt:

// 对于库存记录进行行锁

SELECT *FROM sys_goods s WHERE s.Id='1' FOR UPDATE;

//执行库存扣减
update sys_stock s set s.stockQty=s.stockQty-#{number} where s.goodId=1 and s.stockQty>0;

//提交事务,自动释放悲观锁。

Optimistische Sperre

Einführung

Optimistische Sperre wird basierend auf dem Mechanismus der Datenversionsnummer (Version) implementiert. Beim Auslesen der Daten wird ein Feld „Version“ ausgelesen. Beim Updatevorgang werden die Versionsnummern verglichen und die Versionsnummer erfolgreich ausgeführt 1. Wenn die Versionsnummern inkonsistent sind, schlägt das Update fehl.

Implementierungsprinzip

Im Vergleich zum pessimistischen Sperren wird bei der Implementierung des optimistischen Sperrens nicht der Sperrmechanismus der Datenbank verwendet. Das Prinzip des optimistischen Sperrens wird mithilfe des CAS-Mechanismus (Compare-and-Swap) implementiert .

  • 1, Vergleich: Lesen Sie einen Wert A. Bevor Sie ihn auf B aktualisieren, prüfen Sie, ob der ursprüngliche Wert immer noch A ist (nicht von anderen Threads geändert).
  • 2, Einstellung: Wenn Wenn Die Änderung wird nicht gesendet, A auf B aktualisieren und beenden. Wenn eine Änderung eintritt, unternehmen Sie nichts.

Spezifische Implementierung

Der Pseudocode für optimistische Sperren zur Erzielung eines Bestandsabzugs lautet beispielsweise wie folgt:

// 查询库存记录,获取版本号
SELECT stockQty,version FROM sys_goods s WHERE s.Id='1'

//执行库存扣减,防止出现超卖
update sys_stock s set 
  s.stockQty=s.stockQty-#{number},
  s.version=version+1
  where s.goodId=1 and s.stockQty>0 and version=#{version};

Redis implementiert verteilte Sperren

Über die Implementierung der verteilten Redis-Sperre wurde in früheren Artikeln erläutert . Sie können sich auf den folgenden Artikel beziehen:

Spring Boot implementiert das Prinzip der verteilten Sperre von Redis.

Spring Boot integriert Redisson, um den detaillierten Fall einer verteilten Sperre zu implementieren Summe der Zookeeper-Knoten Um Ordnung zu erreichen.

Sperrvorgang

Wenn Client 1 eine Anfrage stellt, erstellt der Zookeeper-Client einen dauerhaften Knoten. Wenn Client 1 die Sperre erwerben möchte, erstellt er einen temporären Knoten /node_000000 unter dem Sperrknoten unter Sperren Ein geordneter untergeordneter Knoten erhält die Sperre erfolgreich, wenn er der kleinste Knoten ist.

Wenn Client 2 versucht, die Sperre zu erhalten, überprüft er auch die temporären Knoten unter Sperren, um festzustellen, ob sein eigener Knoten/Knoten_000001 der kleinste ist. Wenn er nicht der kleinste ist, schlägt der Erwerb der Sperre fehl und Client 2 sortiert es nach vorne. Der Knoten node_000000 registriert ein Überwachungsereignis, um zu überwachen, ob node_000000 vorhanden ist. Obwohl die Sperre fehlschlägt, wechselt node_000001 in den Wartezustand.

Der Vorgang zum Aufheben der Sperre

Wenn das Client-Geschäft von Zookeeper abgeschlossen ist oder der Client ausfällt, wird der temporäre Knoten gelöscht und die Sperre aufgehoben. Wenn die Aufgabe abgeschlossen ist, ruft Client 1 auch explizit die Anweisung zum Löschen von node_000000 auf.

In der obigen Abbildung ist beispielsweise Client 1 getrennt und der temporäre Knoten node_000000 wurde gelöscht. Zu diesem Zeitpunkt wird node_000001 durch die Watcher-Überwachung als kleinster temporärer Knoten erkannt, sodass die Sperre erfolgreich erworben wurde.

异常场景分析

客户端1创建临时节点后,会与Zookeeper服务器维护一个Session,这个Session会依赖客户端 定时心跳来维持连接。由于网路异常原因,Zookeeper长时间收不到客户端1的心跳,就认为这个Session过期了,也会把这个临时节点删除,此时客户端2创建临时节点能够获取锁成功。当客户端网络恢复正常后,它仍然认为持有锁,此时就会造成锁冲突。

具体实现

Zookeeper实现分布式锁,可以采用Curator实现分布式锁,关于SpringBoot如何集成Curator,大家可以参考如下文章:

Java Spring Boot 集成Zookeeper

Zookpeer实现分布式锁实现库存扣减

 @RequestMapping("/lockStock")
    public void lockStock()
    {
       zooKeeperUtil.lock("/Locks", 1000, TimeUnit.SECONDS, ()->{
           //业务逻辑
       });
    }

小结:

关于分布式锁的实现的对比,详情请查看下图:

推荐学习:Redis视频教程

Das obige ist der detaillierte Inhalt vonDie Prinzipien und Implementierung gemeinsamer verteilter Sperren in Redis (Zusammenfassungsfreigabe). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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