Redisロックを解除する正しい方法

小云云
リリース: 2023-03-17 21:50:01
オリジナル
2753 人が閲覧しました

Redis は PHP の良い友達です。PHP でビジネスを記述する場合、同時に特定の動作を実行できるのは 1 人だけです。現時点ではロックを使用する必要があります。ロック方法はいくつかありますが、PHP ではメモリ内のロックを使用できず、データベースを使用してロックすることもできません。現時点では、ロック メカニズムとして redis を選択するのが一般的です。この記事では主に Redis のロックを解除する正しい方法を紹介し、皆様のお役に立てれば幸いです。

setnx

Redis でロックされている最も単純なデータ構造は文字列です。初期の頃、setnx はロック操作に一般的に使用されていました。このコマンドは、:lock が存在しない場合に val を設定するためのものでした。ロックのロックを解除するには、expir を使用することも忘れないでください。 del コマンドの疑似コードは次のとおりです:

if (Redis::setnx("my:lock", 1)) {
  Redis::expire("my:lock", 10);
  // ... do something

  Redis::del("my:lock")
}
ログイン後にコピー

ここには実際には問題があります。問題は、setnx とexpired の間にクラッシュまたはその他の動作がある場合、ロックが解放されない可能性があることです。したがって、さらなる最適化ソリューションは、タイムスタンプをロックに保存することかもしれません。タイムスタンプの長さを決定します。

set

現在、ロックを実装するには set を直接使用することが公式に推奨されています。 set コマンドを使用して setnx を置き換えることができます。これは次のようになります

if (Redis::set("my:lock", 1, "nx", "ex", 10)) {
  ... do something

  Redis::del("my:lock")
}
ログイン後にコピー

上記のコードは my:lock を 1 に設定します。ロックが存在しない場合に限り、有効期限はその後 10 に設定されます。設定が完了しました。

ロックを取得するメカニズムは正しいですが、del を直接使用してロックを削除するメカニズムは正しくありません。他の人のロックを誤って削除してしまう可能性があるためです。

たとえば、このロックを10秒間ロックしましたが、処理時間が10秒を超え、10秒でロックが自動的に期限切れになり、他の人によって奪われ、再ロックされました。この時点で、Redis::del を再度呼び出すと、他の人が作成したロックが削除されます。

公式には、ロックを解除するためのコマンドも記載されています。 lua スクリプトを使用し、最初に get を実行し、次に del を実行することをお勧めします。 プログラムは次のようになります。

$token = rand(1, 100000);

function lock() {
  return Redis::set("my:lock", $token, "nx", "ex", 10);
}

function unlock() {
  $script = `
if redis.call("get",KEYS[1]) == ARGV[1]
then
  return redis.call("del",KEYS[1])
else
  return 0
end  
  `
  return Redis::eval($script, "my:lock", $token)
}

if (lock()) {
  // do something

  unlock();
}
ログイン後にコピー

ここでのトークンは、ロック時の乱数です。 、redis に移動します。このトークンは my:lock に保存されています。ロックを解除するときは、まずロック内のトークンを取得します。一致しない場合は、ロックが以前に設定されたことを意味します。は、ロックが期限切れになったことを意味します。誰かが設定したものなので、何もするべきではありません。

つまり、setnx はもう使用せず、ロックの実装には set を直接使用してください。

関連する推奨事項:

php redis ロックを使用して同時アクセス クラスを制限する

php redis ロックを使用して同時アクセス クラスを制限する例

php で redis を操作する一般的な方法のまとめ

以上がRedisロックを解除する正しい方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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