1. データ損失の問題
Redis データの永続性。
2. 同時実行性の問題
私たちのマスター/スレーブ クラスターは、読み取りと書き込みの分離を実現します。
3. 障害回復の問題
Redis Sentinel を使用して、正常性の検出と自動回復を実装します。
4. ストレージ容量の問題
シャード クラスターを構築し、スロット メカニズムを使用して動的な拡張を実現します。
RDB の正式名は、Redis データベース バックアップ ファイル (Redis データ バックアップ ファイル) で、Redis データ スナップショットとも呼ばれます。簡単に言うと、メモリ内のすべてのデータがディスクに記録されます。 Redis インスタンスに障害が発生して再起動すると、スナップショット ファイルがディスクから読み取られ、データが復元されます。
スナップショット ファイルは RDB ファイルと呼ばれ、デフォルトでは現在の実行ディレクトリに保存されます。
Redis 内に RDB をトリガーするメカニズムがあり、これは redis.conf ファイルにあります。形式は次のとおりです。 bgsaveコマンドを実行するとforkが渡され、メインプロセスとメモリデータを共有する子プロセスが生成されます。フォークが完了したら、メモリ データを読み取り、RDB ファイルに書き込みます。
Fork はコピーオンライト テクノロジを使用します:
メイン プロセスが読み取り操作を実行すると、共有メモリにアクセスします。AOF コマンド記録の頻度も変更できます。 redis.conf を介して渡される 一致するファイル:
構成項目
欠点 | ##常に | #同期ディスクフラッシュ##高い信頼性、データ損失はほとんどなし | ##素晴らしいパフォーマンスへの影響||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
毎秒 | フラッシュ ディスク/秒 | 中程度のパフォーマンス | 最大 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 で構成することもできます:
RDB と AOF にはそれぞれ長所と短所があります。データ セキュリティ要件が高い場合、この 2 つは実際の開発ではこれらを組み合わせて利用することが多いです。
1. フラッシュ セールの手順:
2. Redis 最適化フラッシュ セールの手順:
3. フラッシュ セール用の Lua スクリプト 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 に基づく共有セッション ログインの実装 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 サイトの他の関連記事を参照してください。