Heim >Datenbank >Redis >So verwenden Sie die optimistische und die pessimistische Sperre von Redis

So verwenden Sie die optimistische und die pessimistische Sperre von Redis

王林
王林nach vorne
2023-05-28 17:58:092144Durchsuche

Concept

Redis ist ein In-Memory-Schlüsselwertspeichersystem, das eine Vielzahl von Datenstrukturen unterstützt, einschließlich Zeichenfolgen, Hashes, Listen usw. Redis bietet zwei Sperrmechanismen, nämlich optimistisches Sperren und pessimistisches Sperren.

Optimistische Sperre

Optimistische Sperre ist eine optimistische Parallelitätskontrollstrategie. Sie geht davon aus, dass die Daten in den meisten Fällen nicht von anderen Threads belegt werden. Daher wird die Sperre nicht jedes Mal erfasst, wenn die Daten geändert werden müssen, sondern direkt . Überarbeiten. In Redis kann optimistisches Sperren über die Befehle WATCH und CAS implementiert werden. Der Befehl WATCH wird zum Überwachen eines oder mehrerer Schlüssel verwendet, und der Befehl CAS dient zum Überprüfen und Aktualisieren des Werts des Schlüssels.

Wenn beispielsweise ein Zähler mit dem Schlüsselnamenzähler vorhanden ist, müssen mehrere Clients damit arbeiten. Sie können optimistisches Sperren verwenden, um den Zählerschlüssel vor jeder Client-Operation zu überwachen, indem Sie den WATCH-Befehl

WATCH counter
current_count = GET counter
new_count = current_count + 1
MULTI
SET counter new_count
EXEC

ausführen. Bevor der EXEC-Befehl ausgeführt wird, verwenden Sie dann den GET-Befehl, um den Wert des Zählerschlüssels erneut abzurufen und ihn mit dem vorherigen zu vergleichen erhaltene Werte werden verglichen. Wenn die Werte gleich sind, bedeutet dies, dass während des Zeitraums kein anderer Client den Zählerschlüssel geändert hat. Zu diesem Zeitpunkt können Sie den CAS-Befehl verwenden, um den neuen Wert auf den Zählerschlüssel festzulegen. Wenn die Werte unterschiedlich sind, bedeutet dies, dass andere Clients den Zählerschlüssel in diesem Zeitraum geändert haben und der Vorgang erneut ausgeführt werden muss.

GET counter

Pessimistische Sperre

Pessimistische Sperre ist eine pessimistische Parallelitätskontrollstrategie. Sie geht davon aus, dass die Daten in den meisten Fällen von anderen Threads belegt werden. Daher wird jedes Mal, wenn die Daten geändert werden müssen, zuerst die Sperre erworben, um dies sicherzustellen Es gibt keine anderen Threads, die auf diese Daten zugreifen können. In Redis kann pessimistisches Sperren über den WATCH-Befehl implementiert werden, der einen oder mehrere Schlüssel überwachen kann. Wenn sich der Wert eines überwachten Schlüssels während der Transaktionsausführung ändert, wird die gesamte Transaktion zurückgesetzt.

Immer noch das obige Beispiel

WATCH counter
current_count = GET counter
new_count = current_count + 1
MULTI
SET counter new_count
EXEC

Wenn andere Clients den Zählerschlüssel während der Ausführung der Transaktion ändern, wird die gesamte Transaktion zurückgesetzt und muss erneut ausgeführt werden.

Obwohl pessimistische Sperren den Vorteil der Datenkonsistenz gewährleisten können, besteht ihr Nachteil darin, dass zuerst die Sperre erworben werden muss, was zu einer Thread-Blockierung führen und dadurch die Parallelitätsleistung beeinträchtigen kann.

Beispiel für eine optimistische Sperre

Angenommen, es gibt eine E-Commerce-Plattform, auf der Benutzer Waren kaufen können. Um sicherzustellen, dass die Reduzierung des Produktbestands konsistent ist, kann der optimistische Sperrmechanismus von Redis verwendet werden, um dies zu erreichen.

Zuerst müssen wir die Bestandsinformationen jedes Artikels in Redis mithilfe einer Hash-Datenstruktur speichern, zum Beispiel:

