Comments 66
2) Вы ведь проводили бенчмарки? Можно увидеть результаты сравнения производительности с другими решениями, хотя бы с тем-же mysql?
2. К сожалению нет, но существующие SQL-решения (в частности, PostgreSQL) при наличии индекса по ключу неприемлемо замедлялись при миллионах записей (скорость падала в сотни раз). Данное же решение позволило записать несколько миллиардов записей на два сервера (оборудованных SSD) в течение 6-ти дней (половина отведённого времени ушло на парсинг источников данных). За этот срок скорость записи упала на 30%.
2) Какой именно тип индекса пробовали? Какого размера ключи и значения?
2. Нету никаких алгоритмов, просто массив строк отсортировали и поделили на части с заданным размером, сжали и записали в файлы.
Гм-гм, велосипедостроение, конечно, почетная и уважаемая отрасль промышленности, но сложно представить себе современную базу данных, которая бы захлебнулась на миллионах/миллиардах записей при хоть сколько либо вменяемых настройках и железе.
Плюс к тому, существующие решения и пишут на диск грамотнее и хранят лучше. То, что вы три дня писали терабайт на SSD как бы намекает на неоптимальность вашего решения. Чисто ради интереса: а сколько времени ушло на разработку?
Итераторы в LevelDB делают его очень гибким.
В вашем случае, возможно, стоит еще обратить внимание на RocksDB
Это доработанный LevelDB. Он оптимизирован для SSD и подходит для больших размеров БД. Не нужны лишние конвертирования — можно хранить бинарные данные. Ну и скорость нaaaамного выше. Три дня, что-то уж совсем перебор.
Короче, LevelDB/RocksDB — то что вам нужно.
Если же вам нужно одновременно И читать, И активно писать, то это надо было делать с разных реплик, конечно же.
Не вполне понятно, для чего эта статья.
О том, как раскидать миллиард записей по файлам? Так это почти тривиально не такая уж сложная задача.
Предоставить сообществу код? Но тогда хотелось бы видеть лицензию и комментарии в коде (единственный — комментарий репозитория "Key/value(s) database capable for effective storage of billions of records" — мало о чём говорит). Вообще, текущая ревизия — неплохой пример того, что т. н. "самодокументируемый код" плохо понятен. Описание "алгоритмов" тоже не слишком подробно.
И самое главное — где результаты замеров скорости записи и поиска? Сколько ключей, сколько записей на один ключ, какой их объём?
Интересно было бы увидеть скорость с использованием других ФС и других алгоритмов сжатия. gzip всё-таки не самый быстрый (и не самый сильный) компрессор.
Тема интересна, но освещена недостаточно подробно.
А уникальных ключей сколько?
SELECT * FROM table WHERE pkey IN (100 случайных ключей)
Время выполнения — 0.012s.
У автора одному ключу соответствует довольно большой список записей.
Возможно, "обычная" СУБД в этом случае из-за фрагментации списков записей с одним ключом будет тормозить при добавлении, да и при поиске (зависит от последовательности добавления; вероятно, перед поиском БД можно дефрагментировать).
К такому количеству записей существующие SQL/NoSQL системы хранения оказались плохо приспособлены
Неубедительно. Приведите сравнение по скорости с каким-нибудь MySQL/PostgreSQL, храня значение в листовой колонке, и документной базой типа Couchbase.
Чаще всего такие кейсы «миллиард записей» требуют многопоточных или распределённых по не скольким машинам приложений.
К такому количеству записей опробованные SQL/NoSQL системы хранения оказались плохо приспособлены
Данные в базе распределены по секциямПроводилось ли сравнение (в т.ч. по производительности) с распространенными СУБД именно с использованием секционирования?
Использовались ли при этом средства bulk insert сравниваемой СУБД?
Правда, там ограничение на 8К партиций. Если этого не хватает, то можно сделать несколько таблиц, если логика задачи позволяет. Правда, тогда разделение данных по таблицам придется самостоятельно реализовывать.
Ну или другую СУБД выбрать, с другим ограничением.
В пределе можно вообще эмулировать секционирование, создав 64К таблиц. Но насколько это хороший вариант — не знаю, надо тестировать.
Ну есть же достаточно большое количество СУБД которых вам с головой хватит, тем более при таких то объемах
Глянул Apache Hadoop, но там безумное количество каких-то пакетов, месяц уйдет, чтобы разобраться. А что ещё можно попробовать?
А вы уверены, что вам нужна rdbms? Hadoop вообще ни пол раза не про sql.
Если исходные данные в виде какой-нибудь csv, то можно попробовать любой поточный обработчик. Например, Apache Spark, он может обмолотить довольно быстро. Ну и лучше, конечно, сначала обкатать на небольшом куске алгоритмику, а потом уже развлекаться со всей базой. Больше итераций может быть куда более продуктивным подходом.
Мне нужно сджойнить 3 csv-файла и посчитать частоты. Можно было бы всё это делать небольшими кусками по миллиону записей. Но проблема в том, что данные идут вперемежку, сначала 100Gb-файл нужно отсортировать. Для сортировки и джойнинга я как-раз и хотел использовать РСУБД. Ну, и частоты тоже можно сразу в РСУБД посчитать. Но оказалось, что это очень медленно.
Спасибо, попробую Apache Spark, тем более у него есть биндинги для R и библиотека для машинного обучения. Хотя есть сомнения, что он сможет сджойнить несколько CSV, отсортировать их и при этом уложится в 16Gb оперативной памяти.
А колоночные РСУБД кто-нибудь пробовал?
Если вместо CSV использовать более адекватные форматы, то со Spark можно добиться ещё большей производительности. Ещё в Spark очень прикольный Web UI, в котором видна схема выполняемого запроса, виден прогресс каждого шага — сколько данных уже обработано и т.п. Напоминает SSIS-скрипт, только ты его не накликиваешь мышкой, а пишешь нормальный код на R или другом языке, а схема выполнения рисуется сама.
Словом, очень не хотелось изучать очередную технологию. Но Spark — очень клевая штука.
Чтение этих данных — питон потоково получал, распаковывал и передавал сырье в с++ либу которая уже все обсчитывала. По скорости, 20 млн (или 200 млн, уже не помню) записей обрабатывались за 2 сек на одном ядре, это включая вычитывание из базы и пересчет — формирование простого отчета, на одно ядро виртуалки из DO. Не один SQL-db построчно такую скорость не выдаст на ядро.
За счет чанкования и сжатия скорость выросла в сотни раз, занимаемое место уменьшилось в десяки и индексы уменьшились в сотни раз.
Возможно ClickHouse нам бы подошел, но его ещё не было (в паблике).
1000 ключей по 10 000 значений = 10 000 000 записей, размер значения ~100 байт:
CSV GENERATION:
real 2m4.618s
user 1m51.416s
sys 0m12.280s
CSV IMPORT:
real 0m33.533s
user 0m21.216s
sys 0m2.640s
INDEX CREATION:
real 0m6.253s
user 0m4.420s
sys 0m1.036s
#!/bin/bash
keys=1000
values=10000
size=100
data=$(tr -dc 'a-z' < /dev/urandom | head -c $size)
csv_file=test.csv
db_file=test.db
rm $csv_file $db_file
echo CSV GENERATION:
echo key,value > $csv_file
time for k in $(seq $keys); do
for v in $(seq $values); do
echo $k.key,$k.$v.$data
done
done >> $csv_file
echo
echo CSV IMPORT:
time echo -e ".mode csv\n.import $csv_file kv" | sqlite3 $db_file
echo
echo INDEX CREATION:
time sqlite3 $db_file 'create index ikey on kv (key)'
Размер csv — 1.1 Gb
Размер базы с индексом — 1.4 Gb
Человек решил свою задачу так как ему нравится. Поделился с вами своим внутренним миром и получил «а зачем», «а есть же». Чуть ли не «ты дурак, делал то что уже есть»
Семён (@ababo) жму руку. От какой суммы рассматриваешь предложения о работе?
Кто из вас, минусующих автора диванных аналитиков, написал свое хоть немного что-то близкое по сложности?
Задача не так сложна, как вам кажется. Автор в ~800 строк кода на go уложился — уже показатель невысокой сложности. Примерно уровень курсового проекта. Такое писали все.
Система хранения для миллиардов записей с доступом по ключу