ホームページ  >  記事  >  データベース  >  Redisでフラッシュセールを実現する課題について話しましょう

Redisでフラッシュセールを実現する課題について話しましょう

WBOY
WBOY転載
2022-05-27 11:40:343255ブラウズ

この記事では、Redis に関する関連知識を提供します。主にフラッシュ セールのロジック、既存のリンク タイムアウト、過剰販売、在庫のレガシーなど、フラッシュ セールの実現に関する関連コンテンツを紹介します。以下の問題を見てみましょう。 . 皆様のお役に立てれば幸いです。

Redisでフラッシュセールを実現する課題について話しましょう

# 推奨学習:

Redis ビデオ チュートリアル

#1. フラッシュ セール ロジック

二次販売 : カウンタと人事レコードのトランザクション操作を解決

##1. uid と proid が空ではないと判断
    ##2. redis に接続
  1. 3. スプライシング キー
  2. 在庫キー
    • 成功したフラッシュ セール ユーザー キー
    • 4. 在庫を取得します。在庫が null の場合は、フラッシュ セールはまだ開始されていません
  3. 5. ユーザーがフラッシュ セール操作を繰り返すかどうかを決定します
  4. #6. 商品の数量を決定します。在庫数量が 1 未満の場合、フラッシュ セールは開始されません。セールは終了します
  5. 7. フラッシュ セール プロセス
  6. 在庫-1
  7. フラッシュ キルに成功したユーザーをリストに追加します
    • 2. 問題
  8. 2.1. 接続タイムアウト

理由: 接続の作成には多くのパフォーマンスが消費され、時間内に接続が取得できない場合があります。

2.2. 過剰販売

は、同時に発生する状況、つまり、出力が在庫切れになった場合 (フラッシュセール)、終了後もまだ商品が販売されている場合、その結果、マイナスの在庫数量が発生します。

2.3. 在庫のレガシー
Redisでフラッシュセールを実現する課題について話しましょうオプティミスティック ロックを使用して問題 2 を解決した後、問題 3 が発生します

在庫数量が比較的多く同時発生している場合、楽天ロックを使用すると、最初のユーザーがフラッシュセールに成功した後、在庫キーのバージョン番号が変更され、それを取得した他のユーザーはバージョン番号が異なるため購入を続行できなくなり、在庫が残ります。従来の問題

3. 解決策

3.1. 接続タイムアウト

接続プールを使用する場合、ツール クラスは次のとおりです:

public class JedisPoolUtil {
	private static volatile JedisPool jedisPool = null;
	private JedisPoolUtil() {
	}
	public static JedisPool getJedisPoolInstance() {
		if (null == jedisPool) {
			synchronized (JedisPoolUtil.class) {
				if (null == jedisPool) {
					JedisPoolConfig poolConfig = new JedisPoolConfig();
					poolConfig.setMaxTotal(200);
					poolConfig.setMaxIdle(32);
					poolConfig.setMaxWaitMillis(100 * 1000);
					poolConfig.setBlockWhenExhausted(true);
					poolConfig.setTestOnBorrow(true);
					jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379, 60000);
				}
			}
		}
		return jedisPool;
	}}//使用JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();Jedis jedis = jedisPoolInstance.getResource();

springBoot バージョン (pom. XML の導入、application.yml の設定、オブジェクトの挿入)

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-data-redis</artifactid></dependency><dependency>
    <groupid>redis.clients</groupid>
    <artifactid>jedis</artifactid>
    <version>3.2.0</version></dependency>
spring:
  redis:
    host: 127.0.0.1    port: 6379
    database: 0
    timeout: 1800000
    lettuce:
      pool:
        max-active: 20
        max-wait: -1
        max-idle: 5
        min-idle: 0
    @Autowired
    private RedisTemplate redisTemplate;

3.2. 売られすぎの問題

Redis トランザクションの使用、オプティミスティック ロックの監視

//监视库存
jedis.watch(kcKey);//中间代码忽略

//7 秒杀过程
//使用事务
Transaction multi = jedis.multi();//组队操作
multi.decr(kcKey);multi.sadd(userKey,uid);//执行
List<object> results = multi.exec();if(results == null || results.size()==0) {
    System.out.println("秒杀失败了....");
    jedis.close();
    return false;}</object>

3.3. インベントリのレガシー問題オプティミスティック ロックが原因です。

Lua 埋め込みスクリプト言語を使用します。

複雑なまたは複数ステップの Redis 操作をスクリプトとして記述し、一度に実行するために Redis に送信して、操作の数を減らします。 redis への繰り返し接続。性能を上げる。

LUA スクリプトは redis トランザクションに似ています。ある程度の原子性があり、他のコマンドによってキューに入れられることはありません。redis トランザクション操作を完了できます。
  1. LUA スクリプト機能はのみ利用可能ですRedis 2.6 以降では、
  2. を使用して lua スクリプトを使用してユーザーを排除し、過剰販売の問題を解決できます。
  3. redis バージョン 2.6 以降では、競合の問題は
  4. lua スクリプトによって解決されます。実際、
  5. redis はシングルスレッド機能を使用して、マルチタスクの同時実行の問題を解決します。タスクキュー。
  6. local userid=KEYS[1];				//1、2行定义两个变量,					
    local prodid=KEYS[2];
    local qtkey="sk:"..prodid..":qt";	//3,4行定义拼接key
    local usersKey="sk:"..prodid..":usr";
    local userExists=redis.call("sismember",usersKey,userid); //5-8,判断用户是否存在,不存在return 2
    if tonumber(userExists)==1 then
        return2;
    end
    local num=redis.call("get",qtkey);	//9-11,判断商品是否存在
    if tonumber(num)<strong>完全なコードは次のとおりです: </strong><pre class="brush:php;toolbar:false">// 定义两段Lua脚本(使用Lua脚本可以解决乐观锁带来的库存遗留问题)
    	static String secKillScript =
    			"local userid=KEYS[1];\r\n" +
    					"local prodid=KEYS[2];\r\n" +
    					"local qtkey='sk:'..prodid..\":qt\";\r\n" +
    					"local usersKey='sk:'..prodid..\":usr\";\r\n" +
    					"local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
    					"if tonumber(userExists)==1 then \r\n" +
    					"   return 2;\r\n" +
    					"end\r\n" +
    					"local num= redis.call(\"get\" ,qtkey);\r\n" +
    					"if tonumber(num)
    推奨される学習:
  7. Redis ビデオ チュートリアル

以上がRedisでフラッシュセールを実現する課題について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。