Власний RPC-вузол дає повний контроль над даними, латентністю та індексацією — без обмежень хмарних провайдерів на кількість запитів чи доступ до специфічних методів. Нижче — покрокова інструкція для підняття full node з Geyser plugin у dev-середовищі з обмеженими ресурсами.

Запуск full node з необхідними конфігураціями

Передумови та середовище

  • ОС: Ubuntu 24.04 LTS LTS (перевірена стабільність із Solana CLI)
  • Процесор: мінімум 16 ядер (ARM або x86_64)
  • Оперативна пам'ять: 128 ГБ (для mainnet-beta)
  • Накопичувач: NVMe SSD від 2 ТБ, переважно окремий диск під лід-логи та snapshot-и
  • Мережа: стабільне з'єднання з пропускною здатністю від 1 Гбіт/с
  • Програмне забезпечення: solana-cli, jq, systemd

Для devnet або testnet вимоги до пам'яті та диска нижчі, але архітектура налаштування ідентична — це дозволяє перевірити конфігурацію перед переходом на mainnet-beta.

Встановлення та ініціалізація

Встановіть solana-cli з офіційного реліз-репозиторію (перевірте актуальну стабільну версію в репозиторії solana-labs/solana на GitHub перед встановленням):

  1. Завантажте бінарні файли та розпакуйте їх у /opt/solana.
  2. Додайте шлях до PATH у профілі оболонки.
  3. Перевірте: solana --version має повернути встановлену версію без помилок.

Створіть окремого користувача для запуску вузла — не запускайте від root:

  1. sudo useradd -m -s /bin/bash solana
  2. Налаштуйте права доступу до директорій з даними.

Конфігурація вузла

Створіть директорію для конфігурації та даних:

  1. sudo mkdir -p /mnt/solana-data — на окремому NVMe-диску.
  2. sudo chown solana:solana /mnt/solana-data

Сформуйте файл конфігурації config.yml. Ключові параметри для dev-середовища:

  • ledger_path — /mnt/solana-data/ledger
  • rpc_port — 8899 (за замовчуванням, змініть якщо зайнято)
  • rpc_bind_address — 127.0.0.1 (для dev-середовища обмежте локальним доступом)
  • rpc_fullnode — true
  • rpc_send_transaction_retry_ms — 1000
  • account_indexes — додайте індекси за тими програмами, з якими працюєте (наприклад, індекс за owner для вашого Anchor-програмного простору). Кожен додатковий індекс збільшує споживання пам'яті приблизно на 5–15 ГБ залежно від кількості акаунтів.
  • snapshot_interval_slots — для dev-середовища можна збільшити (наприклад, 500), щоб зменшити дискове навантаження.
  • limit_ledger_size — встановіть розумну межу, щоб диск не переповнився під час тривалого запуску.

Очікуваний результат: вузол завантажує snapshot, синхронізується з мережею та відповідає на curl http://127.0.0.1:8899 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' зі статусом "ok".

Запуск через systemd

Створіть юніт /etc/systemd/system/solana-rpc.service. Це забезпечить автоматичний перезапуск та логування:

  • ExecStart — повний шлях до agave-validator з прапорцем --config /home/solana/config.yml
  • User=solana, Group=solana
  • LimitNOFILE=1000000 — обов'язково, інакше вузол впаде з помилкою Too many open files
  • Restart=on-failure, RestartSec=5

Після створення: sudo systemctl daemon-reload && sudo systemctl enable --now solana-rpc.

Перевірка: sudo journalctl -u solana-rpc -f — в логах має з'явитися "Starting validator" та прогрес завантаження snapshot-ів.

План відкату

  1. Зупиніть сервіс: sudo systemctl stop solana-rpc.
  2. Видаліть директорію /mnt/solana-data/ledger та /mnt/solana-data/snapshots.
  3. Відновіть попередню конфігурацію з резервної копії config.yml.
  4. Перезапустіть сервіс.

Налаштування geyser plugin локально

Geyser plugin — це інтерфейс потокової передачі даних від вузла Solana до зовнішніх споживачів (бази даних, індексатори, аналітичні пайплайни). Для dev-середовища найчастіше використовують geyser-plugin-postgres або власний plugin, зібраний із шаблону.

Збірка з вихідного коду

  1. Клонуйте репозиторій обраного plugin-у (перевірте актуальність гілки — вона має відповідати версії вашого agave-validator, інакше будуть помилки сумісності ABI).
  2. Встановіть залежності збірки: Rust toolchain, PostgreSQL development headers (якщо використовуєте postgres-plugin).
  3. Зберіть: cargo build --release.
  4. Результат — бінарний файл у target/release/. Скопіюйте його у /opt/solana/geyser-plugins/.

Конфігурація Geyser

Створіть файл geyser-config.json. Структура залежить від конкретного plugin-у, але загальні обов'язкові поля:

  • libpath — абсолютний шлях до скомпільованої бібліотеки (.so для Linux)
  • accounts_selector — фільтр за програмами або owner-ами. Для dev-середовища обмежте лише ті акаунти, які потрібні, щоб не перевантажувати базу даних
  • transactions_selector — аналогічно, фільтруйте за підписами або акаунтами, залученими в транзакцію
  • connection_string — рядок підключення до бази даних (для postgres-plugin)

