主な要点

  • Binance の台帳は、アカウント残高と取引を保存すると同時に、サービスによる取引も可能にします。

  • これにより、高スループット、年中無休の可用性、ビットレベルのデータ精度に必要な条件が整います。

Binance Ledger は舞台裏での役割を果たしているため、Binance の最も重要なテクノロジーの 1 つとなっています。ここで、世界最大の暗号通貨取引所の運営においてその仕組みと解決している問題を正確に学びましょう。

Binance がなぜ動いているのか、正確に考えたことはありますか?大規模なユーザーベースで毎日数百万件のトランザクションを処理する必要があるため、Binance が内部で何を実現しているのかを見てみる価値があります。

Binance の技術的運用の基盤となっているのは、元帳です。元帳はアカウントの残高と取引を保存し、サービスが取引を行えるようにします。

Binanceは元帳に対して高い要件を課している

ご想像のとおり、膨大なユーザー需要を満たすには、Ledger に対する要件は高くなります。考慮すべき主なポイントは 3 つあります。

  • ピーク時に大量の TPS (1 秒あたりのトランザクション数) を実現できる高スループット。

  • ダウンタイムなしで 24 時間 365 日ご利用いただけます。

  • 資金の損失や取引エラーのない、ビットレベルのデータ精度。

元帳の基本的なエントリの例を見てみましょう。これは、アカウント 1 が 1 BTC をアカウント 2 に転送する一般的なトランザクションです。

取引前の残高:

アカウントID

資産

バランス

1

BTC         

10

2

ビットコイン

0.1

表1

取引後の残高:

アカウントID

資産

バランス

1

BTC         

9

2

ビットコイン

1.1

表2

このトランザクションには、次の 2 つのコマンドがあります。

  1. アカウント 1 -1 BTC

  2. アカウント 2 +1 BTC

取引が行われると、監査と調整のために 2 つの残高ログが保存されます。

アカウントID

資産

デルタ

TX_ID

時間

100001

ビットコイン

-1

TX-001 の検索結果

2022-01-01  01:02:03

100002

ビットコイン

+1

TX-001 の検索結果

2022-01-01  01:02:03

表3

業界標準ソリューション

業界標準の Ledger ソリューションの 1 つは、リレーショナル データベースに基づいています。前の例に戻ると、トランザクションの 2 つのコマンドは 2 つの SQL ステートメントに変換され、データベース トランザクションで実行できます (表 4)。

取引を開始する。

balance_1 を更新し、balance = balance - 1 に設定します

ここで、account_id=1、asset = ‘BTC’、balance - 1 >= 0;

影響を受ける行が 0 行の場合はロールバックします。

balance_2 を更新し、balance = balance + 1 に設定します

ここで、account_id=2、asset = ‘BTC’、balance + 1 >= 0;

影響を受ける行が 0 行の場合はロールバックします。

専念;

表4

ソリューションの利点

  1. 実装するのは非常に簡単です。

  2. 読み取り/書き込みの分割やシャーディングなどの一般的なデータベース チューニング手法を簡単に適用して、パフォーマンスを向上させることができます。

  3. DevOps にとって、フェイルオーバーからの回復や商用データベースの監視および保守は難しくありません。

この解決策の欠点

  1. 行ロックによる競合状態が発生すると、TPS は急激に低下します。

  2. パフォーマンスを向上させるために水平方向にスケーリングするのは困難です。

ホットアカウントの問題

残念ながら、Binance にとって、上記で示した業界ソリューションは、その高い要件を満たしていません。トランザクションが発生すると、関連するすべての行の行ロックを保持する必要があります。一部のアカウントでは処理するトランザクションが比較的少ない一方で、もちろん、同時トランザクションが多数ある忙しいアカウントもあります。この場合、アカウントの行ロックを保持できるのは 1 つのトランザクションだけです。

他のトランザクションはロックが解除されるのを待つことしかできません。この状況をホット アカウント問題と呼んでいますが、内部テストではこの状況では TPS が少なくとも 10 倍低下することが示されています。この問題は、下の表 5 で確認できます。

ホットアカウントの例:

Tx 1 (アカウント1からアカウント2に1 BTCを送金)

