English post is here
Используется в одном из наших проектов такая штучка как Project Voldemort. Если вкратце, то это весьма любопытная реализация key-value storage aka NoSQL database. То есть даешь ему ключик и значение, и оно быстро в памяти это хранит/отдает и на диске тоже сохраняет, для персистентности. Оно на Java написано, и вообще больше из Java мира, но обслуживать и тюнить его приходится конечно нам, OPS Team. :)
В общем, столкнулись мы с одной проблемкой при эксплуатации, а именно - при большом трафике на этот Вольдеморт его база начала пухнуть со страшной силой - буквально десятки гигабайт в час - хотя девелоперы уверяли что такого количества данных там быть не должно. Пришлось копаться.
В результате "копаний" выяснилось следующее - в качестве бэкенда этот Вольдеморт использует так называемую BDB JE - Berkeley DB Java Edition, и оказалось что это JE совсем не похожа на обычную Berkeley DB. Оказывается она write only - то есть, основана на том же принципе что и журнализируемые ФС - при любой операции - запись, обновление, удаление - данные ДОЗАПИСЫВАЮТСЯ в файлики на диске и сами по себе они НЕ УДАЛЯЮТСЯ. Специальный cleaner процесс потом ходит и чистит устаревшие данные - проверяет общую утилизацию файлов в БД, и если она меньше bdb.cleaner.minUtilization процентов (по дефолту - 50%) начинает проверять каждый файлик, и если в нем меньше bdb.cleaner.min.file.utilization процентов (5% по дефолту) файлик удаляется, и данные из него переносятся в новый файл.
Хорошо. Вроде бы надо поиграться этими параметрами. Но что то не похоже чтобы утилизация у нас была 50% - уж очень много данных на диске хранится. Проверяем -
# java -jar /usr/local/voldemort/lib/je-4.0.92.jar DbSpace -h /usr/local/voldemort/data/bdb -u
File Size (KB) % Used
-------- --------- ------
00000000 61439 78
00000001 61439 75
00000002 61439 73
00000003 61439 74
...
000013f6 61415 1
000013fd 61392 2
000013fe 61411 3
00001400 61432 2
00001401 61439 1
...
0000186e 61413 100
0000186f 61376 100
00001870 16875 95
TOTALS 112583251 7
Опа-па. Не работает значит чистка. Пытаемся увеличить количество потоков для чистки - играемся с bdb.cleaner.threads (по умолчанию 1) - без пользы. В результате гугления натыкаемся на тред в форуме посвященному BDB JE (как выяснилось, очень полезный форум, если вы в каком либо виде используете BDB JE - обязательно почитайте).
Тред (сорри, сейчас что то найти его не могу) ясно говорит о том, что на очистку может сильно влиять размер кеша BDB. То есть, если кеш маловат - чистка может даже не запускаться, так как при большом количестве ключей желательно чтобы все они влезали в кеш, иначе сильно падает производительность очистки. Желательный размер кеша можно прикинуть используя следующую команду -
# java -jar /usr/local/voldemort/lib/je-4.0.92.jar DbCacheSize -records 1000000 -key 100 -data 300
Inputs: records=1000000 keySize=100 dataSize=300 nodeMax=128 density=80% overhead=10%
Cache Size Btree Size Description
-------------- -------------- -----------
177,752,177 159,976,960 Minimum, internal nodes only 208,665,600 187,799,040 Maximum, internal nodes only 586,641,066 527,976,960 Minimum, internal nodes and leaf nodes
617,554,488 555,799,040 Maximum, internal nodes and leaf nodes
Btree levels: 3
(где key и data - средний размер ключа и данных, в байтах).
То есть, для наших данных, на каждый миллион записей нужно около 200 МБ кеша - а записей у нас был не один миллион. :(
Итого - после выставления адекватных кешей (bdb.cache.size), за сутки утилизация БД выросла с 7% до искомых 50%, соответсвенно размер БД упал В РАЗЫ.
Мораль - изучайте используемую технологию (даже если она используется не напрямую, а опосредовано. :) )
Этот комментарий был удален автором.
ОтветитьУдалить