Некоторые нюансы конфигурирования golos-ноды [50/50]
Если вы пытались или уже подняли ноду голоса, в процессе настройки вы скорее всего столкнулись с тем, что документация по развёртыванию и архитектуре в целом во многом неполная и частично устаревшая. Внятного описания параметров конфиг-файлов нигде нет.
Перед поднятием ноды хорошо бы представлять, для чего вы её поднимаете. Лично я поднимал, чтобы поиграться и разобраться что и как устроено. Ни на wiki, ни на странице проекта на github толком ничего не написано, какие вообще бывают типы нод. Не могу сказать, что я хорошо с этим разобрался, но кое-что определённо стало понятно.
Задачи, для которых нужна нода
- Вы хотите быть делегатом, соответственно нужна нода-делегат. Свежая инструкция от @vik
- Вы хотите просто помайнить. Кстати, майнится Сила Голоса, если вы не знаете.
- Вам нужна API-нода, чтобы поднять свой фронтенд или гонять скрипты.
- Вы хотите просто помогать сети, поддерживая работу блокчейна (при этом не быть делегатом).
Если почитать статью про настройку нод майнера и делегата на wiki, может сложиться впечатление, что вам нужно две отдельных ноды с разными конфигами. Именно так я и подумал сперва. На самом деле это не так, а именно: нода может быть или witness-only, или miner+witness, т.е. нельзя осуществлять PoW-майнинг без включения witness.
Quickstart
Итак, допустим мы решили воспользоваться quickstart-ом с гитхаба, запустить ноду и посмотреть что будет, понаблюдать за синхронизацией блокчейна, а в это время почитать доки.
На выбор нам предлагают запустить в докере "p2p Node" или "full node". Вот тут сразу и возникает первый непонятный момент: а чем же отличается эта "full node" от "p2p node" и какую нам надо?
Ответ: а ничем не отличаются, документация на github врёт 😁
Запуск "полной ноды" отличается только передачей переменной окружения USE_WAY_TOO_MUCH_RAM=1
, но если посмотреть код, она нигде не проверяется от слова вообще. Это какие-то ошмётки от steem - у них там в docker-контейнере запускается другой бинарник, если эта переменная выставлена, а в golos - она не проверяется.
По этому поводу запилена бага.
Опция компиляции, влияющая на память
Хотя USE_WAY_TOO_MUCH_RAM=1
является фейком, в golosd всё же есть опция, влияющая на потребление памяти. А именно, при компиляции можно задать опцию -DLOW_MEMORY_NODE=TRUE
. В официальном docker-image она установлена в FALSE
.
Note: Ниже будет написано насколько она влияет на RAM usage, а вот как она работает, я не разобрался, т.е. за счёт чего происходит экономия памяти и на что это влияет. Буду благодарен, если кто-то более знающий подскажет.
Версии
Имейте в виду, что если будете пересобирать golosd, вам надо взять текущую актуальную версию (на данный момент - 0.16.4), а не master
-бранч.
А где же хранятся данные?
В quickstart нет опций docker-а для проброса volume, поэтому у меня сразу же возник вопрос, а где же демон держит блокчейн? Разбирательства показали, что у демона есть 2 места хранения данных:
- Непосредственно блокчейн кладётся прямо внутри docker-контейнера в /var/lib/golosd, что несомненно является дичью. Надо обязательно класть данные блокчейна во внешний volume, т.е. добавить опцию -v
docker run ... -v /srv/golos:/var/lib/golosd ...
- shared-файл, за него отвечают опции конфига
shared-file-size
иshared-file-dir
Note: конфиг-файл по дефолту используется зашитый в docker-контейнер, его надо пробрасывать, см. ниже
shared-file - описание
shared-файл - это по сути оперативные данные. Заполняется парсингом блокчейна, т.е. нода вычитывает весь блокчейн и держит все данные в этом файле. Размер этого файла будет зависеть от того, какие плагины вы включили в конфиге в опции enable-plugin =
Об этом shared-файле надо сказать, что golosd использует его по сути как оперативную память, и количество операций ввода-вывода (IOPS) с ним происходит просто огромное. Ни в коем случае не стоит пытаться держать его на обычных дисках. Машина встанет раком и LA улетит в небеса. Некоторые успешно держат его на SSD, но лучше просто держать в памяти. Как это делаем: увеличиваем размер /dev/shm, и пробрасываем её в docker
fstab:
none /dev/shm tmpfs defaults,size=12G 0 0
Перемонтируем:
mount -o remount /dev/shm
Запуск в docker:
docker run \
-d -p 2001:2001 -p 8090:8090 --name golos-default \
-v /srv/golos:/var/lib/golosd \
-v /dev/shm:/shm \
-v ./config.ini:/etc/golosd/config.ini \
goloschain/golos
config.ini:
shared-file-size = 12G
shared-file-dir = /shm
Если нода в процессе работы упрётся в недостаток shared-файла, будет валиться ошибка End of file
, потребуется увеличение этого файла и реиндекс блокчейна. Для того, чтобы запустить реиндекс блокчейна (т.е. пересоздание shared-файла), нужно запустить golosd с опцией --replay
. В случае с docker это можно сделать так:
docker run ... -e STEEMD_EXTRA_OPTS="--replay" ...
Note:
Q: Почему используется проброс /dev/shm, а не использование опции --shm-size
docker-а?
A: Потому что при перезапусках или пересозданиях контейнера такая shm не сохранится и надо будет каждый раз заново парсить блокчейн.
Сколько же нужно памяти
На объём потребляемой памяти под shared-файл влияет то, какие плагины загружены. Под witness/miner ноду нужен только плагин witness, тогда использование памяти будет минимальным.
config.ini для witness/miner:
enable-plugin = witness
public-api = database_api login_api
Итак, со единственным включенным плагином witness
сейчас размер shared-файла примерно такой:
- LOW_MEM=FALSE: полный блокчейн (~ 10 миллионов блоков): 4.7G
- LOW_MEM=TRUE: полный блокчейн (~ 10 миллионов блоков): 3G
Если вы настраиваете ноду под API и вам надо много плагинов, потребление памяти на данный момент будет что-то около 15-16G RAM.
docker-compose.yml
На закуску вот вам для примера мой docker-compose.yml, которым можно удобно гонять ноду:
version: "2"
services:
golos1:
image: vvk/golos_lowmem:latest
#environment:
# STEEMD_EXTRA_OPTS: --replay
ports:
- "2001:2001"
- "8090:8090"
volumes:
- "/dev/shm:/shm"
- "/srv/golos1:/var/lib/golosd"
- "./config.ini:/etc/golosd/config.ini"
Note: образ vvk/golos_lowmem:latest
не выкладывал, это просто образ собранный по оригинальному Dockerfile с LOW_MEM опцией.
P.S.
Тема майнинга, генерации и подписи блоков сознательно тут не рассматривается дабы не перегружать статью. Думаю, надо написать отдельную статью, т.к. эта тема всё ещё остаётся плохо освещённой и нуждается в пояснении.