ホームページ  >  記事  >  バックエンド開発  >  Redisフラッシュセール使用時の商品スーパー現象を解決するにはどうすればよいですか?

Redisフラッシュセール使用時の商品スーパー現象を解決するにはどうすればよいですか?

WBOY
WBOYオリジナル
2016-10-17 09:30:081169ブラウズ

最近フラッシュセールイベントを行っていたのですが、パフォーマンスと応答速度の観点からredisを使用しました。書いているときは、超常現象を防ぐために特に注意を払っていましたが、Redis理論に基づいた楽観的ロックを使用していましたが、それでも非常に混乱しました。具体的なコードは次のとおりです:

リーリー

返信内容:

最近フラッシュセールイベントを行っていたのですが、パフォーマンスと応答速度の観点からredisを使用しました。書いているときは、超常現象を防ぐために特に注意を払っていましたが、Redis理論に基づいた楽観的ロックを使用していましたが、それでも非常に混乱しました。具体的なコードは次のとおりです:

リーリー

このコードは、同時実行性が高い状況では依然として過剰に販売されると思います。仮定します: 賞品が 1 つしか残っていない場合、3 人が同時に実行し $redis->watch("mywatchkey") 得られたデータが 99 であった場合、売られすぎ現象が発生します。

はシングルスレッド読み取りであるため、最も単純なキュー実装を使用しましょう。 redis

  1. 抽選の前に、賞品の数を

    キューに書き込みます award:100 // 長さ 100 のリスト。値は賞品を獲得するかどうかを決定するためにのみ使用されますredis队列award:100

  2. 同時抽選

  3. リーリー

sleep(5);

あなたの会社はまだ人材を受け入れていますか?

この状況について考えてください。

mywatchkey=99
ユーザー A が mywatchkey をリクエストし、99 を取得します。
ユーザー B が mywatchkey をリクエストし、99 を取得します。
A と B のリクエストが完了したら、mywatchkey は何になるべきですか? 。 101、それとも100?

これは典型的な Check-then-Act エラーです

まず最初に、このコードの「売られすぎ」の結果が $mywatchkey > 100 であるかどうかをお聞きします (それは不可能だと思います)

または、$mywatchkey = 100 の場合、2 つのページが同時に表示され、「購入に成功しました!」
これについてはわかりません コードはテストされていますが、次の状況になるかどうかを推測しています:

1.セッション A: mywatchkey チェックを実行します。この時点では mywatchkey = 99 です

2.セッションB: mywatchkeyの処理後、この時点ではmywatchkey=100ですが、セッションAの後続の操作には影響しません

さらに 2 つの接続を追加して見てください、何か得られるかもしれません

redis のトランザクションと監視ステートメント

redis-watch-multi-exec-by-one-client

この問題を根本的に解決したい場合は、まず勉強してください:

1.ロックします。

2. 従来のデータベーストランザクション。

次に、Redis と従来のデータベースの違いを学びます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。