Страницы

Поиск по вопросам

вторник, 17 декабря 2019 г.

Выбор key-value storage

#cpp #nosql


Необходимо обеспечить доступ к набору данных вида (key, value) где key - числовой
идентификатор, а value - динамический массив. На С++ я описал бы структуру так:
typedef struct {
    int id;
    int time;
    double value;
} item;

typedef std::unordered_map > my_storage;

Но, к сожалению датасет не помещается в оперативную память. Поэтому нужно выбрать
какое-то хранилище данных. Задача имеет следующие особенности:

Длина динамических массивов распределена экспоненциально (половина массивов вообще
состоят из одного элемента).
Хранилище заполняется постепенно: данные вида std::pair поступают
отсортированные по полю item.time и добавляются в конец соответствующего динамического
массива.
Хранилище должно обеспечивать операции двух видов: чтение целого массива по ключу
и добавление одного элемента в конец соответствующего ему массива
Вероятность обращения к конкретному массиву зависит от поля item.time последнего
элемента массива (тоже экспоненциально). Так как каждый массив отсортирован по возрастанию
item.time, можно сказать, что вероятность обращения зависит от времени последнего обращения
к нему.

Я нагуглил несколько вариантов таких хранилищ: LevelDB, Berkeley DB, Kyoto Cabinet...
Даже бенчмарк нашел: 
Требования к базе такие:

Возможность хранения значений переменной длины (наверное все могут - строки-то хранить
как-то научились).
Если массив-значение длинный, не перезаписывать его полностью, а только конец с добавленным
элементом.
Кэширование наиболее часто запрашиваемых массивов.
Желательно, чтобы база была встраиваемой. Не хочется терять время на сериализацию
и сетевое взаимодействие. Сервер-то один.

Данных будет где-то 50-200 Gb (это если слепить в один массив все структуры типа item).
Ну, собственно, прошу помочь тех, кто  работал с перечисленными выше БД. Или, может,
что-нибудь другое предложите?
UPD:
Забыл добавить, что задание скорее учебное, поэтому ни транзакции, ни конкурентный
доступ с большого числа клиентов, ни постоянная синхронизация не нужны.
Нашел еще решение: HDF5. Позиционируется как раз, как хранилище для научных данных.
Кто работал с ним, можете прокомментировать?
Еще хотел спросить у знающих людей, какие FS + mount options использовать, чтобы
избежать ненужного журналирования?    


Ответы

Ответ 1



Я бы использовал LevelDB, но со сложным ключом (основной идентификатор + номер в массиве или time), чтобы значением был только один элемент, а не массив. Поскольку в LevelDB данные отсортированы по ключу, то можно пробежаться по следующим/предыдущим ключам и получить весь массив.

Ответ 2



То, что Вы превели, в качестве примера - не предназначенно для этого, как минимум, будет очень медленно. Для таких объемов, скорее что-то на https://ru.wikipedia.org/wiki/Hadoop с https://ru.wikipedia.org/wiki/Apache_Cassandra.

Комментариев нет:

Отправить комментарий