Порівняння індексаторів: Zaino проти Ztreamer
Zaino і Ztreamer — це два індексатори, що підтримують протокол lightwallet gRPC — API, який Zcash light-гаманці використовують для синхронізації. На цій сторінці підсумовано незалежне, відтворюване порівняння цих двох: чи повертають вони однакові відповіді, скільки часу витрачають на побудову свого індексу та наскільки швидко обслуговують гаманці.
Коротко
- Обидва індексатори повертають коректні дані ланцюга. Кожна відповідь, яку можна було перевірити за Zebra, збіглася, тож гаманці можуть використовувати будь-який із них.
- Виявлені відмінності стосуються домовленостей і крайових випадків: коди помилок, порядок байтів одного хешу, спосіб підрахунку дубльованої адреси та кілька форм відповідей JSON-RPC.
- Ztreamer будує свій індекс приблизно у 6 разів швидше на тому самому CPU. Zaino починає відповідати через 6 секунд, пересилаючи запити до Zebra під час побудови.
- Ztreamer обслуговує швидше в кожному виміряному сценарії: для повного завантаження гаманця — у 13–17 разів більше блоків за секунду.
- Значна частина затримки Zaino спричинена одним відсутнім налаштуванням сокета (
TCP_NODELAY), яке додає приблизно 40 мс до багатьох запитів. Це виправляється одним рядком.
Що порівнювалося
| Збірка | Базовий вузол | Чому |
|---|
| Zaino 0.10.1 | Zebra 6.4.2 (бекенд direct) | Останній стабільний випуск Zaino |
| Zaino 0.9.0 | Zebra 6.4.2 (бекенд direct) | Версія, виміряна у власному опублікованому порівнянні Ztreamer |
| Ztreamer v0.1.0 | Вбудований вузол Zakura | Останній тег Ztreamer |
| Ztreamer master | Вбудований Zakura 1.5.1 | Те, що збирають інструкції з установлення Ztreamer |
Ці два індексатори використовують різні архітектури:
- Zaino працює як окремий процес поруч із повним вузлом Zebra, читає стан Zebra і підтримує власний індекс. Це індексатор у стеку Z3. Див. Zaino.
- Ztreamer вбудовує вузол Zakura (форк Zebra) у той самий процес і підтримує індекс компактних блоків.
Як це вимірювалося
- Ті самі дані для всіх. Кожна збірка починалася з того самого знімка тестнету Zcash Foundation, зафіксованого на висоті 4,382,897, тож усі вони індексували точно той самий ланцюг.
- Будь-хто може це повторити. Усе працює на безкоштовних runner-ах, розміщених у GitHub: зробіть форк репозиторію та запустіть один workflow.
- Три запуски для кожної збірки, кожен із порожнього індексу. Сервер і генератор навантаження працювали на окремих ядрах CPU.
- Сумісність: усі 20 методів gRPC протоколу lightwallet (274 тестові випадки) порівнювалися побайтно між збірками та перевірялися за JSON-RPC Zebra. Також було перевірено 28 методів JSON-RPC, які обслуговує Zaino.
- Продуктивність: час і ресурси для побудови індексу, затримка кожного запиту, пропускна здатність діапазону блоків, від 1 до 128 одночасних клієнтів і повне завантаження гаманця від активації Sapling до вершини ланцюга.
Результати
Побудова індексу
Медіани трьох запусків:
| Збірка | Індекс завершено | Перша відповідь | Розмір індексу на диску |
|---|
| Zaino 0.10.1 | 1,395 с | 6 с | 22.06 GiB |
| Zaino 0.9.0 | 1,211 с | 6 с | 22.06 GiB |
| Ztreamer v0.1.0 | 216 с | 210 с | 1.44 GiB |
| Ztreamer master | 159 с | 158 с | 1.44 GiB |
Zaino стає придатним до використання майже відразу, оскільки пересилає запити до Zebra під час побудови. Ztreamer не обслуговує нічого, доки його індекс не буде завершено. На тій самій моделі CPU Zaino 0.10.1 працював у 6–6.5 раза довше, ніж Ztreamer v0.1.0, і використав у 7.5–8 разів більше процесорного часу (включно з Zebra).
Обслуговування
Медіани трьох запусків, у блоках за секунду, якщо не зазначено інше:
| Сценарій | Zaino 0.10.1 | Ztreamer v0.1.0 |
|---|
| Діапазон із 1,000 блоків | 11,414 | 179,486 |
| Повне завантаження гаманця (280,000 → вершина) | 11,124 | 189,041 |
| Діапазон із 1,000 блоків, 128 клієнтів | 110,093 | 229,527 |
| Один блок, 128 клієнтів (запитів/с) | 6,843 | 11,044 |
За 128 клієнтів розрив звужується приблизно до 2 разів, оскільки обидва сервери були обмежені двома ядрами CPU.
Межа в 40 мс
На Zaino шість із дванадцяти RPC мають медіанну затримку приблизно 40 мс, а кожен RPC має 99-й перцентиль близько 41 мс. Причина полягає в тому, як Zaino налаштовує свій слухач gRPC: параметр сокета TCP_NODELAY ніколи не вмикається, тому операційна система затримує малі відповіді до 40 мс.
Увімкнення параметра ззовні, без зміни бінарного файлу Zaino, прибрало цю межу. Наприклад, GetTreeState знизився з 40.3 мс до 0.75 мс (Ztreamer: 0.63 мс). Потокове передавання великих блоків не змінилося, тож наведена вище різниця пропускної здатності є реальною.
Відмінності сумісності
- Zaino 0.9.0 за замовчуванням включає прозорі дані в
GetBlock, тоді як протокол вказує, що типовим значенням є лише shielded-дані. Це виправлено у версії 0.10.1.
GetSubtreeRoots: поле completingBlockHash використовує протилежний порядок байтів у двох індексаторах. Поточні гаманці не читають це поле.
- Коди помилок: Zaino повертає
INTERNAL для некоректного вводу; Ztreamer повертає INVALID_ARGUMENT або NOT_FOUND.
- Дубльовані адреси в
GetTaddressBalanceStream підраховуються двічі, за винятком Ztreamer master.
- JSON-RPC: Zaino у
getrawtransaction з деталізацією 0 повертає об’єкт замість шістнадцяткового рядка, на відміну від Zebra і zcashd.
Обмеження
- Лише тестнет. Блоки тестнету менші за блоки mainnet, тому абсолютні значення часу й розміру не є показниками mainnet. Порівняння є відносним, на ідентичних вхідних даних.
- Спільні машини CI з кількома моделями CPU. Повний звіт містить порівняння на однакових CPU для ключових показників.
- Не вимірювалися: реорганізації, відстеження вершини активного ланцюга, навантаження mempool і TLS.
Де дізнатися більше