token selection workerのsharding機能の概要と効果について考える
2024年「ブロックチェーンビジネス・アドベントカレンダー企画」14日目の記事です。 関連企業の皆様にも記事を書いていただく予定ですので、是非お立ち寄りください!
はじめに
この記事ではCorda clusterの構築オプションであるtoken selection workerのsharding機能の概要と実装方法、ユースケース事の効果を机上検証した結果をご紹介します。なお言葉は同じですが、データベースのshardingや一般的なブロックチェーンのsharding(バリデーターの分散)とは異なる概念ですのでご注意ください。
想定読者
- Corda clusterのインフラ担当者
前提
- CorDappsが※Tokenアプリであること。 ※Corda5におけるTokenとはUtxoTokenTransactionStateObserverを実装したFlowにて制御されるStateの総称です。Tokenはfungible(同じ種類のTokenをグループ化して使用したり分割することができる特性)な特徴を持つStateで、TokenアプリはそのようなTokenの発行、移転、償還機能を備えたアプリケーションを指します。
- token selection workerを2台以上起動していること。1台の場合でもsharidng機能は使えますが、2台以上token selection workerが起動している場合に効果を発揮します。(その他の項参照)
基礎知識
Tokenアプリの内部処理
token selection workerは文字通りtokenを制御するworkerです。flowを制御するworkerから呼び出されてtokenを確保します。flow workerはworkerはHTTP/sプロトコルでのクライアントサーバー通信でtoken selection workerを呼び出します。使用中のtokenは一時的にキャッシュテーブルに蓄積されます。
TokenはFlow中の明示的リリース、もしくは、キャッシュのタイムアウトによりToken Cacheから除外されます。
token selection workerとテーブルのやり取りにフォーカスすると以下のような図式になります。
- Node AliceがTokenを保有していると仮定
- token selection worker #1がAliceのTokenをテーブルから取得
- token selection worker #1がキャッシュテーブルにレコードを挿入
Tokenの更新失敗 ~ 再試行
複数のtoken selection workerが偶然同じtokenを操作しようとした場合、後発のtoken selection workerは「Optimistic locking prevented updates to the following States」というWARNを出力しflow workerに503エラーを返します。503エラーを受け取ったflow workerは100msを置いてリトライします。リトライは最大3回試行され、それ以上失敗した場合はFlow APIは例外をスローします。
- 「Token使用時の内部処理」のtoken selection workerとテーブルのやり取りフローの「2」と「3」の間でtoken selection worker #2がAliceのTokenをテーブルから取得したと仮定
- token selection worker #1がキャッシュテーブルにレコードを挿入
- token selection worker #2がキャッシュテーブルに挿入を試行するが、すでに同一キーのレコードがあるため失敗する
- Flow workerにリターンコード503を返す。Flow workerは3回までリトライを試行する
shardingの導入
「Tokenの更新失敗 ~ 再試行」のとおりTokenロックの競合が発生した場合、flow workerとtoken selection workerの間でリトライ処理が発生します。再試行時に別のTokenをロックできればFlowは成功しますがリトライの分パフォーマンスが劣化します。この課題を解決するのがtoken selection workerのshardingによる分散機能です。
shardingはnginxを実装したingressリソースをtoken selection workerおよびtoken selection internal serviceの前面に配置することでhttpリクエストによるロードバランシングを実現します。
URLパラメータ評価によるロードバランシング
nginxはflow workerから渡されたURLのパラメータを評価して送信するtoken selection workerを決定します。以下はFlow workerから受け取ったnginxがどのように宛先を決めるかを解説する図です。
- Flow workerからリクエストを送信。URLは「仮想NodeのID, トークンタイプ, 発行者, Notary, シンボル」から成り立つ。
- nginx内でリクエストをハッシュ化。
- ハッシュを
nginx.ingress.kubernetes.io/upstream-hash-by
に渡し、送信するtoken selection workerを決定
- token selection workerに送信。flow workerから渡されるパラメータが同じ場合常に同じハッシュが作られるので、常に同じworkerに送信される。
ロードバランシングによる競合回避
次にロードバランシングがなぜ競合を回避できるかを説明します。
- token selection workerが2つ起動していると仮定
- token selection worker #1がAliceのTokenをテーブルから取得
- 2番目のAliceのTokenロック要求受信。「URLパラメータ評価によるロードバランシング」にあるとおり、同一属性の場合は常に同じtoken selection workerにルーティングされる。またCordaのworkerはシングルスレッドであり、かつ「テーブルからのToken取得」から「Cacheへの書き込み」まではアトミックである。そのため新たなAliceのTokenのロック要求を受信しても、一つ前の処理が完了するまでは待ち状態になり順序性が担保される。
- token selection worker #1がキャッシュテーブルにレコードを挿入
- 1番目のリクエストが完了したので2番目のリクエストを開始。使用中ではないAliceのTokenをテーブルから取得
- token selection worker #1がキャッシュテーブルにレコードを挿入
設定
shardingのためのingressリソースは、corda5のyamlファイルのtoken selection workerのセクションに定義します。
workers:
crypto:
.
.
.
# workerのtokenSelection配下のshardingセクションを追加
tokenSelection:
debug:
enabled: true
logging:
level: all
image:
repository: "corda-ent-token-selection-worker"
replicaCount: 2
sharding:
# -- shardingの使用有無
enabled: true
# 使用するimage。
image:
# -- token selection sharding image registry
registry: "registry.k8s.io"
# -- token selection sharding image repository
repository: "ingress-nginx/controller"
tag: "v1.9.3"
# sharding podのレプリカ数。tokenSelectionのレプリカ数とは別。適切なレプリカ数に関しては「その他」の項目を参照
replicaCount: 1
定義をした後は、helm installやupgradeで更新を反映します。
helm install corda ./corda-enterprise-5.2.1.tar -f ./values.yaml
プロンプトが返ってきたら、kubectl get ingressでingressリソースが作られていることを確認します。
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
corda-corda-enterprise-token-selection-worker-sharded <none> * 10.100.170.146 80 5m
もしくはFlow workerのtoken selection workerのエンドポイントがnginxになっていればOKです。
# kubectl describe deployments.apps corda-corda-enterprise-flow-worker | grep "endpoints.tokenSelection"
--serviceEndpoint=endpoints.tokenSelection=corda-corda-enterprise-token-selection-worker-nginx:7000
その他
sharding podのレプリカ数について
sharding podはtoken selection workerと1対1にする必要はなくまた処理コストも少ないためたくさんのレプリカは不要です。ただし冗長性を鑑みると、本番環境では2以上に設定することが望ましいと考えます。
おわりに
sharding自体はあらゆるケースで効果を発揮するものではなく、特定の条件化のもとで効果を発揮するものと考えられます。こちらの検証記事に関しましても準備中ですが、公開されましたら併せてごらんいただければと思います。
<ご質問・ご要望の例>
- Corda Portalの記事について質問したい
- ブロックチェーンを活用した新規事業を相談したい
- 企業でのブロックチェーン活用方法を教えて欲しい 等々
SBI R3 Japan エンジニアリング部所属
ソリューションアーキテクト/PoC支援
This is the way. みんなでキャズムを超えていきましょう!