rpcpool.solana_rpc

Solana RPCロール

=========

Solana RPCノードをデプロイするためのAnsibleロールです。これは、ユーザーsolanaの下で動作するRPCモードでバリデーターソフトウェアを設定します。RPCサービスはこのユーザーの下で動作するユーザーサービスとしてインストールされます。

更新


  • 16/02 - Solana 1.8.15(メインネット)および1.9.6(テストネット)以降、このロールが完全に公開されたRPC APIノードを作成するために、solana_full_rpc_api: trueを指定する必要があります。

ハードウェア要件


RPCサーバーは、少なくともSolanaバリデーターと同じスペックが必要ですが、通常はより高い要件があります。特に、インデックスを保存するために256 GBのRAMを使用することを推奨します。ハードウェア要件の詳細については、こちらをご覧ください。特に、何をすべきか分からない限り、クラウドプロバイダーよりもベアメタルプロバイダー(Hetznerでない)を使用することを強くお勧めします。

デプロイする前に、アカウントデータベースとレッジャーの位置を適切に構成するためにホストを準備する必要があります。これは、アカウントのためのtmpfsフォルダと、レッジャーのための別のファイルシステム(理想的にはNVMEドライブ上)を設定することを含む場合があります。一般的な設定例は以下のようになります:

/solana/tmpfs - アカウント状態を保持するための100 GBのtmpfsパーティション
/solana/ledger - レッジャー用の2 TBのNVMEドライブ

なぜベアメタルでクラウドではないのか?

クラウドサーバー(AWS、GCPなど)は、以下の理由から一般的にSolanaには不適切です:

  1. イーグレスが非常に高価で、Solanaは多くのイーグレスを使用します
  2. 単一コアのパフォーマンスが一般的に低すぎて、ベアメタルのようにブーストできません
  3. 多くのクラウドプロバイダーは、コストの低いインスタンスではSolanaに関連するワークロードを受け入れたくないため、非常に高価なベアメタルインスタンスを使用することになります。

なぜヘッツナーではないのか?

ヘッツナーはソラナRPCサービスを自社ネットワーク上で実行したくないと決定しています。彼らはソラナのエントリーポイントへの接続を積極的にブロックし、ソラナのトラフィックを制限しています。ソラナノードはネットワークに追いつくのが難しく(メインネットでは決して追いつかない可能性があります)、ヘッツナーはアカウントを停止する可能性が非常に高いです。

ソフトウェア要件


  • Ansible >= 2.7(主にAnsible 2.8でテスト済み)
  • 対象デプロイマシン上でのUbuntu 18.04+

このロールは、Solanaバリデーターソフトウェアデプロイメントプロセスにある程度の慣れがあることを前提としています。

ロール変数


