Corda5のアーキテクチャ・内部サービス構成・3つのデプロイ方法
- はじめに
- 1. Corda5のアーキテクチャ概要
- Corda 5のクラスターを構成する「ワーカーノード」
- なぜ設計段階から冗長性を組み入れるのか?
- 2. Corda5の内部サービス構成
- Flowエンジン (Flow Engine)
- FlowSessionマネージャー (Flow session manager)
- DBサービス (DB Service)
- 暗号サービス (Crypto Service)
- HTTPS RPCサービス (HTTPS RPC service)
- P2P HTTPSゲートウェイ (P2P HTTPS Gateway)
- シングルトンサービス (Singleton Service)
- スキーマサービス (Schema Service)
- MGM (メンバーシップ・グループ・マネージャ)キャッシュ
- コンフィギュレーションサービス (Configuration service)
- モニタリング
- 3. 3つのデプロイ方法
- 「シンプル」アーキテクチャ
- 「高SLA」アーキテクチャ
- セキュリティとセキュリティ課題に対する耐性
- サービスの耐障害性
はじめに
前回までの2回(1回目、2回目)は、Corda5の概要でした。シリーズの最初の深堀りでは、Corda 5最大の変更点である、新しいアーキテクチャを取り上げます。Corda 5のアーキテクチャとデプロイ方法は、”高可用性”と”スケーラビリティ”を実現するように設計されています。高い信頼性を必要とするシステムに不可欠なこの2つの側面を、Corda5アーキテクチャ検討の中心に据えました。可用性、スケーラビリティを高い信頼性のもとで実現する新しいCorda 5ノードのアーキテクチャの方向性をお伝えします。
最初の記事で述べたように、Corda 5を定義するにあたり、私たちは
「ミッションクリティカルなサービスが必要とする高可用性要求を満たすことができるアーキテクチャ」と、「バースト的な高スループットに対応するために水平方向に拡張可能なアーキテクチャ」をコスト効率の高い方法で実現することを目指しました。
私たちが目指したのは、国全体の通貨供給や世界最大の国際決済ネットワークを動かすことができる、そんなスケーラブルで可用性の高い分散型システムを構築することでした。
このブログ記事では、
- アーキテクチャの概要
- 内部サービス構成
- 3つのデプロイ方法
についてご紹介します。
1. Corda5のアーキテクチャ概要
Corda 5の特徴は、完全に冗長化されたワーカーベースのアーキテクチャを、ノードに必要なすべての重要なサービスに適用することです。
ノードサービス間の通信を促進するメッセージブローカーとして、Kafkaクラスタを使用しています。
Corda 5のアーキテクチャは、複数のワーカークラスターで構成されています。一つのワーカークラスタは、ワークロードをワーカーに均等に分配する形で、クラスタ内での(水平)スケーリングを実現します。
ワーカーの作業配分はKafkaがおこないます。ワーカーごとに処理の一部を負担し、負荷は動的に分散されます。これにより、Hot-Hot要件を満たし、オンデマンドでスケール変更するためのクラウド技術を利用することができます。反対にアイドル時にはワーカーの数を簡単に減らすことができます。
Corda 5のクラスターを構成する「ワーカーノード」
一つのワーカーは、一つのJava Virtual Machine (JVM) インスタンスを指します。JVMインスタンスは、一塊の処理を実施するために必要な幾つかのサービスを実行します。
各サービスは独立して動作し、ユーザーコード実行、データベースへの問い合わせ、設定管理など、明確に定義された機能を実行します。ワーカーは、Kafkaクラスターの機能を使用して相互に通信し、最新の状態を保存および取得するメカニズムとして、コンパクト化されたトピック(ログ)を使用します。(トピックについては、こちらなどが参考になります。)
サービスごとに(Hot-Hot)構成されたクラスタが、(水平)スケーリングを容易にし、サービスを組み合わせることで、さまざまなワークフローに適応させることを可能にしています。
なぜ設計段階から冗長性を組み入れるのか?
製品に最初から「冗長性」を組み込むことは、奇妙な選択に見えるかもしれません。しかし、冗長性とは、「システムの各コンポーネントがサービスを中断することなく交換可能」であることを意味します。これは、高可用性アーキテクチャの要になり、予測不可能なサービス停止イベントに対するフェイルセーフになります。
ミッションクリティカルで、リアルタイム処理を要するトランザクションが処理されている場合、目立ったダウンタイムは許されないことが一般的です。冗長性があれば、一部のワーカーが応答しなくなっても、トランザクション処理を中断することなく継続できます。
ワーカーはハートビートを送信し、アクティブであることを確認します。Kafkaは、ワーカーのハートビートを検出できない場合、自動的にワークロードを別のワーカーにリダイレクトするため、目立ったダウンタイムを回避できます。
また、ワーカー内のサービスの一つに障害が発生しても、そのワーカー内の他のサービスは影響を受けません。一つのサービスに対して、複数の冗長インスタンスが別々のワーカーで実行されています。そのため、システムは完全な(水平方向の)スケーラビリティを備えており、需要が増加した場合にはより多くのワーカーを追加してメッセージを並行して処理することができます。
2. Corda5の内部サービス構成
Corda 5の設計方針の一つは、内部サービスを用途に応じてグルーピングし、グループごとに別々のワーカーで稼働させるようにすることです。これにより、システム運用者は、特定のSLAを満たす方法をより細かくコントロールすることができるはずです。モジュール方式を採用したことで、エンドユーザーのシステム要件に合わせて広範囲にカスタマイズ可能なシステムを実現しています。Corda5を構成する各サービスの概要は以下の通りです。
Flowエンジン (Flow Engine)
Flowエンジンには、ユーザーのFlowコードを実行し、FlowイベントおよびFlowCheckpointトピックのイベントを処理するFlowStateMachineが含まれます。Flowエンジンは、Flowイベントごとに、コンパクト化されたトピックを保存します。また、必要に応じて、FlowCheckPointトピックから対応するFlowCheckPointを読み込んで、その時点からFlowStateMachineを再起動します。そして、FlowStateMachineは、次のFlowCheckpointや他のイベントに到達するまで、ユーザーコードを実行します。次のFlowCheckpointに到達すれば、FlowCheckPointトピックが追加されるますし、他のサービスを必要とするイベントに到達した場合、関連するトピックが流され、他のサービスによる処理が開始されます。
各Flowエンジンは、Kafkaから割りあてられたパーティション (トピックの一部)を処理します。障害が発生した場合、パーティションは生きている他のFlowエンジンに渡されて処理されます。
FlowSessionマネージャー (Flow session manager)
Flowの開始リクエストがRPCや他のNodeから送信されると、FlowSessionマネージャーがリクエストをチェックし、重複を排除します。その後、実行される各Flowに一意のIDを割り当てます。これは、過去の活動の監査証跡を確保するために必要です。又、ノード間でFlowSessionを呼び出す際に、セッション維持することもFlowSessionマネージャーの役割です。
DBサービス (DB Service)
DBサービスは、データベースのクエリを処理します。イベントごとに、問い合わせ、処理実行、結果返却をおこないます。台帳データの書き換えなど、特定のテーブルの変更は、プッシュ通知によってリスナーに通知されます。DBサービスの各インスタンスは、”DBクエリ”トピックの1つのパーティションを処理します。
暗号サービス (Crypto Service)
暗号サービスは、公開鍵と秘密鍵の検索処理と関連タスクを実行しますします。タスクには、署名要求、新しいキーペア生成、および証明書の保存と取得が含まれます。イベントごとに、暗号サービスは鍵問い合わせ、タスク実行、結果返却など一連の作業を実行します。又、認証管理サービスの各インスタンスは、暗号に関するトピックの1つのパーティションを処理します。
HTTPS RPCサービス (HTTPS RPC service)
RPCサービスは、クライアントからのRPCリクエストを処理し、RPC経由で新しいフローが開始されたときにフローIDをクライアントIDにマッピングし、リクエストの進捗状況をクライアントに知らせます。また、HTTPS RPCリクエストをこのサービスで処理できるように変換する、HTTPS変換レイヤーがあります。
P2P HTTPSゲートウェイ (P2P HTTPS Gateway)
Flowが別のノードと通信する必要がある場合、P2P HTTPSゲートウェイがノード間メッセージを管理します。
このサービスは
- 信頼性の高いメッセージ配信機能(重複排除機能含む)
- セキュア・リンク・マネージャ
- P2P HTTPSゲートウェイ
などの機能を持ちます。
このサービスはFlowエンジンによって生成されたメッセージを消費し、P2P HTTPSゲートウェイを通じてセキュア・リンク・マネージャーにメッセージを転送します。
受信側のメッセージ配信機能は、最初のメッセージを受信したという確認を送信します。メッセージはセッション管理するためにFlowSessionマネージャに登録された後、FlowイベントがFlowStateMachineに送信されます。
又、重複排除機能を持つため、メッセージが複数回送信された場合や、ノード間で送信されるメッセージの順序が間違っている場合に、誤った処理が実行される心配はありません。一方で、”セキュア・リンク・マネージャ”と”P2P HTTPSゲートウェイ”は、耐障害性や耐久性などに関して懸念する必要はありません。
シングルトンサービス (Singleton Service)
シングルトンサービスは、常に1つのワーカーだけがアクティブとなる必要があるサービスに使用されます。例えば、台帳変更のイベントに反応してFlowを開始するサービスの場合、複数ワーカーがアクティブだと、誤って複数のフローを開始してしまう可能性があります。シングルトンサービスは、それ自体マルチスレッドであることを妨げるものではありません。
リーダー選挙コンポーネントは、どのワーカーが現在アクティブであるかを決定する役割を担っています。又、障害が発生した場合にその他のワーカーが引き継ぐことができるように待機しています。
スキーマサービス (Schema Service)
Kafka では、メッセージを Kafka ストリームに追加する前にシリアル化する必要があります。Corda 5では、シリアル化スキーマとしてAvroを使用しています。各サービスは、オブジェクトをシリアライズおよびデシリアライズする際に、スキーマサービスにアクセスできる必要があります。(訳注※サービスの可用性がスキーマサービスの可用性に依存するので)当初、スキーマサービスは、各プロセスが使用するプロセス内レジストリとなる予定です。
将来的には、Avro スキーマの進化を利用してワーカー・プロセスのローリング・アップグレードを処理し、古いプロセスが新しいメッセージ・スキーマについての情報を得て、それを適切に処理または無視できるようにする予定です。
MGM (メンバーシップ・グループ・マネージャ)キャッシュ
ノード上で実行されている各 ID について、MGMキャッシュは、そのノードが所属する各メンバーシップ・グループを表す ID のセットを維持します。MGM キャッシュは、圧縮されたトピックを使用して、メンバーシップ情報を保存します。
コンフィギュレーションサービス (Configuration service)
コンフィギュレーションサービスは、システムのコンフィギュレーションリクエストを管理します。各要求は検証され、要求が成功したか失敗したかを示す応答イベントを呼び出し元に返します。設定状態は、システムの他のコンポーネントからアクセスできるように、コンパクト化されたトピックに追加されます。設定はデータベースにも保存されます。
モニタリング
モニタリングサービスは、JMX メトリクスを使用してシステムの健全性を監視することになります。各ワーカーはそれぞれ独自の監視サービスを持ち、それぞれのメトリクスは照合されてシステムオペレータに報告されます。あるいは、監視インフラがKafkaから直接データを引き出すことも可能です。
3. 3つのデプロイ方法
私たちは、エンドユーザーの要件に応じて、異なるレベルの可用性を保証する「シンプル」、「高SLA」、それから「オールイン」の、3つの異なるデプロイモデルを設計しました。
1. 「シンプル」なアーキテクチャは、効率的で信頼性の高いが、同時に費用対効果も追求します。
2. 「高SLA」なアーキテクチャは、最大限のパフォーマンスと信頼性を確保したいユーザーに向けたアーキテクチャになります。
3. 高可用性を必要とする本番環境向けアーキテクチャとは別に、低コスト or 開発用に、「オールイン」のオプションもあります。
「シンプル」アーキテクチャ
このアーキテクチャは、以下3つの特徴を備えます。
・ソフトウェアの分離可能
・展開容易
・(水平)スケーリング可能
このアーキテクチャは、Corda4のノードとFirewallの可用性を改善する(Hot-Hot構成)一方で、”シンプルなDeploy”や”DMZと信頼できる内部に分離したサービス構成”といった特徴を維持します。
サービスは2つの独立したワーカーに展開されます。一つにP2P HTTPSゲートウェイが配置され、もう一つにそれ以外のサービスが配置されます。ゲートウェイ側はインターネットに直接接続されているため、その他のサービスから分離する必要があります。
ワーカーは、冗長化された並列インスタンス上に配置され、需要に応じて(水平)スケーリング可能です。各ワーカーには独自の監視サービスがあり、システムエラーやパフォーマンスに関する最新情報をノードの管理者に提供します。
「高SLA」アーキテクチャ
この構成は、プロセスがより細分化されます。その為、より高い可用性が実現できるとともに、より細かい単位で(水平)スケーリングのコントロールできます。しかし、その分、導入プロセスが複雑になります。
以下の通り、サービスは機能テーマごとに4つの独立したワーカーにまとめられています。
・HTTPS RPCサービス
・フローエンジン
・データベースと暗号サービス
・HTTPS P2Pゲートウェイ
各ワーカーには監視サービスがあり、システムのエラーやパフォーマンスに関する最新情報をノードの管理者に提供します。
このアーキテクチャは、コストパフォーマンスを高めるために、ワーカーの数を最適化することが可能です。負荷の高いサービスだけワーカーの数を増やし、負荷の低いサービスのワーカーを減らすことができます。
お客様のニーズに応じて、サービスをさらに細分化することも可能ですが、その場合は展開プロセスがより複雑になります。
セキュリティとセキュリティ課題に対する耐性
各ワーカー内のサービスは、システム内での悪意ある攻撃を防ぐために、各々独立したサンドボックス上に分割されています。 例えば、FlowエンジンとDBサービスを分離することで、悪意のあるユーザーがFlowエンジン経由でデータベースに保存されている情報にアクセスしようとすることを防ぎます。
ワーカーに致命的なエラーが発生した場合、そのワーカー内のすべてのサービスが停止します。このとき、Kafkaのフェイルオーバーメカニズムは、先に示したアーキテクチャ概要のセクションで説明したように、メッセージを他のワーカーにリダイレクトします。
「高SLA」アーキテクチャでは、サービスは別々のワーカー上で実行されるため、(ソフトウェア分離に加えて)プロセス分離も保証されています。サービスが2つの独立したJVMインスタンス上に存在するため、悪意のあるユーザーであっても、他のワーカーに展開されたサービスにアクセスすることはできません。
サービスの耐障害性
ワーカー上で動作しているサービスが停止したり、反応停止したりした場合に備えて以下のような対策がとられています。
・Kafkaが作業を他のワーカーにリダイレクトする。
反応のなくなったサービスは、ハートビートを送信しなくなります。(本概要の欄で説明しています)Kafka は、ワーカーのハートビートを検出できない場合、ワークロードを他のワーカーに自動的にリダイレクトします。
・応答のないサービスはKafkaクラスタに参加できない。
サービスが起動時の処理(設定の読み込み等)に失敗したり、関連サービスに連絡できなかったりすると、そのサービスはメッセージの消費(処理)を開始しません。Kafkaの持つドミノロジックにより、サービスがKafkaに接続(subscribe)するためには、サービスの準備が完全に整ったことを確認する必要があります。
・プロアクティブモニタリング。
モニタリングサービスには、「ウォッチドッグ(watchdog)」機能が含まれます。これにより、安定していないサービスを停止させることができます。
<ご質問・ご要望の例>
- Corda Portalの記事について質問したい
- ブロックチェーンを活用した新規事業を相談したい
- 企業でのブロックチェーン活用方法を教えて欲しい 等々
SBI R3 Japan エンジニアリング部長
書籍出してます:https://amzn.asia/d/c0V31Vd
趣味:サッカー、ガンプラ、ドライブ、キャンプ