Tx 2 (アカウント 1 からアカウント 3 に 2 BTC を転送)

取引を開始する。

取引を開始する。

バランスを更新します。バランスを = バランス - 1 に設定します。

ここで、account_id=1、asset = ‘BTC’、balance - 1 >= 0;

(行がロックされています: account_id=1、asset = ‘BTC’)

影響を受ける行が 0 行の場合はロールバックします。

バランスを更新します。バランス = バランス - 2 を設定します。

ここで、account_id=1、asset = ‘BTC’

残高 - 2 >= 0;

影響を受ける行が 0 行の場合はロールバックします。

バランスを更新します。バランス = バランス + 1 を設定します。

ここで、account_id=2、asset = ‘BTC’、balance + 1 >= 0;

影響を受ける行が 0 行の場合はロールバックします。

待機ロック

専念;

待機ロック

ロックを取得して実行

バランスを更新します。バランス = バランス + 2 を設定します。

ここで、account_id=3、asset = ‘BTC’、balance + 1 >= 0;

影響を受ける行が 0 行の場合はロールバックします。

専念;

表5

BinanceのLedgerソリューション

ホットアカウントの問題をどのように解決するのでしょうか?

この問題の解決策として考えられるのは、マルチスレッド モデルをシングルスレッド モードに革新的に変換することです。これにより競合状態の問題が回避され、結果としてホット アカウントの問題も発生しなくなります。

新しいスレッドモデル

メッセージベースのコミュニケーション

新しいスレッド モデルを実装した後、通信の問題を解決する必要があります。ステート マシン層はシングル スレッドですが、ネットワーク層はマルチ スレッドなので、この 2 つの層の間で効率的に通信するにはどうすればよいでしょうか。

ディスラプター[1]はパズルの次のステップです。リングバッファ設計に基づいて、ロックフリーの高性能キューを作成します。

高可用性

これまで、インメモリモデルとRocksDB [2]ローカルストレージを使用することで高いパフォーマンスを実現してきました。しかし、ここでまた新たな課題が発生しました。今度は、高いデータ可用性を考慮する必要があるのです。

ノード間のデータの一貫性を確保するために、Raftコンセンサスアルゴリズム[3]を使用します。これは、データバックアップの数が、存在する非リーダーノードの数に等しいことを意味します。このアルゴリズムは、少なくとも半数のノードが正常な状態でシステムが引き続き動作することを保証し、高いサービス可用性を提供します。

Raft ドメインの役割:

  • リーダー。リーダーはすべてのクライアント要求を処理し、その操作をすべてのフォロワーに複製します。

  • フォロワー。フォロワーはすべての操作においてリーダーに従います。リーダーが失敗した場合、フォロワーの 1 人が新しいリーダーとして選出されます。

  • 学習者。学習者は、各冪等性/トランザクション変更レコードを他のサービスに送信する非投票フォロワーです。

Raftドメインの役割

CQRS (コマンド クエリ責任分離)

私たちが保証したいもう 1 つの重要な基準は、Ledger の書き込みパフォーマンスの向上と、より多様なクエリ条件に対応する機能です。このためには、さまざまなドメインを作成する必要があります。raft ドメインは rocksdb+raft に基づいてより効率的な書き込みを提供し、view ドメインは raft ドメインのメッセージをリッスンして、外部クエリ用にリレーショナル データベースに保存します。また、アーキテクチャ レベルでコマンド クエリの責任分離を実装することもできます。

元帳アーキテクチャ

全体的なアーキテクチャ

Raft と Ledger 間の規約:

ラフト

元帳

複製されたステートマシン

元帳ノード

バランス

指示

取引

表6

ドメインロールの表示

  • ラフトレジャーセンター

学習者によって生成されたメッセージを消費し、クエリの目的でトランザクションと残高データを MySQL に保存します。

リクエスト処理

トランザクション リクエストは、まずネットワーク層、台帳層 (リクエスト ハンドラー)、および raft 層 (raft ログ同期) を通過します。その後、台帳層 (ステート マシン)、ネットワーク層 (レスポンス ハンドラー) に戻り、最後にクライアントにレスポンスを返します。