Wenn der Benutzer dann in der Geschäftslogik einen Artikel kauft, müssen die folgenden Schritte ausgeführt werden:

  • Verwenden Sie den WATCH-Befehl, um Produktbestandsschlüssel zu überwachen, z. B. stock:sku001;

  • Verwenden Sie den GET-Befehl, um die aktuelle Produktbestandsmenge abzurufen.

  • Überprüfen Sie, ob der Produktbestand ausreichend ist. Geben Sie direkt eine Fehlermeldung zurück.

  • Berechnen Sie die neue Lagerbestandsmenge und starten Sie eine Transaktion.

  • Verwenden Sie den HSET-Befehl, um die neue Lagerbestandsmenge in Redis zu speichern. Wenn andere Kunden während der Ausführung den Produktbestand ändern, wird die Transaktion zurückgesetzt und muss erneut ausgeführt werden.

  • Das Folgende ist ein Beispielcode, der mit Spring Boot implementiert wurde:

    @Service
    public class OrderService {
        private final RedisTemplate<String, Integer> redisTemplate;
    
        @Autowired
        public OrderService(RedisTemplate<String, Integer> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    
        public void placeOrder(String sku, int quantity) {
            String stockKey = "stock:" + sku;
            while (true) {
                // 监视商品库存键,以便在事务开始前检测是否有其他客户端修改了库存
                redisTemplate.watch(stockKey);
                // 获取当前库存数量
                int currentStock = redisTemplate.opsForHash().get(stockKey, sku);
                // 检查库存是否足够
                if (currentStock < quantity) {
                    // 库存不足,放弃事务并抛出异常
                    redisTemplate.unwatch();
                    throw new RuntimeException("Out of stock");
                }
                // 计算新的库存数量
                int newStock = currentStock - quantity;
                // 开始事务
                redisTemplate.multi();
                // 更新库存数量
                redisTemplate.opsForHash().put(stockKey, sku, newStock);
                // 提交事务
                List<Object> results = redisTemplate.exec();
                // 如果事务执行成功,则退出循环
                if (results != null) {
                    break;
                }
                // 如果事务执行失败,则重试
            }
        }
    }
  • Im obigen Code verwenden wir RedisTemplate, um Redis zu betreiben, wobei die Watch-Methode zur Überwachung des Produktinventarschlüssels und die opsForHash-Methode verwendet wird Zum Abrufen und Ändern des Produktbestands werden Multi- und Exec-Methoden zum Starten und Festschreiben von Transaktionen verwendet.

Beispiel für eine pessimistische Sperre

Neben der optimistischen Sperre unterstützt Redis auch eine pessimistische Sperre, die durch Setzen der Flags NX (Not Exist) oder XX (Exist) erreicht werden kann. Wenn beispielsweise das NX-Flag auf „true“ gesetzt ist und die Sperre nicht vorhanden ist, wird „OK“ zurückgegeben. Wenn die Sperre bereits vorhanden ist, wird „null“ zurückgegeben, was darauf hinweist, dass die Sperre nicht erfasst werden konnte. Wenn das XX-Flag hingegen auf „true“ gesetzt ist und die Sperre bereits vorhanden ist, wird „OK“ zurückgegeben, was darauf hinweist, dass die Sperre erfolgreich erworben wurde .

Das Folgende ist ein Beispielcode für eine pessimistische Sperre, der mit Spring Boot implementiert wurde:

@Service
public class OrderService {
    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    public OrderService(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void placeOrder(String sku, int quantity) {
        String lockKey = "lock:" + sku;
        // 尝试获取锁,如果锁已经存在,说明有其他线程正在执行相关操作
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked");
        if (!locked) {
            // 获取锁失败,抛出异常
            throw new RuntimeException("Unable to acquire lock");
        }
        // 设置锁的过期时间,防止锁被一直占用
        redisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);
        try {
            // 执行订单创建、扣减库存等操作
        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
    }
}

Im obigen Code verwenden wir die setIfAbsent-Methode, um zu versuchen, die Sperre zu erhalten, was bedeutet, dass andere Threads verwandte Vorgänge ausführen Zu diesem Zeitpunkt wird „false“ zurückgegeben, was darauf hinweist, dass die Sperrenerfassung fehlgeschlagen ist. Andernfalls wird „true“ zurückgegeben, was darauf hinweist, dass die Sperrenerfassung erfolgreich war. Wir erwerben zuerst die Sperre, legen dann die Ablaufzeit der Sperre fest, führen entsprechende Vorgänge aus und geben schließlich die Sperre frei.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie die optimistische und die pessimistische Sperre von Redis. 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