Приклад фільтрації за owner: вкажіть масив публічних ключів програм, з якими працюєте. Це різко зменшить обсяг даних, що пишуться в базу.

Підключення до вузла

Додайте до команди запуску agave-validator прапорці:

  • --geyser-plugin-config /home/solana/geyser-config.json

Або додайте відповідний рядок у ExecStart systemd-юніта та перезапустіть сервіс.

Перевірка та типові помилки

У логах journalctl шукайте рядки з префіксом geyser. Очікуваний результат — повідомлення про успішне підключення до plugin-у та початок потокової передачі слотів.

Типова помилка: "Failed to load plugin: cannot open shared object file". Фактична причина — відсутні системні бібліотеки (перевірте через ldd на шляху до .so-файлу) або невідповідність архітектури бінарного файлу.

Інша поширена проблема — розрив з'єднання з базою даних після кількох хвилин роботи. Причина: таймаут з'єднання у PostgreSQL за замовчуванням. Збільште idle_session_timeout та statement_timeout у конфігурації PostgreSQL, або налаштуйте keepalive у connection string.

Обмеження ресурсів для dev-середовища

Full node Solana споживає значні ресурси навіть у режимі лише читання. Без обмежень dev-вузол може витіснити інші процеси на машині розробника або сервері.

Обмеження через systemd

Додайте до юніта solana-rpc.service:

  • MemoryMax — встановіть жорстку межу, наприклад 100G. При досягненні межі процес буде завершений systemd — це краще, ніж OOM killer на рівні ядра, оскільки systemd забезпечить контрольований перезапуск.
  • CPUQuota — наприклад 800% для 16-ядерної машини (обмеження до 8 ядер). Це не зупинить синхронізацію, але уповільнить її, що для dev-середовища зазвичай прийнятно.
  • IOWeight — зменшіть пріоритет дискового вводу-виводу, якщо на тому ж диску працюють інші сервіси (наприклад, IOWeight=50 замість стандартних 100).

Обмеження кількості акаунтних індексів

Кожен індекс у account_indexes утримує додаткову структуру в пам'яті. Для dev-середовища залиште лише ті індекси, які критичні для вашого стеку. Якщо вам потрібні лише транзакції за певними програмами, розгляньте використання Geyser замість акаунтних індексів — це зменшить споживання RAM вузлом.

Обмеження розміру лідера

Параметр limit_ledger_size у config.yml дозволяє вказати максимальний розмір лідера в байтах. Для dev-середовища встановіть значення, що відповідає вашому диску з запасом. Коли межа досягається, вузол автоматично обрізає старі слоти. Це не впливає на валідність даних для розробки, але запобігає переповненню диска.

Моніторинг споживання

Використовуйте systemctl status solana-rpc для швидкої перевірки пам'яті та journalctl -u solana-rpc -g "memory|slot|snapshot" для фільтрованого перегляду. Для детальнішого моніторингу налаштуйте node_exporter та Grafana — це дозволить побачити динаміку споживання і вчасно скоригувати обмеження.

Коли власний вузол краще за хмарний провайдер

Вибір між власним вузлом і хмарним RPC-провайдером визначається не бюджетом, а конкретними технічними вимогами. Власний вузол має однозначну перевагу в таких випадках:

  • Потрібен повний доступ до всіх RPC-методів, включно з getProgramAccounts з фільтрами за великими наборами даних. Хмарні провайдери часто обмежують або кешують відповіді на ці методи, що спотворює результати для індексації.
  • Необхідна потокова передача даних у реальному часі через Geyser plugin. Жоден хмарний провайдер не дає прямого доступу до Geyser — ви завжди отримуєте дані через їхній API з додатковою латентністю та потенційними втратами.
  • Тестування edge cases: повторювані транзакції, специфічні послідовності слотів, відновлення після розриву синхронізації. На хмарному провайдері ви не контролюєте стан вузла і не можете відтворити умови відмови.
  • Індексація з кастомною логікою: якщо ваш пайплайн потребує обробки кожного слоту з нульовою втратою даних, власний Geyser — єдиний надійний варіант.
  • Вимоги до латентності: локальний вузол на тій самій машині, що й ваш бекенд, дає латентність RPC-викликів на рівні мілісекунд замість десятків мілісекунд через мережу до хмарного провайдера.
  • Конфіденційність даних: запити до вашого вузла не проходять через треті сторони, що критично для інфраструктурних команд, які працюють з незапущеними продуктами.

Власний вузол не є обов'язковим, якщо ви працюєте з типовими CRUD-операціями через Anchor, не потребуєте індексації в реальному часі та готові адаптувати логіку під обмеження провайдера. У такому випадку хмарний RPC зменшує операційне навантаження.

Для production-розгортання власного RPC-вузла рекомендується спочатку перевірити всю конфігурацію в dev-середовищі, описаному вище, а потім масштабувати ресурси та додати резервування. Експлуатація валідатора з функцією консенсусу має свої специфічні вимоги і виходить за межі цього матеріалу.

Джерела