1. ホーム
  2. go

[解決済み] SETNXでシングルインスタンスのRedisをロックする

2022-02-25 01:40:13

質問

アプリケーションクライアントから1つのRedisインスタンスに接続する必要があります。

クライアントはKubernetesで複製されるので、クライアントレプリカ間の競合を防ぐために、ロックに関するRedisのドキュメントを勉強しています。

ググって読み漁った結果、この2つのリソースにたどり着きました。

興味深いことに SETNX を使用しないよう、文書で明示的にアドバイスしています。 SETNX を使用してロックを実装することは、基本的に時代遅れであると述べています。

次のようなパターンは推奨されず、Redlockアルゴリズムが推奨されます[...]。

既存の実装の中には、このページをリファレンスとしてリンクしているものがあるため、とにかく古いパターンを文書化しています。

しかし、レッドロックのアルゴリズムは、特に 分散型 ロックされるため、複数のRedisインスタンスをロックしようとする場合、実際には複数の マスター .

もうちょっと踏み込むと、ライブラリの レッドシンク (golang)で宣言されている New 関数は次のようになります。

func New(pools []Pool) *Redsync {
    return &Redsync{
        pools: pools,
    }
}

まぎれもなく、Redisクラスタでのロックをサポートするために設計されているようです。

私の使用例では、1つのRedisインスタンスにのみ接続するつもりです。

おそらく、redsync パッケージを使用して、長さ 1 のスライスを渡すことができると思いますが、私には SETNX のパターンは、単一のRedisインスタンスで同様にうまく機能する可能性があります。

これは正しい理解でしょうか? ありがとうございます。

解決方法は?

Redlockのアルゴリズムは分散Redisシステム用に設計されています。 SET SETNX のドキュメントを参照してください。

しかし、もっと重要なポイントはこれです。 複数のRedisクライアント間の競合を回避するためにロックを使用する必要はないでしょう。 . Redisロックは、通常、いくつかの 外部 分散されたリソース(私の回答 こちら を参照してください)。Redisはシングルスレッドなので、多くのコマンドはすでにアトミックです。また、トランザクションやLuaスクリプトを使用して、任意の複雑なアトミック操作を構成することができます。

ですから、私のアドバイスは、(分散型であろうとなかろうと)ロックを使おうとするのではなく、衝突を避けるために原子性を使用するようにクライアントコードを設計することです。