Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
xandros
6 лет назад

Нода нищеброда

Введение

Доброго времени суток, Голос.

Исходя из более менее свежих материалов по настройке witness-ноды блокчейна Golos, для стабильной и комфортной работы делегата необходим сервер с минимум 6ГБ ОЗУ (речь про сборку/реплей, уже готовая нода входит на 1ГБ ОЗУ - в комментариях @t3ran13 подтверждает этот факт). Такие редко попадаются, обычно у хостеров при нарезке мощностей речь идёт о степенях двойки. Выходит, нужно смотреть в сторону 8ГБ. Но мы не ищем легких путей, попробуем сэкономить, всё уместить в 4ГБ и не ждать второго пришествия, глядя на уныло текущий реплей. На диске на текущий момент блокчейн с последним блоком в районе 16500000 занимает в районе 16ГБ, плюс индексы, плюс shared_memory файл. Добавив ко всему этому безобразию размер самой операционной системы легко вываливаемся за 20ГБ.

du -hs --apparent-size /home/golosnode0.17.2/blockchain/*
16G /home/golosnode0.17.2/blockchain/block_log
127M    /home/golosnode0.17.2/blockchain/block_log.index

Тут отдельно стоит отметить, что блокчейны крайне прожорливы, и актуальные данные по требуемым техническим характеристикам весьма быстро устаревают. Стоит учитывать этот момент и всегда брать с запасом. Закладывая эти соображения тоже, мы и будем пытаться сегодня сэкономить на ноде делегата.

Сразу оговорюсь, мы не будем использовать для сборки/реплея и других операций домашние ПК, ноутбуки соседей по даче и какие-то еще дополнительные мощности. Задача - собрать живой конфиг для уверенной работы голой ноды делегата без всего лишнего.

Выбор железа

Для начала находим более-менее вменяемый хостинг по соотношению цена-качество. Для этого можно воспользоваться сервисами вроде VDS.menu (не реклама) или просто спросить у знакомых веб-мастеров.

Я давно использую Hetzner, его же предлагает вышеупомянутый подборщик. На нем и остановимся. Пробуем влезть в мощности конфигурации CX21 (2 CPU, 4 GB RAM, 40 GB SSD, 20 TB TRAFFIC):

Снимок экрана от 2018-05-15 23-57-34.png

Стреляем серебрянными пулями

Для начала объясню несколько моментов, которые позволяют таки влезть в столь скромные ресурсы (детальное описание основных используемых технологий было приведено в прошлом посте):

  1. Оперативную память прокачаем с помощью zRam. В среде Steem этот модуль ядра уже давно используют многие делегаты (там, к слову, для комфортной работы full-ноды в начале года перестало хватать 256ГБ ОЗУ, а сервера с 512ГБ стоят как крыло от самолета)
  2. Положим всю систему на ZFS, что позволит изрядно сэкономить на размерах самого блокчейна без значительной потери в производительности. В качестве компрессии возьмем показывающую неплохие результаты LZ4.
    Снимок экрана от 2018-05-15 23-37-01.png

    Swap также разместим в ZFS, но с минимальным сжатием LZE. Вместо этого можно использовать похожую на zRam технологию zSwap, но у нас всё будет в едином стиле.
  3. Включим опцию сборки Голоса LOW_MEMORY_NODE, дабы высвободить еще немного ОЗУ. Это вроде как best practice для нод делегатов, если верить официальной доке
  4. Хранить shared-memory будем в tmpfs (так советуют делать старожилы) из-за большого количества обращений с ним (у нас система на SSD, но даже это уже давно не панацея, да и помним про циклы перезаписи)
  5. Запретим на этапе реплея лазить в кэш файлу данных блокчейна block_log, тем самым оставим место в ОЗУ и swap исключительно под shm с помощью dd флага nocache.

Установка и настройка системы

У Hetzner есть удобный rescue-режим, в котором можно сконфигурировать будущую систему и произвести первоначальную настройку железа (виртуального, в данном случае). К сожалению, их автоматический скрипт-инсталлятор installimage не умеет в zfs, поэтому установим ОС на обычный раздел, а потом перенесем (в момент оформления заявки на виртуалку выбираем любую операционную систему, всё равно потом будем ставить через rescue).

  1. Грузимся в rescue из консоли управления, входим по SSH.

    hetzner rescue motd
    Если при входе видим нечто похожее - мы там, где нужно

  2. Запускаем скрипт installimage, выбираем Ubuntu 16.04 minimal (тут не принципально, полагаю к примеру свежий 18.04 релиз умеет во все наши хитрости не хуже, просто я консервативен в выборе ОС) и попадаем в настройки.

  3. В файле конфигурации указываем, что система должна будет располагаться на 4ГБ разделе, а остальное пусть займет /home, потом удалим (настройка эта располагается ближе к концу файла):

    Снимок экрана от 2018-05-17 11-21-35.png

  4. Выходим из конфигуратора, ждем установки и перезагружаемся в свежеустановленную систему.

  5. Размонтируем /home, он нам больше не нужен (удаляем его из автозагрузки с помощью редактирования файла /etc/fstab)

    umount /home 
        
    sed -i '/\/home/s/^/#/' /etc/fstab
    
  6. Устанавливаем необходимые для работы zfs компоненты

    apt-get update && apt-get install zfs-dkms zfs-initramfs
    
  7. Создаем пул на разделе, который недавно был /home, проверяем успешность создания

    zpool create -o ashift=12 -O atime=off -O canmount=off -O compression=lz4 -O normalization=formD rpool -f /dev/sda2
    
    zpool status
       pool: rpool
     state: ONLINE
      scan: none requested
    config:
    
        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          sda2      ONLINE       0     0     0
    
    errors: No known data errors
    
  8. Делаем файл подкачки, добавляем его в автозагрузку

    zfs create -V 4G -b $(getconf PAGESIZE) -o compression=zle -o logbias=throughput -o sync=always -o primarycache=metadata -o secondarycache=none -o com.sun:auto-snapshot=false rpool/swap
    
    mkswap /dev/zvol/rpool/swap
    Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
    no label, UUID=41be4f36-fbea-4e31-a736-3f17a7a14646
    
    echo "/dev/zvol/rpool/swap none swap defaults 0 0" | tee -a /etc/fstab
    
  9. Создаем в пуле контейнер под системный раздел, делаем его загружаемым и указываем точку монтирования (не пугаемся варнингам)

    zfs create rpool/root
        
    zfs set compression=lz4 rpool/root
        
    zfs set mountpoint=/ rpool/root
    cannot mount '/': directory is not empty
    property may be set but unable to remount filesystem
    
  10. Сохраняем наш конфиг

    zpool export rpool
    
  11. Создаем временную точку монтирования и подключаем туда наш контейнер для переноса операционной системы

    mkdir /mnt/rpool
    zpool import -R /mnt/rpool/ rpool
    
  12. Копируем всё в контейнер

    rsync -a --one-file-system / /mnt/rpool/
    
  13. Заходим в окружение портированной системы и исправляем системную конфигурацию для корректной загрузки с ZFS

    cd /mnt/rpool/ && mount --bind /dev dev && mount --bind /proc proc && mount --bind /sys sys && mount --bind /run run && chroot .
        
    / # export ZPOOL_VDEV_NAME_PATH=YES && update-grub && grub-install /dev/sda
    Generating grub configuration file ...
    Found linux image: /boot/vmlinuz-4.13.0-36-generic
    Found initrd image: /boot/initrd.img-4.13.0-36-generic
    done
    Installing for i386-pc platform.
    Installation finished. No error reported.
        
    / # exit
    
  14. После выхода из окружения размонтируем всё, сохраняем настройки пула и перезагружаемся в новую систему на zfs

    cd .. && umount /mnt/rpool/{dev,proc,run,sys} && zpool export rpool && shutdown -r now
    
  15. После загрузки системы проверяем, что мы уже на zfs

    df -h
    Filesystem      Size  Used Avail Use% Mounted on
    udev            1.9G     0  1.9G   0% /dev
    tmpfs           385M  8.0M  377M   3% /run
    rpool/root       29G  957M   28G   4% /
    tmpfs           1.9G     0  1.9G   0% /dev/shm
    tmpfs           5.0M     0  5.0M   0% /run/lock
    tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
    tmpfs           385M     0  385M   0% /run/user/0
    
    free -m
                  total        used        free      shared  buff/cache   available
    Mem:           3849         125        3641           7          82        3541
    Swap:          4095           0        4095
    
  16. Ставим и настраиваем zram

    apt-get update && apt-get install zram-config
        
    sed -i 's|/ 2 /|/ 1 /|g' /usr/bin/init-zram-swapping
        
    systemctl restart zram-config
    
  17. Снова убеждаемся, что у нас получилось

    free -h
                  total        used        free      shared  buff/cache   available
    Mem:           3.8G        614M        3.0G        8.1M        159M        2.9G
    Swap:          7.8G          0B        7.8G
    
  18. Ставим докер (исключительно по желанию) и другие недостающие приложения

    apt-get install docker.io screen git
    
  19. Качаем актуальный на сегодня билд голоса

    git clone https://github.com/GolosChain/golos.git && cd golos && git checkout v0.17.2
    
  20. В Dockerfile указываем необходимые нам параметры сборки, например так

    RUN
    cd /usr/local/src/golos &&
    git submodule update --init --recursive &&
    mkdir build &&
    cd build &&
    cmake
    -DCMAKE_BUILD_TYPE=Release
    -DLOW_MEMORY_NODE=TRUE
    ..
    &&
    make -j$(nproc) &&
    make install &&
    rm -rf /usr/local/src/golos

  21. Создаем рабочий каталог для конфига нашей ноды и файла блокчейна

    mkdir -p /home/golosnode0.17.2/blockchain
    
  22. Копируем config.ini и переделываем под себя (отключаем ненужные логи, указываем активный и публичный ключи делегата, если нужно - конфиги майнеров)

    cp share/golosd/config/config_witness.ini /home/golosnode0.17.2/
    
  23. Чтобы не ждать, пока блокчейн стянется с других p2p-нод, качаем откуда-нибудь готовый файл block_log (есть конечно https://download.golos.io/blockchain.tar.bz2, но его потом нужно разархивировать, а это тот еще геморрой с нашим-то минимализмом). Если взять готовый неоткуда - не беда, придется подождать его синхронизации из сети

  24. Увеличиваем shared-memory до максимально возможного. У нас 12ГБ ram+swap, делаем 11 (в config.ini с недавних пор указывать ничего не надо, там инкрементально с 2ГБ растёт объем, стоит только проверить, что директива смотрит по верному пути (shared-file-dir = /dev/shm)

    mount -o remount,size=11264M /dev/shm
    
  25. Запускаем сборку ноды в докере (тут кому как больше нравится, я им пользуюсь чуть ли не впервые, до этого всегда ручками собирал) и идём пить чай/кофе/другие напитки

    docker build -t xandros/golos -f Dockerfile .
    
  26. Заходим в сессию screen и запускаем небольшой костыль, чтобы файл block_log не кэшировался

    cd /home/golosnode0.17.2/ && while : ; do  dd if=blockchain/block_log iflag=nocache count=0; sleep 60; done
    
  27. Если ошибок в процессе сборки не было - запускаем контейнер на реплей

    docker run -d -p 4243:4243 -v /home/golosnode0.17.2/config.ini:/etc/golosd/config.ini -v /home/golosnode0.17.2/blockchain/:/var/lib/golosd/blockchain/ -v /dev/shm:/dev/shm -e STEEMD_EXTRA_OPTS="--replay" --name "xgolos" xandros/golos
    
  28. Мониторим работу и ждем окончания реплея

    docker logs --tail=100 -f xgolos
    

У меня ~16450000 блоков закончили индексирование примерно через час

2107749ms th_0 database.cpp:207 reindex ] Done reindexing, elapsed time: 3583.34902099999999336 sec
2107751ms th_0 plugin.cpp:333 plugin_startup ] Started on blockchain with 16512369 blocks

После успешного реплея рекомендую стопнуть контейнер (когда он начнет получать транзакции в штатном режиме)

docker stop xgolos && docker rm xgolos

Затем удалить опцию "--replay" и перезапустить его заново

docker run -d -p 4243:4243 -v /home/golosnode0.17.2/config.ini:/etc/golosd/config.ini -v /home/golosnode0.17.2/blockchain/:/var/lib/golosd/blockchain/ -v /dev/shm:/dev/shm --name "xgolos" xandros/golos

Посткриптум

Данный опыт носит исключительно исследовательский характер, показывает возможность разворачивания ноды на сервере представленной конфигурации и никоим образом не призывает держать свои основные ноды в таких спартанских условиях. Вероятно кому-то будут полезны лишь некоторые моменты из вышеизложенного, кто-то же может попробовать воспроизвести подобное у себя в песочнице.

Resource Monitor
График нагрузки из панели хостера

При написании использовались опубликованные ранее материалы следующих авторов: @t3ran13, @vik, @vvk. Выражаю им свою благодарность.


Текст подготовлен в редакторе OnePlace.media. Если Вы хотите поддержать проект, голосуйте за делегата oneplace по ссылке или любым другим удобным способом

oneplace witness

21
194.951 GOLOS
На Golos с December 2017
Комментарии (22)
Сортировать по:
Сначала старые