less account history
Недавно был принят pull request в 0.17.2 ветке,
https://github.com/GolosChain/golos/pull/527
Потому я хотел немного написать, как и в каких случаях им пользоваться.
Эти изменения помогают значительно экономить на потребляемой нодой shared_memory памятью за счет того, что не все данные хранятся в базе данных ноды.
account_history плагин
Как многие знают, есть регулярные операции, которые записываются в блокчейне (comment, vote, transfer) и есть виртуальные, которые генерируются golos-нодой в результате некоторых событий (author_reward, curator_reward).
account_history плагин получает все эти операции и записывает их базе данных ноды. В результате базе данных требует большое количество места в shared_memory файле. Я конкретно сказать не могу, так как полную версию истории уже давно своими нодами не сохранял, но думаю уже более 50G требуется миниум. Если держать shared_memory файл на диске, то синхронизация всей истории может продлиться до 5 дней (@vik). Зависит конечно от размера оперативной памяти. Можно, при наличии 64G RAM поместить файл на RAM диск, синхронизация тогда будет идти быстрее, но можно себе представить, сколько стоит аренда сервера с таким количеством оперативной памяти.
Потому я искал методы по сокращению потребляемой памяти. Самый простой способ - выключить account_history плагин. Потребление сокращается в разы (12-15Gb, не проверял, если не LOW_MEM), но теряется возможность получить от ноды виртуальные операции, что может быть необходимо. Можно конечно самому посчитать, тоже авторское вознаграждение, но это сильно затратно.
Потому я для себя поменял account_history плагин, что бы для начала он сохранял только виртуальные операции в истории. Нода у меня стала потреблять памяти порядка 18G, синхронизация длилась уже всего часов 7.
А потом я увидил в steemit, что они уже адаптировали account_history, что бы можно было гибко задавать список операций, которые будут сохраняться в истории. Эту возможность я и портировал в 17.0 ветку голоса.
Теперь можно параметрами history-whitelist-ops и history-blacklist-ops задать список операций, которые будут сохраняться в истории.
К примеру так
history-whitelist-ops = author_reward_operation curation_reward_operation
Дальше, мне лично не интересна полная история голоса, скрипты, что у меня есть, обрабатывают только оперативные данные и сохраняют у себя в локальной базе агрегированные данные. Потому нету нужды при синхронихации ноды сохранять историю. Достаточно начать ее сохранять с актуального блока. Потому был добавлен еще один параметр - history-start-block. Этим параметром можно задать номер блока с которого начнется сохраняться история.
Это экономит еще порядка 3-5G потребляемой памяти и время синхронихации сократилось еще в двое, до 3 часов (зависит от наличия свободной памяти под кэш).
Даже если потом нода упадет, что бы не иметь разрыва в получаемых данных, можно при синхронихации в конфигурационном файле задать последний обработанный блок.
history-start-block = 15399855
Теперь типричный скрипт обрабатывает данные следущим образом.
block = 1
while(true) {
processVirtualOps(get_ops_in_block(block));
processRegularOps(get_block(block));
block++;
}
то есть get_ops_in_block получаем виртуальные операции и обрабатываем их, а вторым вызовом получаем уже регулярные операции и тоже обрабатываем их.
LOW_MEM
Если включить флаг прекомпайлера LOW_MEM, то получится еще сэкономить 1-2 гигабайта памяти. Но была проблема в том, что при установленном LOW_MEM виртуальные операции не отправлялись на обработку плагинам. Потому account_history плагин был бесполезен с LOW_MEM нодой.
Потому было внесено изменение в код, теперь и LOW_MEM нода отправляет на обработку виртуальные операции плагинам. Для совместимости добавлен новый параметр skip_virtual_ops. Если его установить в true, то виртуальные операции не будут передаваться плагинам на обработку.
CLEAR_VOTES
Еще сэкономить получалось при установки прекомпайлер флага CLEAR_VOTES. В этом случае votes после получения выплат удалялись из базы данных. Это экономит еще 1 гигабайт или больше памяти.
Проблема только была в том, если выплаты прошли, а их надо к примеру распределить среди проголосовавших (откатный скрипт, бустер паровоз), то с установленным CLEAR_VOTES не было возможность получить список проголосовавших с rshares (get_content.active_votes пуст).
Потому был CLEAR_VOTES фалг заменен конфигурационным параметром clear-votes-before-block
clear-votes-before-block = 15399855
То-есть можно задать, до какого блока голоса будут удаляться. Если при синхронизации задать актуальный блок, то все старые посты будут синхронизированы без votes. А начиная с заданного блока голоса будут сохраняться и могут быть использованны в скриптах.
При наличии всего этого, нода на моем домашнем компьютере синхронизировалась 2.5 часа и shared_memory файл получился размером 6G! Для моих нужд получаемых данных вполне достаточно и нода будет работать вполне комфортно и на слабом, но дешевом сервере.