ホームページ  >  記事  >  データベース  >  Redis分散キャッシュとフラッシュセールを実装する方法

Redis分散キャッシュとフラッシュセールを実装する方法

王林
王林転載
2023-06-02 23:43:201154ブラウズ

1. シングルポイント Redis の問題

1. データ損失の問題

Redis データの永続性。

2. 同時実行性の問題

私たちのマスター/スレーブ クラスターは、読み取りと書き込みの分離を実現します。

3. 障害回復の問題

Redis Sentinel を使用して、正常性の検出と自動回復を実装します。

4. ストレージ容量の問題

シャード クラスターを構築し、スロット メカニズムを使用して動的な拡張を実現します。

2. RDB

RDB の正式名は、Redis データベース バックアップ ファイル (Redis データ バックアップ ファイル) で、Redis データ スナップショットとも呼ばれます。簡単に言うと、メモリ内のすべてのデータがディスクに記録されます。 Redis インスタンスに障害が発生して再起動すると、スナップショット ファイルがディスクから読み取られ、データが復元されます。
スナップショット ファイルは RDB ファイルと呼ばれ、デフォルトでは現在の実行ディレクトリに保存されます。

Redis 内に RDB をトリガーするメカニズムがあり、これは redis.conf ファイルにあります。形式は次のとおりです。 bgsaveコマンドを実行するとforkが渡され、メインプロセスとメモリデータを共有する子プロセスが生成されます。フォークが完了したら、メモリ データを読み取り、RDB ファイルに書き込みます。

Fork はコピーオンライト テクノロジを使用します: Redis分散キャッシュとフラッシュセールを実装する方法

メイン プロセスが読み取り操作を実行すると、共有メモリにアクセスします。

  • メインプロセスが書き込み操作を実行するとき、データのコピーをコピーして書き込み操作を実行します;

  • RDB モード bgsave の基本プロセス?

メイン プロセスをフォークして子プロセスを取得し、メモリ空間を共有します。

  1. 子プロセスはメモリ データを読み取り、新しいデータを書き込みます。 RDB ファイル;

  2. 古い RDB ファイルを新しい RDB ファイルに置き換えます;

  3. RDB はいつ使用されますか処刑されるのか? 60 1000 を節約とはどういう意味ですか?

Redis分散キャッシュとフラッシュセールを実装する方法

デフォルトはサービスの停止時です。

  • は、60 秒以内に少なくとも 1000 件の変更が実行された場合に RDB がトリガーされることを意味します。

  • RDB の欠点?

RDB の実行間隔が長く、2 つの RDB 書き込みの間にデータ損失のリスクがあります;

  • fork サブプロセス、圧縮、書き込み RDB ファイルのエクスポートには時間がかかります;

  • AOF コマンド記録の頻度は、redis.conf ファイルを通じて構成することもできます:

    3. AOF
AOF は追加専用ファイルの略です。 Redis によって処理されるすべての書き込みコマンドは AOF ファイルに記録され、コマンド ログ ファイルとみなすことができます。

AOF はデフォルトでオフになっています。AOF を有効にするには、redis.conf 構成ファイルを変更する必要があります:

AOF コマンド記録の頻度も変更できます。 redis.conf を介して渡される 一致するファイル:

Redis分散キャッシュとフラッシュセールを実装する方法

Redis分散キャッシュとフラッシュセールを実装する方法構成項目

フラッシュ タイミング利点欠点#同期ディスクフラッシュ##素晴らしいパフォーマンスへの影響毎秒フラッシュ ディスク/秒中程度のパフォーマンス最大 1 分間のデータ損失noオペレーティング システム制御最高のパフォーマンス信頼性が低く、大量のデータが失われる可能性があります
##常に##高い信頼性、データ損失はほとんどなし
##

これは記録コマンドであるため、AOF ファイルは RDB ファイルよりもはるかに大きくなります。 AOF は同じキーに対する複数の書き込み操作を記録しますが、意味があるのはそれらのうちの最後の書き込み操作のみです。 bgrewriteaof コマンドを使用すると、最小限のコマンドで AOF ファイルの書き換え機能を完了できます。

set id 1
set name nezha
set id 2

bgrewriteaof

mset name nezha id 2

Redis は、しきい値がトリガーされると、AOF ファイルを自動的に書き換えます。しきい値は redis.conf で構成することもできます:

# AOF ファイルが最後のファイルより大きくなった場合、書き換えがトリガーされます。 AOF ファイルの最小サイズは? トリガー リライト auto-aof-rewrite-min-size 64mb

