マイクロサービスのインフラ層でRedisを活用する方法:イベントストアとメッセージキューの実装
2019年、筆者はRedisでイベントストアを作成する方法についての記事を執筆しました。その中で、Redis Streamsはトランザクションログのようなイミュータブル(不変)な追記専用の仕組みでイベントを保存できるため、イベントストアに最適であると説明しました。今回は、当時紹介したサンプルアプリケーション「OrderShop」をアップデートし、Redisをメッセージキューとして活用する方法を実演します。これにより、キャッシュ以外にも多くのユースケースを持つRedis Enterpriseの可能性をさらにご紹介していきます。
マイクロサービス、インフラストラクチャサービス、分散システムの基礎知識
Redisは、メッセージキューやイベントストアといったインフラストラクチャサービスを構築するための優れたソリューションです。ただし、マイクロサービスアーキテクチャで分散システムを構築する際には、いくつか考慮すべき点があります。リレーショナルデータベースはモノリシックなアプリケーションには適していましたが、マイクロサービスアーキテクチャに求められるスケーラビリティと可用性の要件を満たせるのは、RedisのようなNoSQLデータベースです。
分散システムでは、状態も分散されます。CAP定理によれば、ソフトウェア実装が同時に実現できるのは「一貫性(Consistency)」「可用性(Availability)」「分断耐性(Partition tolerance)」という3つの属性のうち2つまでです。したがって、フォールトトレラントなシステムを実現するには、可用性と一貫性のどちらかを選択しなければなりません。可用性を選択した場合、結果的に結果整合性(eventual consistency)となります。つまり、データは一定時間の経過後に一貫した状態になるということです。一方、一貫性を選択すると、分散システム全体で書き込み操作の同期と分離が必要になるため、パフォーマンスに影響が出ます。
イベントソーシングは、注文や顧客などのビジネスエンティティの状態を、状態変更イベントの時系列として永続化する手法で、一貫性よりも可用性を優先します。この手法では書き込み操作は非常にシンプルになりますが、読み取り操作のコストは高くなります。複数のサービスにまたがる読み取りの場合、リードモデルなどの追加の仕組みが必要になることがあるためです。
分散システムにおける通信方式には、ブローカーありとブローカーなしの2種類があります。ブローカーなし方式は広く知られており、最も有名な例がHTTPです。ブローカーあり方式は、名前の通り、メッセージの送信者と受信者の間にブローカーが介在します。これにより送信者と受信者が疎結合になり、同期・非同期の両方の通信が可能になります。メッセージ送信時にコンシューマーが稼働している必要がないため、よりレジリエント(障害耐性の高い)な動作が実現します。また、ブローカー経由の通信では、送信者と受信者をそれぞれ独立してスケールさせることもできます。
(詳細については、同期・非同期通信のニーズに応じた選択肢――Redis Streams、Redis Pub/Sub、Kafkaなど――に関する記事も併せてご覧ください。)
OrderShop:Eコマースのサンプル実装
マイクロサービスアーキテクチャにおける「Hello World」といえるのがOrderShopです。これは、イベント駆動型のアプローチを用いたEコマースシステムのシンプルな実装です。このサンプルアプリケーションはシンプルなドメインモデルを使用していますが、アプリケーションの目的は十分に果たせます。
OrderShopはDocker Composeを使ってオーケストレーションされており、すべてのネットワーク通信はgRPCで行われます。中心的なコンポーネントはイベントストアとメッセージキューで、すべてのサービスはgRPC経由でこの2つにのみ接続します。OrderShopはPythonによるサンプル実装で、ソースコードはGitHubで公開されています。
(注意:このコードは本番環境向けではありません。デモ目的のみのものです!)
実行手順
- GitHubリポジトリをクローン:https://github.com/redis-demos/ordershop-v2
- 以下の5ステップでOrderShop v2を実行できます
- docker-compose upでアプリケーションを起動
- ブラウザでhttps://localhost:5000/を開く
- イベントの監視と状態の閲覧が可能
- python -m unittest tests/unit.pyでクライアントを実行
- ブラウザで別タブを開き、https://localhost:8001/にアクセス
- redis:6379を使用してテストデータベースに接続
- docker-compose downでアプリケーションを停止
OrderShop v2のアーキテクチャ
このサーバーアーキテクチャは複数のサービスで構成されています。状態は複数のドメインサービスに分散していますが、単一のイベントストアに格納されます。Read model(リードモデル)コンポーネントは、状態の読み取りとキャッシュのロジックを集約しており、以下の図のように配置されています。
コマンドとクエリはMessage queue(メッセージキュー)コンポーネント経由でやり取りされ、イベントはEvent store(イベントストア)コンポーネント経由で伝達されます。イベントストアはイベントバスとしても機能します。
インフラストラクチャサービス
OrderShop v2では、すべてのユニキャスト通信はMessage queueコンポーネント経由で行われます。ここではRedis Listsを使用し、特に2つのリストを組み合わせた「reliable queue(信頼性のあるキュー)」を実装しています。このキューは、単純なコマンド(単一エンティティへの操作など)を同期的に処理し、長時間かかる処理(バッチ処理やメール送信など)は非同期で処理します。また、同期メッセージへの応答も標準でサポートしています。
Event storeはRedis Streamsをベースにしています。ドメインサービス(OrderShopの機能を実証するためのダミー実装)は、イベントトピック(エンティティ名)にちなんだ名前のイベントストリームを購読し、これらのストリームにイベントを公開します。各イベントはストリームエントリであり、イベントのタイムスタンプがIDとして機能します。ストリームに公開されたすべてのイベントの集積が、システム全体の状態となります。
アプリケーションサービス
Read modelは、ドメインモデルを使用して、Event storeから導出されたエンティティをRedisにキャッシュします。キャッシュを除けば、ステートレスです。
API gatewayもステートレスで、ポート5000でREST APIを提供します。HTTP接続を終端し、状態を読み取る(クエリ)場合はリードモデルへ、状態を書き込む(コマンド)場合は専用のドメインサービスへとルーティングします。この読み取り操作と書き込み操作の概念的な分離は、CQRS(Command Query Responsibility Segregation:コマンドクエリ責務分離)と呼ばれるパターンです。
ドメインサービス
ドメインサービスは、API gatewayからの書き込み操作をMessage queue経由で受け取ります。実行が成功すると、それぞれの操作に対するイベントをEvent storeに公開します。対照的に、すべての読み取り操作は、Event storeから状態を取得するRead modelが担当します。
CRMサービス(顧客関係管理サービス)はステートレスで、イベントストアからのドメインイベントを購読し、Mail serviceを使用して顧客にメールを送信します。
中心となるドメインエンティティは注文です。「status」というフィールドを持ち、その遷移は下図に示すステートマシンによって実行されます。
これらの遷移は、ドメインイベントを購読する複数のイベントハンドラー(SAGAパターン)で実行されます。例えば以下のようなケースです。
クライアント
クライアントはPythonのUnitテストフレームワークを使ってシミュレートされています。現在10個のユニットテストが実装されています。詳細はtests/unit.pyをご覧ください。
ポート5000では、WebSocketを使用してイベントを監視し、状態を閲覧できるシンプルなUIが提供されています。
Redisインスタンスを調査するためのRedisInsightコンテナも用意されています。ブラウザでhttps://localhost:8001/を開き、redis:6379を使用してテストデータベースに接続してください。
まとめ
Redisは、ドメイン層(カタログ検索など)やアプリケーション層(HTTPセッションストアなど)だけでなく、インフラストラクチャ層(イベントストアやメッセージキューなど)でも強力なツールです。これらの層全体でRedisを使用することで、運用オーバーヘッドが削減され、開発者は既に熟知している技術を再利用できます。
ぜひコードを覗いてみて、実際に実装してみてください。この記事が、ドメインサービスとインフラストラクチャサービスにおけるRedisの多用途性と柔軟性を示し、キャッシュ以外の用途でも活用できることを証明できれば幸いです。
試してみた感想は、Twitter(@martinez099)でお知らせください。
-
Windows 10のタスクバーからカレンダーを使う方法!予定の追加・確認も簡単
Windows 10には標準で「カレンダー」アプリが搭載されていますが、実はタスクバーから直接利用できることをご存じの方は少ないのではないでしょうか。タスクバーからデスクトップカレンダーにアカウントを連携させることも可能で、予定の確認や編集をタスクバー上で手軽に行えます。2019年11月のアップデートでは、タスクバーから直接リマインダーや予定を追加できる機能も加わりました。 タスクバーからカレンダーを開く方法 Windows 10のカレンダーは、タスクバーの時刻表示をクリックするだけで開くことができます。カレンダーは画面右下、時計と並んで配置されているため、もし時計をタスクバーの別の場所へ移動
-
Windowsイベントビューアの使い方と活用メリットを徹底解説
Windows 10は世界で最も広く使われているOSであり、市場シェアの大部分を占めています。MicrosoftはWindowsをより効率的かつ安全にするため、定期的に新しいアップデートを提供し続けています。 ところで、「Windowsイベントビューア」をご存じでしょうか?これはWindows OSに標準搭載されている便利なユーティリティツールで、デバイス上で何が起きているのかという情報を記録・保存してくれるものです。 この記事では、Windowsイベントビューアとは何か、その基本的な使い方、そしてなぜ重要なのかについて、知っておくべきポイントをすべてご紹介します。 それでは早速見ていきましょ