デプロイでは、ダウンロードするsolana-installerのバージョンに対するチェックサムがvars/main.ymlに記載されたものと一致することを確保します。そこにリストされていないSolanaのバージョンをインストールしたい場合は、まずsolana-installerスクリプトのsha256チェックサムをダウンロードして確認するのが良いです(https://raw.githubusercontent.com/solana-labs/solana/master/install/solana-install-init.sh)。

Solanaのための設定可能なパラメータは多数存在します。多くの値には適切なデフォルトがあり、デフォルト値を変更せずにこのロールを使用してSolana RPCノードをデプロイすることもできます。パラメータを指定せずにこのロールを実行すると、標準のmainnet RPCノードが構成されます。

基本変数

これらはバリデーターの設定を構成する基本変数です。これらはデフォルト値がありますが、設定に応じてカスタマイズすることをお勧めします。

名前 デフォルト値 説明
solana_version stable インストールするSolanaバージョン。
solana_full_rpc_api true フルRPC APIを有効にするかどうか。通常はこれを望みます。
solana_root /solana Solanaレッジャーとアカウントのメインディレクトリ
solana_ledger_location /solana/ledger Solanaレッジャーの保存場所(NVME上にあるべき)
solana_accounts_location /solana/ledger/accounts Solanaアカウント情報の保存場所。tmpfsを使用する場合は、tmpfsマウントポイントのサブディレクトリであるべきです(例:tmpfsが/solana/tmpfsにマウントされている場合は/solana/tmpfs/accounts)。
solana_snapshots_location Solanaスナップショットの保存場所。レッジャーとは別のNVMEに保管するのが便利です。
solana_keypairs [] バリデータノードにコピーするキーペアのリスト。リスト内の各エントリにはkeynameが必要です。これは/home/solana/<name>.jsonを作成し、keyの値を含みます。
solana_generate_keypair true キーペアを生成するかどうか。solana_keypairsを指定していない場合、この値をtrueにすると、新しいキーが生成され、/home/solana/identity.jsonに配置されます。
solana_public_key /home/solana/identity.json バリデータノードのアイデンティティの位置。
solana_network mainnet このノードが参加する予定のSolanaネットワーク
solana_environment see defaults/main.yml バリデータノードの環境変数を指定します。最も重要なのはRUST_LOGです。
solana_enabled_services [ solana-rpc ] ブート時に自動的に起動するサービスのリスト
solana_disabled_services [ ] 無効にするサービスのリスト

ポート

RPCサーバーのために次のポートを構成する必要があります。

名前 デフォルト値 説明
solana_gossip_port 8001 ゴシップトラフィック用のポート(TCPとUDPの両方でファイアウォールで公開される必要があります)
solana_rpc_port 8899 (+8900) 入力RPC(およびWebSocket)のためのポート。これらは通常、localhostのみに開かれています。これらのポートの前にhaproxyのようなプロキシを配置し、公開しないでください。
solana_rpc_bind_address 127.0.0.1 RPCをバインドするアドレス。通常はlocalhostであるべきです。これに公開トラフィックを受け入れるためにhaproxyのようなプロキシを配置してください。
solana_dynamic_port_range 8002-8020 入力Solanaトラフィックのためのポート。UDPに対してもファイアウォールで公開される必要があります。

デフォルト値では、少なくとも8001-8020をファイアウォールでオープンにする必要があります。

純粋なRPCノードの場合、TPUおよびTPUフォワードポートを閉じることが可能です。これらのポートは動的に割り当てられ、ノードのsolana gossipを確認することで見ることができます。これらをファイアウォールする場合は、このユーティリティを使用できます: https://github.com/rpcpool/tpu-traffic-classifier。このツールを使用すると、次のようにローカルノードのTPUとTPUフォワードのトラフィックをブロックすることができます:

./tpu-traffic-classifier -config-file config.yml -our-localhost -tpu-policy DROP -fwd-policy DROP -update=false

これをSystemDサービスに入れておくと、ノードの起動時に自動的に開始し、継続的に実行されます。

ネットワーク特有の変数

これらの変数のデフォルト値はvars/{{ solana_network }}-default.ymlに指定されています(例:vars/mainnet-default.yml)。自分の設定を提供する必要がある場合は、{{ solana_network }}.ymlというファイルを作成し、すべての変数を指定する必要があります。

名前 デフォルト値 説明
solana_network mainnet このノードが参加すべきSolanaネットワーク
solana_metrics_config see vars/mainnet-default.yml メトリクスエンドポイント
solana_genesis_hash see vars/mainnet-default.yml このネットワークのジェネシスハッシュ
solana_entrypoints see vars/mainnet-default.yml エントリーポイントホスト
solana_known_validators see vars/mainnet-default.yml スナップショットやジェネシスバイナリをスタートアップ時に取得するための既知のバリデーター
solana_expected_bank_hash see vars/mainnet-default.yml 期待されるバンクハッシュ
solana_expected_shred_version see vars/mainnet-default.yml 期待されるシュレッドバージョン
solana_index_exclude_keys see vars/mainnet-default.yml パフォーマンス向上のためにインデックスから除外するキー

RPC特有の変数

名前 デフォルト値 説明
solana_rpc_faucet_address RPCファウセットを指定
solana_rpc_history true RPCを介して過去の値を提供するかどうか
solana_account_index program-id spl-token-owner spl-token-mint 有効にするインデックス。これによりパフォーマンスが大きく向上しますが、起動時間が遅くなり、メモリ要件が増加する可能性があります。

パフォーマンス変数

これらはパフォーマンスを向上させるために調整可能な変数です

名前 デフォルト値 説明
solana_snapshot_compression スナップショットを圧縮するかどうか。パフォーマンスを向上させるためには、noneを指定します。
solana_snapshot_interval_slots スナップショットを取得する頻度。パフォーマンスを向上させるためには増加させます。推奨値は500です。
solana_pubsub_max_connections 1000 許可されるpubsub接続の最大数。
solana_bpf_jit BPF JITを有効にするかどうか。デブネットではデフォルトで有効。
solana_banking_threads 16 バンキングスレッドの数。
solana_rpc_threads RPCスレッドの数(システムのデフォルト最大スレッド/コア)
solana_limit_ledger_size solana default, 250 mio 保存するローカルレッジャーのサイズ。フルエポックの場合、350百万から500百万の間の値を設定します。最適なパフォーマンスを得るためには50(最小値)を設定します。
solana_accounts_db_caching アカウントDBキャッシングを有効にするかどうか
solana_accounts_shrink_path アカウント縮小プロセス用の別の場所を指定したいかもしれません。

Bigtable

ローカルレッジャーに存在しないブロックを照会するためのGoogle Bigtableアカウントの資格情報を指定できます。

名前 デフォルト値 説明
solana_bigtable_enabled false Bigtableアクセスを有効にする
solana_bigtable_upload_enabled false Bigtableへのアップロードを有効にする(下に提供する資格情報には書き込みアクセス権が必要です)
solana_bigtable_project_id BigtableプロジェクトID
solana_bigtable_private_key_id BigtableプライベートキーID
solana_bigtable_private_key Bigtableプライベートキー
solana_bigtable_client_email Bigtableクライアントメール
solana_bigtable_client_id BigtableクライアントID
solana_bigtable_client_x509_cert_url Bigtable証明書URL

BigTableの詳細については、こちらをご覧ください。

フォークの取り扱い

時折devnet/testnetがフォークを経験します。この場合、Discordの指示に従って以下のパラメータを使用します:

名前 デフォルト値 説明
solana_hard_fork ハードフォーク
solana_wait_for_supermajority ノードがスーパーメジャリティを待つべきかどうか

CPUガバナーとSysctl設定

RPCノードを正しく実行するために必要な特定の設定があります。このロールは、いくつかの標準的な設定変更を支援できます。ただし、完全な最適化はハードウェアに大きく依存するため、ハードウェアを正しく設定する方法に慣れる必要があります。

最適化の最も重要な要素はCPUパフォーマンスガバナーです。これはブースト動作とエネルギー使用量を制御します。多くのDCホストは、パフォーマンスとエネルギー使用量のバランスが取れるように設定されています。Solanaの場合、最速で実行する必要があります。サーバーのCPUガバナーを設定する方法は3つあります:

  1. BIOSにアクセスでき、BIOS CPU設定をmax performanceに設定します。これはHPEシステムでうまく機能するようです。この場合、変数cpu_governor: biosを指定します。AMD EPYCシステムでも必要になることがあります。
  2. BIOSにアクセスでき、BIOS CPU設定をos controlに設定します。これが一般的なデフォルト設定です。この場合、cpu_governor変数をデフォルトのままにするか、cpu_governor: performanceに明示的に設定します。
  3. BIOSまたはCPUガバナー設定にアクセスできない場合。可能であれば、cpu_governor: performanceを設定するようにします。さもなければ、プロバイダーが良好なパフォーマンスで設定していることを願います。

次に、Solana RPCユースケースに合わせてさまざまなカーネルパラメータを編集する必要があります。

一つのオプションは、この設定と共にsolana-sys-tunerをデプロイし、いくつかの変数を自動調整することです。

新しいパフォーマンス調整に不慣れな場合には、RedHatのtunedtune-admを使用し、throughput-performanceプロファイルが適しているかもしれません。

最後に、このロールを介してデプロイすると、ホスト上で自動的に設定するためのsysctl値のリストを指定することもできます。これにより、完全な制御が可能になり、これらは恒久的に設定されます。 以下は、rpcpoolで使用されたsysctl値のリストです:

sysctl_optimisations:
  vm.max_map_count: 700000
  kernel.nmi_watchdog: 0
# CPUバウンドタスクの最小プリエンプション粒度:
# (デフォルト: 1ミリ秒#  (1 + ilog(ncpus)), 単位: ナノ秒)
  kernel.sched_min_granularity_ns: '10000000'
# SCHED_OTHERのウェイクアップ粒度。
# (デフォルト: 1ミリ秒#  (1 + ilog(ncpus)), 単位: ナノ秒)
  kernel.sched_wakeup_granularity_ns:  '15000000' 
  vm.swappiness: '30'
  kernel.hung_task_timeout_secs: 600
# これは仮想メモリ統計が kurangするために得るが、低レイテンシへの合理的取引です
  vm.stat_interval: 10
  vm.dirty_ratio: 40
  vm.dirty_background_ratio: 10
  vm.dirty_expire_centisecs: 36000
  vm.dirty_writeback_centisecs: 3000
  vm.dirtytime_expire_seconds: 43200
  kernel.timer_migration: 0
# pid_maxの推奨値は1024 * <# of cpu cores/threads in system>です
  kernel.pid_max: 65536
  net.ipv4.tcp_fastopen: 3
# Solana sys-tunerからのもの
# 参照: https://medium.com/@CameronSparr/increase-os-udp-buffers-to-improve-performance-51d167bb1360
  net.core.rmem_max: 134217728
  net.core.rmem_default: 134217728
  net.core.wmem_max: 134217728
  net.core.wmem_default: 134217728

例示的なプレイブック


メインネットノード:

    - hosts: rpc_nodes
      become: true
      become_method: sudo
      roles:
         - { role: rpcpool.solana-rpc, solana_network: mainnet }

テストネットノード:

    - hosts: rpc_nodes
      become: true
      become_method: sudo
      roles:
         - { role: rpcpool.solana-rpc, solana_network: testnet }

デブネットノード:

    - hosts: rpc_nodes
      become: true
      become_method: sudo
      roles:
         - { role: rpcpool.solana-rpc, solana_network: devnet }

RPCノードの起動


デプロイ後、次のコマンドを使用してマシンにログインし、solanaユーザーになります:

su -l solana

デプロイ中に生成されたSolanaバリデーターコマンドラインを見るには、/home/solana/bin/solana-rpc.shを確認してください。このファイルの変更は、次回このAnsibleを実行すると上書きされることを覚えておいてください。

初回の起動では、/home/solana/bin/solana-rpc.shファイル内の--no-genesis-fetchおよび--no-snapshot-fetchをコメントアウトする必要があります。これにより、Solanaが最初の起動に必要な基本ファイルをダウンロードできるようになります。最初のバリデーターの起動が完了した後は、これらの行を再度有効にすることを忘れないでください。

次に、以下のコマンドを実行してSolana RPCプロセスを起動します:

systemctl --user start solana-rpc

プロセスの状態は、次のコマンドを実行して確認できます:

systemctl --user status solana-rpc

最初の起動にはしばらく時間がかかります。以下のコマンドを実行して起動を監視できます:

solana catchup --our-localhost

最後に、Solana RPCノードのログを表示するには以下を実行します:

journalctl --user -u solana-rpc -f

初めてSolanaノードを実行する場合は、こちらおよびこちらに、ノードの操作方法についての詳細が記載されています。

RPCノードのチェック


ノードが起動した後の基本的なチェックは、キャッチアップを追跡することです:

solana catchup --our-localhost

その後、RPCコールが正しく提供されているか確認できます。

RPCアクセスのテスト

バッファル(buffalu)の手助けを受けて、いくつかの簡単な検証コマンドを試すことができます:https://gist.github.com/buffalu/db6458d4f6a0b70ac303027b61a636af:

curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
  {"jsonrpc":"2.0","id":1, "method":"getSlot", "params": [
      {
        "commitment": "processed"
      }
    ]}
'

curl http://localhost:8899  -X POST -H "Content-Type: application/json" -d '
  {"jsonrpc":"2.0","id":1, "method":"getSlot"}
'

WebSocketアクセスのテスト

WebSocketをテストする最も簡単な方法は、ユーティリティwscatをインストールすることです。これを行うには、NodeJSとNPMをインストールし、次にnpm install wscatを実行します。

次に、次のようにしてWebSocketに接続できます:

wscat -c localhost:8900

ここから、手動でWebSocketのサブスクリプションリクエストを入力できるコマンドプロンプトが表示されます:

> {"jsonrpc":"2.0", "id":1, "method":"slotSubscribe"}

これにより、RPCノードによって確認されたスロットの最新情報を定期的に受信できるはずです。

RPCノードが遅れている/追いつけない場合


RPCノードが直面する最も一般的なパフォーマンス問題は、ネットワークに遅れをとり、追いつくことができないことです。

最初の起動で追いつけない場合、通常は設定ミスによるものです。最も一般的な問題は、CPUブーストの周波数です(CPU設定の詳細については上記参照):

  • CPUが十分に新しいことを確認してください(AMDのEPYC 2世代未満またはIntelのCascade Lake未満では苦戦します)
  • BIOSおよびカーネル設定で省エネモードに設定されていないことを確認してください
  • watch -n 1 grep MHz /proc/cpuinfoを実行してCPUの周波数を観察し、通常はすべてのコアで3GHz以上である必要があります(経験則)。1.4-1.8GHzに落ち着くコアは避けるべきです。

以前は追いつけたが今は追いつけない場合(またはCPUの修正が解決しない場合):

  • メモリ/CPU/ネットワークを確認してください - 良好なCPU周波数がありますか、スワップに入り込んでいますか(メモリ不足)?あるいはプロバイダーがUDPパケットを制限していますか?
    • _CPU_:パフォーマンスガバナー/ブースト設定を修正し、新しい世代のCPUまたはすべてのコアがターボをかけるCPUを取得します(詳細はwikichipを参照)。MHzは異なる世代で同じではありません。Broadwell 3.0GHzは、Cascade Lake 3.0GHzやEPYC 3rd gen 3.0GHzとは同じではありません。
    • _ネットワーク_:UDPパケット制限と接続性を確認します。少なくとも500Mbpsのパイプが必要で、UDPに制限がない必要があります。一部のプロバイダーは、DDoS保護のためにUDPをブロックまたは制限することがあります。これは、入力と出力の両方で発生します。入ってくるトラフィックが制限されると、ノードはネットワークからのシャードを適時に受信できません。ファイアウォールを確認して、制限されていないことを確認してください。
    • _メモリ_:RAMをもっと増やしてください。Solanaはスワップ上での実行を嫌うため、定期的にスワップに入る場合は修正する必要があります。一時的な解決策として、spl-token-owner / spl-token-mintインデックスを無効にすることができます。これらは非常に大きくなっています。
    • _ディスク_:レッジャーやアカウントを保持するためのNVMEが壊れていないか確認してください。簡単に言えば、dmesgやSMARTステータスクエリで確認できます。
  • getBlocksの重いRPC呼び出しの後にノードが常に遅れているというバグがあります。ノードを再起動してみて、それがうまくいくかもしれません。これがあなたの問題かもしれません。
  • 一度切り離して再接続しましたか?時には、レッジャーをクリーンにし、再起動することで解決できる場合があります。
  • トラフィックパターンを確認してください。特定のRPCトラフィックパターンは、ノードを容易に遅れさせる可能性があります。別のノードを追加してRPCトラフィックを分割する必要があるか、問題のあるクエリ(getProgramAccountsなど)への呼び出しを制限する必要があるかもしれません。

歴史データへのアクセス


デフォルトでは、RPCノードを起動すると、ソラナネットワークから受け取ったブロックからローカルレッジャーを構築し始めます。このローカルレッジャーは、ノード起動時にダウンロードしたアカウントスナップショットの時点から始まります。solana-validatorコマンドラインに--no-snapshot-fetchを追加しないと、バリデーターは起動時にネットワークからスナップショットを取得することが多いです。これにより、RPCノードを停止した時点とアカウントスナップショットをダウンロードした時点の間にギャップが発生します。これを避けるためには、ノードを最初に起動した後は常に--no-snapshot-fetchを指定してください。スナップショットを取得するたびにローカルレッジャーにギャップができます。

ローカルレッジャーのサイズは、--limit-ledger-sizeパラメータによって決まります。これはシャード単位で測定されます。シャードは固定のデータユニットです。シャードとブロックの間の変換は固定ではなく、ブロックサイズは様々です。そのため、ノードがどれだけの歴史(時間またはブロック数での測定)を保存するかを正確に言うことは非常に難しいです。ニーズに応じて調整する必要があります。良い出発点は、250-350百万シャードで、これはおおよそエポックをカバーし、約3日になると見込まれます。

RPCノードがどれだけのデータを保存するかは、--enable-cpi-and-log-storageおよび--enable-rpc-transaction-historyパラメータにも依存します。これらは、ノードがフルブロックおよびトランザクションデータを保持し提供するために必要です。

ノードはローカルレッジャーに保存されているデータしか提供できません。これは、歴史がノードを開始した時点から始まることを意味します(実際には:ノードを起動したスナップショットスロット)。ネットワークが現在スロットNにあり、スナップショットをスロットMで取得した場合、ノードはスロットMとスロットNの間で歴史を再構築し始めます。これがcatchup中に発生していることで、ノードはネットワークの最新データを処理し、受信したすべてのデータを処理できるようにします。

ノードは(理論上)高速ストレージに収容できる限りの歴史を保存できます(たとえば、--limit-ledger-sizeを指定しないか、大きな値を与えた場合)。ただし、これによりジェネシスまでスケールバックすることはできません。すべての歴史を取得するには、組み込まれたGoogle BigTableサポートを使用できます。ノードを設定してGoogle BigTableのインスタンスにデータをアップロードすることができ、これにより歴史の照会に対して永続的に利用可能になります。ノードをBigTableインスタンスへのクエリに対応させることもできます。この場合、ノードがローカルレッジャーに保存していないクエリに対して、Google BigTableにリクエストを行い、データが見つかった場合はそこからデータを取得します。

一部のRPCプロバイダーやSolana財団は、ジェネシスまで遡るBigTableのコピーを持っています。これに関する詳細については、こちらをご覧ください。

インデックスとパフォーマンス:あるいは、なぜRPCが遅いのか?


Solanaバリデーターが生成するインデックスは、program-idspl-token-mintspl-token-ownerの3つです。後者の2つは、getTokensByOwnergetTokenLargestAccounts、またはgetTokensByDelegateを介してクエリをサポートするために使用されます。また、特定のフィルターを用いるgetProgramAccountsのクエリをサポートするためにも使用されます。

これらのインデックスは巨大に成長しています。RPCノードに対してこれらのクエリが迅速に行われる必要がない場合は、これらを削除することでノードのメモリ使用量を大幅に削減し、起動時間を改善できます。

RPC呼び出しが必要な場合は、アカウントインデックスフラグを介してインデックスを有効にする必要があります。そうでなければ、これらの呼び出しは耐えられないほど遅くなります。これには大量のRAMが必要です - 一般的には、512GB以上の RAM を用意することが推奨されます。

これらの代替手段として、PostgresプラグインのようなGeyserプラグインを使用して、メモリインデックスに依存せずにクエリを高速化することもできます:https://github.com/rpcpool/solana-geyser-park

セキュリティ上の懸念


セキュリティは広範な分野であり、GitHubリポジトリ内の小さなガイドに依存することはできません。通常、少なくともあなたのRPCサーバーが8899と8900のポートを直接公開せず、何らかのプロキシとアクセス制御を前に置いていることを確認してください。これを行う簡単な方法は、nginxやHAproxyをリバースプロキシとして使用することです。これにより、各自の組み込みツールを通じてSSLサポートと認証を追加できます。

安全のために、rpc-bind-addressを127.0.0.1(このロールのデフォルト)に設定して、ローカルのリクエストにのみ応答するようにすることを確認できます。

その他のプレイブック


通常はSolana RPCの前にリバースプロキシをデプロイしたいと考えるでしょう。HAproxyは素晴らしいオプションであり、Solana RPCサーバー用のHAproxyの設定に関するプレイブックがこちらにあります。

その他のガイドとドキュメント


これらはSolana RPCに関して書かれたその他のガイド、リソース、およびドキュメントです:

これらのドキュメントの正確性や品質については一切の主張を行いません。どのドキュメントに従うかはご自身で確認してください!

ライセンス


MIT

作者情報


このロールはもともとTriton Oneによって開発されました。パッチ、提案、および改善は常に歓迎されます。

プロジェクトについて

Ansible role for deploying Solana RPC nodes

インストール
ansible-galaxy install rpcpool.solana_rpc
ライセンス
mit
ダウンロード
137
所有者
Providers of Solana RPC services