ホームページ  >  記事  >  ウェブフロントエンド  >  Redis 分散ロックを使用したスケーラブルなスロット予約システムの構築

Redis 分散ロックを使用したスケーラブルなスロット予約システムの構築

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-22 20:48:28569ブラウズ

Building a Scalable Slot Booking System with Redis Distributed Locks

今日のペースの速いデジタル世界では、特に複数のユーザーが同じ時間枠を同時に予約しようとする場合、シームレスでスケーラブルな予約システムが不可欠です。このブログでは、分散ロックに Redis を使用した スロット予約システム の低レベル設計の概要を説明します。これにより、ユーザーは競合状態に遭遇することなくスロットを予約できるようになります。 Redis を活用することで、同時実行性とスケーラビリティを管理し、需要が高い場合でも予約システムが効率的に実行されるようにすることができます。

システムの主要コンポーネント

技術的な側面に入る前に、コアコンポーネントを分解してみましょう:

  1. ユーザー: システムを使用してスロットを予約する個人を表します。
  2. スロット: ユーザーが予約できる時間制限のある単位 (会議室、イベントなど) を表します。
  3. Redis 分散ロック: 2 人のユーザーが同時に同じスロットを予約できないようにする重要な機能です。
  4. MongoDB: ユーザーとスロットの情報を保存します。
  5. Redis: 競合状態を処理するロック マネージャーとして機能します。

予約システムの課題

複数のユーザーが同じスロットを同時に予約しようとすると、予約システムはダブルブッキングや競合状態などの問題に簡単に陥る可能性があります。同時実行制御が適切に行われていないと、2 人のユーザーが誤って同じスロットを予約し、フラストレーションや競合が発生する可能性があります。

ここで Redis 分散ロックが活躍します。ロックを使用すると、いつでも 1 人のユーザーだけがスロットを予約できるようになります。


1. モデル: ユーザーとスロットの定義

まず、ユーザースロット 用のデータ モデルを設計する必要があります。これらのモデルは MongoDB に保存され、その構造はシンプルですが効果的です。

a. ユーザーモデル

各ユーザーには、名前、電子メール、認証用のハッシュされたパスワードなどの基本的な属性があります。

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('User', UserSchema);

b. スロットモデル

各スロットには開始時間と終了時間があり、予約されたかどうか、誰によって予約されたかを追跡します。

const mongoose = require('mongoose');

const SlotSchema = new mongoose.Schema({
    startTime: { type: Date, required: true },
    endTime: { type: Date, required: true },
    isBooked: { type: Boolean, default: false },
    bookedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null }
});

module.exports = mongoose.model('Slot', SlotSchema);

2. API エンドポイント: ユーザーがシステムと対話する方法

API はユーザーとシステムの間の架け橋です。必要な主要なエンドポイントは次のとおりです:

a. ユーザー登録

新規ユーザーの登録を許可します:

  • エンドポイント: POST /api/users/register
  • リクエスト: ユーザーの詳細 (名前、電子メール、パスワード)
  • 応答: ユーザー登録の確認

b. ユーザーログイン

ユーザーを認証し、JWT トークンを提供します:

  • エンドポイント: POST /api/users/login
  • リクエスト: ユーザー資格情報 (電子メール、パスワード)
  • レスポンス: 認証用の JWT トークン

c. スロットの作成

管理者または許可されたユーザーがスロットを作成できるようにします:

  • エンドポイント: POST /api/slots/create
  • リクエスト: スロットの開始時間と終了時間
  • 応答: スロット作成の確認

d. 予約スロット

ユーザーが利用可能なスロットを予約できるようにします:

  • エンドポイント: POST /api/slots/book/:id
  • リクエスト: ヘッダーの JWT トークン、URL のスロット ID
  • 応答: スロット予約の確認またはエラー (例: スロットがすでに予約されている場合)

3. Redis 分散ロックの仕組み

同時実行性 は、予約システムにとって最大の課題です。複数のユーザーが同時に同じスロットを予約しようとすると、Redis の 分散ロック 機能が役に立ちます。

Redis ロックを使用した予約プロセス

  1. ロックの取得:

    • ユーザーがスロットを予約しようとすると、システムは SET lock_key NX EX 10 コマンドを使用して Redis でロックを取得しようとします。
    • NX (存在しない場合に設定) は、ロックがまだ存在しない場合にのみ作成されることを保証します。一方、EX 10 は、ロックが 10 秒後に期限切れになることを保証します (ロックを防止します)デッドロック)。
    • ロックがすでに取得されている場合、システムは 423 Locked ステータスを返し、スロットが他の人によって予約されていることをユーザーに通知します。
  2. スロットの空き状況チェック:

    • ロックが正常に取得された場合、MongoDB にクエリが実行され、スロットがまだ利用可能かどうか (つまり、予約されていないか) が確認されます。
    • スロットが利用可能な場合、システムはスロットのステータスを予約済みに更新し、bookedBy フィールドを現在のユーザーの ID に設定します。
  3. ロック解除:

    • 予約プロセスが完了すると、またはエラーが発生した場合、システムは DEL lock_key コマンドを使用して Redis キーを削除することでロックを解放します。

Redis ロックを使用してスロットを予約するためのサンプル コード:

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('User', UserSchema);

4. 予約システムのエラー処理

エラーを適切に処理することは、堅牢なシステムにとって重要な部分です。システムが処理するエラーの一部を次に示します:

  • 400 Bad Request: 入力データが無効な場合。
  • 404 Not Found: 要求されたスロットまたはユーザーが見つからない場合。
  • 423 Locked: スロットが現在別のユーザーによって予約されている場合。
  • 500 Internal Server Error: データベースや Redis の障害など、予期しないエラーの場合。

5. システムの保護

セキュリティは、特にユーザーがリソースを予約する場合には重要です。システムがセキュリティを確保する方法は次のとおりです:

  • JWT 認証: スロット予約のすべてのリクエストには有効な JWT トークンが必要であり、認証されたユーザーのみがシステムにアクセスできるようにします。
  • データ検証: 無効なデータや悪意のあるデータが処理されるのを防ぐために、入力データはすべてのステップで検証されます。
  • ロックの有効期限: Redis ロックには、予約プロセスが途中で失敗した場合のデッドロックを防ぐための有効期限 (10 秒) が組み込まれています。

6. スケーラビリティに関する考慮事項

システムは拡張性を念頭に置いて構築されています。需要が増加するにつれて、次の戦略によりスムーズな運用を確保できます:

  • 同時実行のための Redis: Redis ロックにより、アプリケーションの複数のインスタンスが実行されている場合でも、競合状態が確実に回避されます。
  • Redis クラスタリング: システムが大幅に拡大した場合、Redis クラスタリングを使用して複数の Redis ノードに負荷を分散し、パフォーマンスを向上させることができます。

結論

スケーラブルで信頼性の高い スロット予約システム を構築するには、同時実行性、データの整合性、セキュリティについて慎重に検討する必要があります。 Redis 分散ロック を使用すると、2 人のユーザーが同じスロットを同時に予約することがなくなり、競合状態が排除されます。さらに、データの永続化に MongoDB を、認証に JWT を利用することで、このシステムは安全でスケーラブルで効率的です。

会議室、イベント、またはその他の時間制限のあるリソースの予約システムを設計している場合でも、このアーキテクチャは、高負荷下でも予約を確実に管理するための強力な基盤を提供します。

以上がRedis 分散ロックを使用したスケーラブルなスロット予約システムの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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