RDB と AOF にはそれぞれ長所と短所があります。データ セキュリティ要件が高い場合、この 2 つは実際の開発ではこれらを組み合わせて利用することが多いです。

永続化メソッドデータの整合性ファイル サイズダウンタイム回復速度データ回復の優先順位システム リソース使用量使用シナリオ 4. Redis 最適化フラッシュ セール プロセス

##RDB
AOF
メモリ全体の定期的なスナップショット 実行されたすべてのコマンドを記録
不完全、2 つのバックアップ間で失われます 比較的完成度が高く、ブラッシング戦略に依存します。
圧縮があり、ファイル サイズは小さいです records コマンド、ファイル サイズ非常に大きい
迅速 遅い
低、データ整合性が低くないため 高、データ整合性が高いため
高、多量CPU とメモリの消費量 #主にディスク IO リソースが少なく、AOF の書き換えは多くの CPU リソースとメモリ リソースを占有します
数分間のデータ損失を許容し、より高速な起動速度を追求します。 データ セキュリティに対するより高い要件が一般的です。

1. フラッシュ セールの手順:

    クーポンのクエリ;
  1. フラッシュ セールの製品在庫の判断;
  2. 注文のクエリ
  3. 1 人あたり 1 つの注文を確認します;
  4. 在庫を削減します;
  5. 注文を作成します;

Redis分散キャッシュとフラッシュセールを実装する方法2. Redis 最適化フラッシュ セールの手順:

    フラッシュ セール クーポンを追加し、クーポン情報を Redis に保存します;
  1. Lua スクリプトに基づいて、注文ごとに 1 人のフラッシュ セール商品在庫を決定し、ユーザーのフラッシュ セールが成功したかどうかを判断します;
  2. フラッシュ セールが成功した場合は、クーポン ID、ユーザー ID、および製品 ID をブロック キューにカプセル化します。
  3. 非同期タスクを開始し、継続的にブロッキング キューからのアイテム情報の読み取りと非同期注文関数の実装;

Redis分散キャッシュとフラッシュセールを実装する方法3. フラッシュ セール用の Lua スクリプト

Redis分散キャッシュとフラッシュセールを実装する方法 4. flash kill lua スクリプトを呼び出します

public Result seckillVoucher(Long voucherId) {
     Long userId = UserHolder.getUser().getId();
     long orderId = redisIdWorker.nextId("order");
     // 1.执行lua脚本
     Long result = stringRedisTemplate.execute(
             SECKILL_SCRIPT,
             Collections.emptyList(),
             voucherId.toString(), userId.toString(), String.valueOf(orderId)
     );
     int r = result.intValue();
     // 2.判断结果是否为0
     if (r != 0) {
         // 2.1.不为0 ,代表没有购买资格
         return Result.fail(r == 1 ? "库存不足" : "不能重复下单");
     }
     // 3.返回订单id
     return Result.ok(orderId);
 }

5. スレッド プールを通じて、ブロッキング キューを操作します

// 线程池
private static final ExecutorService SECKILL_ORDER_EXECUTOR = Executors.newSingleThreadExecutor();

/**
* 在类初始化完成后执行
*/
@PostConstruct
private void init() {
    SECKILL_ORDER_EXECUTOR.submit(new VoucherOrderHandler());
}

// 阻塞队列
private BlockingQueue<VoucherOrder> orderTasks = new ArrayBlockingQueue<>(1024 * 1024);
private class OrderHandler implements Runnable{

    @Override
    public void run() {
        while (true){
            try {
                doSomething();
            } catch (Exception e) {
                log.error("处理订单异常", e);
            }
        }
    }
}

5. Redis に基づいて共有セッション ログインを実装します

セッションに基づくログイン

Redis分散キャッシュとフラッシュセールを実装する方法Redis に基づく共有セッション ログインの実装

public class RefreshTokenInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1、获取请求头中的token
        String token = request.getHeader("authorization");
        if (StrUtil.isBlank(token)) {
            return true;
        }
        // 2、基于TOKEN获取redis中的用户
        String key  = LOGIN_USER_KEY + token;
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);
        // 3、判断用户是否存在
        if (userMap.isEmpty()) {
            return true;
        }
        // 5、将查询到的hash数据转为UserDTO
        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        // 6、存在,保存用户信息到 ThreadLocal
        UserHolder.saveUser(userDTO);
        // 7、刷新token有效期
        stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.MINUTES);
        // 8、放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 移除用户
        UserHolder.removeUser();
    }
}

以上がRedis分散キャッシュとフラッシュセールを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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