データは 2 つのレイヤー間のキューを介して渡されます。

  1. ネットワーク層 – RPC 要求をデシリアル化し、要求キューに格納します。

  2. 元帳レイヤー – キューからリクエストを取得し、コンテキストを準備します。次に、リクエストのメタデータをラフト キューに配置します。

  3. Raft レイヤー – ラフト キューからリクエスト メタデータを取得し、すべてのフォロワー間で同期します。その後、結果を適用キューに配置します。

  4. 元帳レイヤー – 適用キューからデータを取得し、ステートマシンを更新します。その後、結果を応答キューに格納します。

  5. ネットワーク層 – 応答キューから結果を取得し、応答データを構築してシリアル化してからクライアントに返します。

リクエスト処理

データ復旧

各 Ledger ノードは、期間に基づいて汎用スナップショットをトリガーします。さらに、一貫性のあるスナップショットも実装します。各ノードは同じラフト ログ インデックスでトリガーされ、各ノードがスナップショットをトリガーしたときにステート マシンがまったく同じであることを確認します。その後、スナップショットは Checker による検証とコールド バックアップのために S3 にアップロードされます。

Ledger が再起動すると、ローカル スナップショットを読み取り、ステート マシンを再構築します。次に、ローカル ラフト ログを再生し、最新のインデックスに追いつくまで、リーダーからの最新のログを同期します。ローカル スナップショットまたはラフト ログが存在しない場合は、リーダーから取得されます。

スナップショットとリカバリ

災害耐性

可用性とフォールト トレランスを向上させるために、Ledger ノードは異なるゾーンにデプロイされます。半数以上のノードが正常である限り、データは失われず、フェイルオーバーは 1 秒以内に完了します。

クラスター全体に障害が発生した場合でも (その可能性は非常に低いですが)、Amazon S3 に保存されている一貫性のあるスナップショットを通じてクラスターを復元し、ダウンストリーム システムを通じて最新の失われたデータを取得できます。

フォールトトレランス

パフォーマンス

次の表は、パフォーマンステストのハードウェア仕様を示しています。

成分

インスタンスタイプ

ネットワーク帯域幅 (Gbps)

EBS 帯域幅 (Gbps)

EBS ストレージタイプ

リーダー/フォロワー

M6i.4xラージ

16c64g

12.5まで

10まで

2T GP3 * 3 IOPS6000 625MB/秒

学習者

M6i.4xラージ

16c64g

12.5まで

10まで

2T GP3 * 3 IOPS6000 625MB/秒

ベンチ

C5.4xラージ

16c32g

10まで

4.750

ルートボリュームのみ

内部テストでは、4 ノード クラスター (リーダー 1 台、フォロワー 2 台、学習者 1 台) が 10,000 TPS 以上を処理できることが証明されています。設計上、クラスターはすべてのトランザクションを 1 つずつ処理します。ロックや競合状態はまったく発生しません。そのため、ホット アカウント シナリオでは、TPS は通常のシナリオと同じくらい高くなります。

ホットアカウントTPS

次の図は、各トランザクションのレイテンシを示しています。ほとんどのトランザクションは 10 ミリ秒以内に完了します。遅いトランザクションは 25 ミリ秒以内に完了します。

レイテンシー(ミリ秒)

Binance Ledgerでサービスを強化

ご覧のとおり、ホット アカウント問題に対する従来の業界の回答は、Binance とその顧客のニーズを満たしていません。Binance のインフラストラクチャ専用に設計されたアプローチを使用することで、最もスムーズな取引所と製品エクスペリエンスの 1 つを実現しました。私たちの経験を皆さんと共有できることを嬉しく思います。Binance のようなサービスが機能するために何が必要なのかをよりよく理解していただければ幸いです。

当社の技術インフラストラクチャの詳細については、次の記事をお読みください。

  • (Binance ブログ) MLOps を使用してリアルタイムのエンドツーエンドの機械学習パイプラインを構築する

  • (Binance ブログ) CTO に会う: Rohit が暗号通貨、ブロックチェーン、Web3、そして Binance での最初の 1 か月を振り返る

参考文献

[1] LMAXディスラプター

[2] RocksDB  

[3] ラフトコンセンサスアルゴリズム