Чому індексатор TON не встигає за зростанням навантаження
Індексатор TON починає відставати не на піку, а раніше — коли потік подій із мережі стабільно швидший, ніж підтверджений запис у сховищі.
Спершу розрив вимірюється одиницями блоків і не видно у відповідях API, потім зростає лавиноподібно: черга стає довшою за вікно, яке воркери встигають пройти за один прохід. Типових причин чотири, і всі вони про будову циклу обробки, а не про потужність заліза.
Повторна обробка блоків: після реорганізації гілки воркер часто переграє весь діапазон, а не лише зачеплені транзакції. Кожен пропущений блок у черзі оплачується подвійною роботою, а проміжні стани у сховищі потім доводиться звіряти окремо.
Конкуренція за вузли додає своє: при обмеженій кількості точок доступу частина запитів відпадає через ліміти, різні воркери читають стан на різних моментах, і в API спливає розбіжність балансів.
Окрема історія — схема ключів. Ключ виду «адреса плюс дата» розмазує записи по гарячих розділах, пакетний запис не збирається, записувач упирається в дискові операції — і відставання зростає вже на виході.
Ключ за діапазоном шарда з накопиченням пачки дає рівний потік і передбачувану затримку між подією в мережі та її появою у сховищі.
Пропущені блоки небезпечні не самі по собі, а тим, що їхнє надолуження конкурує з поточним потоком за ті самі вузли й диск. Тому відставання вважають окремою метрикою за кожним шардом, а не середньою по сервісу, і рішення ухвалюють за нею.
Розбираємо, як це закривається: де ставити межі вікна повторної обробки, як розвести читання й запис між вузлами і який формат ключа тримає запис рівним.
Що дає керована індексація: вимірюваний ефект
Керований індексатор TON тримає відставання від голови мережі в межах одного-двох підтверджених блоків — замість хвилин очікування після кожної транзакції. Реорганізації обробляються перегрою зачепленого діапазону висот, а не повною переіндексацією всієї історії.
Повнота історії тримається на журналі оброблених мастерчейн-блоків: для будь-якої висоти відновлюється стан акаунта, його події та перекази. Коректність перевіряється звіркою контрольних сум стану за випадковими висотами — розбіжності видно до того, як їх помітить користувач.
Стійкість до повторної обробки дає ідемпотентний запис: ключ із висоти блоку й хешу транзакції не дозволяє дублювати дані. Воркер, що впав на середині діапазону, продовжує з останньої контрольної точки і не втрачає жодної події.
Навантаження на вузли знижується підпискою на нові блоки замість постійного опитування, пакетними запитами й кешем гарячих акаунтів — звернень до вузла стає менше на порядок.
Звільнений запас іде на глибокі запити до історії: видача за адресою або за токеном відповідає за частки секунди навіть на довгому діапазоні висот.
Режими індексації: порівняння підходів та обмежень
Вибір режиму визначає не лише швидкість появи даних в API, а й те, як індексатор TON переживає реорганізації та пропуски.
На вході два параметри: допустима затримка між фіналізацією блоку та його видимістю у відповіді, і глибина зберігання — скільки історії потрібно піднімати за запитом.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Потокова індексація | Вітрини, гаманці, баланси й статуси транзакцій: відповідь потрібна майже одразу після фіналізації | Потрібен буфер під реорг та ідемпотентний запис за ключем блоку; збій парсера зупиняє весь потік, а історію заднім числом не перерахувати |
| Пакетні перерахунки | Аналітика, звірка балансів, міграція схеми зберігання, відновлення після збою | Дані з'являються із затримкою від десятків хвилин; повторний прохід архівом вузла дорогий за навантаженням на диск і на сховище |
| Гібридна схема | Публічний API індексатора TON, де важливі і свіжі дані, і глибока вибірка | Складніша в експлуатації: два контури, окремі чекпойнти й узгодження межі між гарячим і холодним шарами |
Глибина зберігання — окрема вісь, і її не варто плутати з режимом. Свіжі блоки тримаємо у швидкому сховищі, історію — у стисненому, із заздалегідь описаною політикою видалення: скільки останніх блоків гарантуємо для відкату, що йде в архів, що перераховується з нього на вимогу.
Гібрид зазвичай і стає робочим варіантом: потік дає низьку затримку, пакетний прохід закриває діри й наповнює історичні зрізи.
На практиці режим підбирається під профіль запитів, а не навпаки: спершу дивимося, які вибірки переважають, потім фіксуємо затримку й глибину.
Етапи впровадження індексатора TON
Порядок робіт один і для нового індексатора TON, і для заміни самописного скрипта, який перестав встигати за потоком блоків. Спершу фіксуємо, які запити до даних потрібні продукту, і лише потім вибираємо схему зберігання: якщо почати з коду, переписувати доводиться на середині. Нижче — послідовність із точками приймання на кожному етапі.
- Аудит схеми даних. Розбираємо таблиці, зв'язки й важкі запити, відзначаємо нестачу складених індексів і дублі. На виході — карта джерел і план перенесення.
- Проєктування моделі зберігання. Вирішуємо, що тримаємо нормалізовано, а що — у денормалізованих проєкціях під часті вибірки: історію адреси, баланси, події контрактів.
- Налаштування черг. Потік блоків ділимо на приймання, розбір і запис; черга гасить піки, а після збою обробка йде з останньої підтвердженої позиції.
- Перевірка консистентності. Звіряємо індекс із даними мережі за балансами, кількістю транзакцій і повторною обробкою; розбіжності зводимо до нуля на тестовому діапазоні.
- Навантажувальний прогін і перемикання. Дивимося відставання індексатора на історичних даних і в реальному часі, переводимо трафік поетапно, з поверненням до попереднього контуру.
- Передача регламентів. Віддаємо опис схеми й запитів, інструкції з перезапуску та відновлення, метрики з порогами. Далі експлуатація йде силами вашої команди.
Комплект постачання: схеми, регламенти, інструменти
Після запуску в команди замовника залишається не лише працюючий сервіс, а й комплект документів, за якими його можна експлуатувати й розвивати без нас.
Передаємо опис схеми даних, регламенти та інструменти спостереження — так, щоб черговий інженер розумів причину збою, а новий розробник додав метод API без розбору чужого коду.
- Схема даних — які таблиці зберігають блоки, транзакції та події, за яким ключем іде розбиття на партиції і які індекси закривають часті запити за адресою та часовим періодом.
- Специфікація API індексатора TON — перелік методів, формати відповідей, курсорна пагінація, ліміти й коди помилок: за нею інтеграцію пишуть без уточнювальних питань.
- Доступи й ролі — сервісний доступ лише на читання, окремі ключі для аналітики, адміністративні операції, порядок ротації та ізоляція стенда від промислового контуру.
- Регламент перезапуску — у якій послідовності піднімаються компоненти, як сервіс добирає пропущені блоки і від якої точки відновлює обробку, щоб події не задвоїлися.
- Моніторинг черг — метрики глибини черг, відставання індексу від ланцюжка та частки відкинутих повідомлень, пороги алертів і перші кроки чергового при спрацюванні.
- Знімки та відновлення — як знімається стан сховища, де воно зберігається і скільки займає повернення до робочого режиму.
- Розбір типових збоїв — розсинхрон, дублі подій, відсталий вузол: за якими ознаками розпізнаються і що робити покроково.
- Передача знань — запис розбору архітектури та відповіді на запитання команди, щоб експлуатація не залежала від однієї людини.
Кейс: як зросла повнота даних після перезапуску
Що було до перезапуску
Індексатор збирали під швидкий запуск: блоки читалися в один потік, усе писалося в одну таблицю без розбиття за шардами.
На піку відставання від мережі сягало кількох годин, а при розсинхронізації процес мовчки пропускав діапазон блоків — діри знаходили за скаргами сервісів, які будувалися на цих даних.
Повнота історії трималася близько 88%: частина внутрішніх переказів і подій контрактів в індекс не потрапляла. У TON це критично — пропущений діапазон рве ланцюжок станів у залежних адрес, і реальний баланс уже не відрізнити від накопиченої помилки.
Що змінили і що стало
Завантаження переписали на паралельну обробку шардів із контрольними точками, переіндексацію зробили керованою: глибина задається параметром — від останніх годин до всієї історії мережі. Відновлення після збою тепер автоматичне, з останньої підтвердженої точки, без ручного розбору.
- Відставання від мережі на піку — хвилини замість годин.
- Повнота історії — 100% за перевіреними діапазонами, контрольні суми збігаються за кожним шардом.
- Відновлення після збою — близько 20 хвилин автоматичного догравання замість годин ручної роботи.
- Глибина переіндексації — вся історія, а не вікно в останню добу.
Звіряли не на око: прогнали індекс проти повного вузла на кількох діапазонах, розбіжностей немає. Після перезапуску команди перестали тримати власні вивантаження — дані з індексу збігаються з мережею й віддаються одразу.
Що робити, якщо індексатор уже розгорнуто і він відстає
Індексатор TON в експлуатації відстає з двох причин: змінилася схема обліку — додалися внутрішні перекази, змінився склад полів — або зросли обсяги, і цикл обробки блоку перестав вкладатися в інтервал.
Зупиняти сервіс не можна: баланси й історія операцій потрібні постійно, а прогін з нуля займає години.
Робочий прийом — поступова міграція через подвійний запис. Обробник пише і в стару, і в нову схему в одній транзакції, тому стани не розходяться.
Читальний шар перемикається не повністю, а за групами запитів: відкат зводиться до зняття прапорця, а не до відновлення з резервної копії.
Історію переносимо у фоні. Фіксуємо висоту блоку, з якої почався подвійний запис, — це точка розбіжності. Усе, що було раніше, заливаємо пакетами в нову схему паралельними обробниками з обмеженням навантаження на вузол, щоб живий потік не відставав сильніше. Наздоганяємо до нуля розбіжності.
Зміна схеми безпечніша, ніж здається: нова таблиця живе поруч зі старою, конфліктів за блокуваннями немає. Обов'язкова звірка — контрольна вибірка адрес і операцій проганяється через обидві схеми, відповіді порівнюються автоматично, і лише після збігу читання переходить на нову.
Якщо відставання вже накопичилося, його знімають перезбиранням гарячого шару з архіву блоків, не торкаючись накопичених даних. Починати з нуля не варто: втрачаються історія балансів і угод, а відновлення займає добу. Старий шар залишаємо читаним, доки новий не доведе збіг на звірці.
Технічні сумніви перед стартом робіт
Індексатор — це стан, який зобов'язаний збігатися з ланцюжком за будь-якого збою: пропущений блок, розрив з'єднання, реорганізація останніх блоків.
Нижче — відповіді на інженерні питання, які найчастіше піднімають на етапі оцінки: цілісність, повторна обробка, доступи та межі відповідальності після передачі.
Як підтверджується цілісність даних за кожним блоком?
Кожен оброблений блок фіксується з його хешем, номером, батьківським хешем і часовою міткою запису. Звірка йде від останньої підтвердженої позначки: якщо батьківський хеш не збігається з уже збереженим, партія блоків відкочується до спільної точки й обробляється заново.
Підсумкова перевірка — контрольна сума стану за вікно блоків, вона звіряється незалежно від основного циклу розбору.
Що буде, якщо індексатор зупинився на кілька годин?
Розбір іде за курсором, а не за часом, тому після запуску обробка продовжується з останньої підтвердженої позначки. Операція запису ідемпотентна: повторна обробка того самого блоку не створює дублів у сховищі. Відставання вибирається пакетами до виходу на актуальну висоту, далі вмикається звичайний режим.
Як влаштовані права доступу до розгорнутого контуру?
Доступи видаються ролями: читання через інтерфейс даних, службові операції з розбору та міграцій — окремо. Ключі та облікові дані передаються вашій відповідальній особі, у нас не залишається постійного доступу.
Відкликання доступу з нашого боку фіксується письмово й підтверджується спробою підключення з обох сторін.
Як розподіляється відповідальність після передачі?
Передаємо конфігурації розбору, схему сховища, політику повторної обробки, інструкції з відновлення та порядок дій у разі розбіжності станів. Ваші інженери відновлюють контур за цими матеріалами без нашої допомоги.
Гарантійний супровід покриває помилки логіки розбору — вони відтворюються й усуваються; зміни вашої інфраструктури та правила доступу до вузлів залишаються на вашому боці.
Обговоримо вашу задачу й повернемося з планом
Щоб оцінка проєкту спиралася на факти, а не на припущення, на старті нам важливо зрозуміти межі: чи потрібна історія з перших блоків, чи достатньо вікна за останні періоди, які сутності обов'язково мають бути у відповіді, яку затримку між появою блоку в мережі та його видимістю в API ви вважаєте допустимою.
Ще два параметри — звідки йде потік даних (власні вузли чи зовнішні джерела) і який запас за навантаженням закладати, щоб індексатор не відставав від голови ланцюга при пікових сплесках.
За підсумками розмови ви отримаєте:
- схему парсингу: обхід шардів, порядок обробки мастерчейну та робочих ланцюжків, поведінку при реорганізаціях і повторній видачі блоків;
- модель зберігання з описом індексів під конкретні запити — щоб вибірки за адресою, транзакцією та історією тримали потрібну швидкість на ваших обсягах;
- контракт API з прикладами відповідей і полями, включно з пагінацією, фільтрами та ознаками фінальності;
- план робіт за етапами з точками приймання на кожному: сирий потік, наповнення сховища, власний API, навантажувальні перевірки;
- склад команди з ролями — хто відповідає за парсинг, хто за шар запитів, хто за супровід;
- план передачі в експлуатацію: дашборди відставання від голови ланцюга, регламент переіндексації після збоїв, порядок оновлення при зміні формату блоків;
- перелік ризиків і припущень, що впливають на строки та обсяг.
Опишіть задачу у вільній формі — обсяги, джерела, вимоги до відповідей. Ми повернемося з оцінкою, планом робіт і ролями в команді.







