新着:HeliusがLight Protocolを買収
LaserStream SDKでSolana JavaScript gRPCクライアントのスループットを40倍向上
ブログ/開発

LaserStream SDKによる高性能なSolanaストリーミング 

インテグレーションエンジニアXのHet DagliLinkedInのHet Dagli
読了時間:4分
目次

    LaserStreamは、Solanaデータを最小限のレイテンシで配信できるよう最適化された、次世代のgRPCストリーミングサービスです。Yellowstone gRPCインターフェースとの完全な後方互換性を維持しており、コードを変更せずにエンドポイントとx-tokenを変更するだけで置き換えられます。

    DFlowのような先進的なチームはLaserStreamを利用し、比類のない速度と信頼性でリアルタイムの注文フローと約定を監視しています。

    この互換性により、開発者は既存のYellowstone実装からシームレスに移行できます。ただし、標準のYellowstoneクライアントには、組み込みのパフォーマンス最適化機能や信頼性を高める機能がありません。

    LaserStream SDKは、こうした課題を解決します。自動再接続、スロットベースのリプレイ、高負荷なワークロード向けの高スループットアーキテクチャを提供し、信頼性と超低レイテンシのストリーミングを妥協なく実現します。

    再接続とリプレイによる信頼性の高いストリーミング

    JavaScript/TypeScript、Rust、Goの3つのLaserStream SDKはすべて、高帯域幅ストリーミングの重要な課題である、ネットワーク障害時のデータ継続性を確保します。

    各SDKは、スロット追跡を伴う自動再接続を実装しています。接続が切断されると、クライアントは最後に処理したスロットを内部で追跡します。

    再接続時には、その正確な位置から再開し、最大48時間分の履歴リプレイをリクエストします。

    このアーキテクチャにより、アプリケーションレベルの再試行ロジックを必要とせず、一時的なサーバー側の切断によるデータ損失を防げます。

    スロットトラッカーは、処理済みのスロット番号をメモリに保存します。replay: true(デフォルト)の場合、SDKはデータストリームに欠落がないことを保証します。一部のデプロイ環境、特に専用ノードは、履歴リプレイに対応していません。これらのエンドポイントでは、replay: falseを設定して内部のスロット追跡を無効にし、再接続時に現在のスロットから再開します。

    gRPCストリームにおけるJavaScriptのパフォーマンスボトルネック

    Node.jsのgRPCストリームでは、データ量が多い場合に深刻となる実用上のボトルネックが発生します。これは理論上の問題ではなく、コールバックで各メッセージを処理する際に実際に起きる問題です。

    JavaScriptのイベントループはシングルスレッドであるため、データハンドラー内のすべての処理(JSONの解析、データの検証、ビジネスロジックの実行、イベントのログ記録など)が後続メッセージをブロックします。

    ハンドラーの処理速度を上回るペースでメッセージが到着すると、ストリームの処理が遅れ、バックプレッシャーが蓄積し、コールバックがキューに滞留します。その結果、アプリケーションが処理するデータはますます古くなります。

    純粋なJSのgRPCクライアントでは、次の追加オーバーヘッドによって問題がさらに悪化します: 

    • JavaScriptでのProtobufデシリアライズ
    • オブジェクト割り当てによるガベージコレクション負荷
    • ネットワークI/OのためにJavaScriptとネイティブの境界を繰り返し越える処理

    MEVインフラ、リアルタイム分析、オーダーブック追跡など、毎秒数千件のアカウント更新やトランザクション通知を処理するアプリでは、こうした遅延によって競争優位性が失われます。システムが反応する頃には、イベントの発生からすでに数秒が経過しています。

    ゼロコピーNAPIバインディングを備えたRustコアによるJavaScript SDKのパフォーマンス最適化

    LaserStream JavaScript SDKは、負荷の高い処理をJavaScriptから完全に切り離すことで、こうしたボトルネックを解消します。

    ストリーミングエンジン全体、gRPC接続管理、Protobufシリアライズ、スロット追跡はRustで実行されます。JavaScriptで実行されるのは、アプリケーションロジックだけです。

    このアーキテクチャは、根本的な問題を次のように解決します: 

    1. ネットワークI/OとProtobufデシリアライズは、JavaScriptのイベントループを一切使用しません。
    2. Rustレイヤーが、すべてのメッセージ処理を別スレッドで実行します。
    3. Rustレイヤーが、事前にシリアライズされたProtobufバイトをNAPI(Node-API)バインディング経由でJavaScriptのコールバックに渡します。

    LaserStream JavaScript SDKの仕組みを次の図に示します:

    NAPIバインディングは、ストリーミング更新のゼロコピーデータ転送を実現します。LaserStreamがProtobufメッセージを送信すると、Rustレイヤーがそれをデシリアライズし、必要に応じてスロットを追跡した後、生のバイトをUint8ArrayとしてJavaScriptに直接渡します。追加のシリアライズも中間コピーもありません。

    パフォーマンスの差は圧倒的です。標準のJavaScript Yellowstoneクライアントの30 MB/sに対し、1.3 GB/sで40倍高速です。 

    これは小幅な改善ではありません。ブロックストリーム全体をリアルタイムで処理できるか、数分遅れになるかを分ける差です。

    Rustコアが処理する項目:

    • gRPC接続のライフサイクルとフロー制御
    • 指数バックオフによる自動再接続
    • スロット追跡とリプレイロジック
    • Protobufのエンコードとデコード
    • 境界付きキューを介したスレッドセーフなコールバックのディスパッチ(コールバックの遅延時にメモリが肥大化するのを防止)

    JavaScriptはネットワークI/Oやシリアライズのボトルネックに関与せず、アプリケーションロジック、フィルタリング、ビジネスルール、データ永続化を処理します。

    圧縮のサポート

    LaserStreamは、gRPCトランスポート層で複数の圧縮アルゴリズムに対応しています。Zstd圧縮は、非圧縮ストリームと比べて帯域幅を70〜80%削減できます。データ転送量に比例して送信コストが増加する大規模なサブスクリプションでは、特に重要です。

    圧縮は簡単に設定できます:

    コード
    const config = {
      apiKey: 'your-key',
      endpoint: 'your-endpoint',
      channelOptions: {
        'grpc.default_compression_algorithm': CompressionAlgorithms.zstd,
        'grpc.max_receive_message_length': 1_000_000_000,
      }
    };

    Zstdは、同程度のCPUオーバーヘッドでgzipより高い圧縮率を実現するため、推奨される選択肢です。

    まとめ

    LaserStream SDKは、高性能なデータストリーミングにおける根本的な課題を解決します。Yellowstoneとの互換性を維持しながら、標準クライアントにはない信頼性向上機能、自動再接続、スロットベースのリプレイを追加します。 

    JSアプリでは、Rustベースのアーキテクチャにより、大規模環境で純粋なJS実装の利用を困難にするイベントループのボトルネックを解消します。

    40倍のスループット向上は、小幅な最適化ではありません。極端な高負荷でもブロックストリーム全体をリアルタイムで処理できるか、数分遅れになるかを決めるアーキテクチャ上の違いです。

    MEVインフラ、リアルタイム分析、自動取引システムなど、レイテンシと信頼性を妥協できない本番アプリケーションに、LaserStream SDKは必要な基盤を提供します。

    その他のリソース

    Heliusを購読

    Solana開発の最新情報や新しい記事の公開通知を受け取れます

    拡大画像