Компания Google объявила о переводе LevelDB, высокопроизводительной системы для хранения данных в формате ключ/значение, в разряд открытых проектов. Хранилище LevelDB написано на языке С++ и подключается к приложениям в виде разделяемой библиотеки (как SQLite и BerkeleyDB), обеспечивая возможность хранения упорядоченных наборов данных, в которых строковые ключи сопоставлены со строковыми значениями. Код LevelDB открыт под лицензией BSD.
Отдельно подчеркивается поддержка эффективного упорядоченного хранения, т.е. связки ключ/значение хранятся в отсортированном виде. Среди примеров возможных применений LevelDB, упоминается использование библиотеки в web-браузере, для хранения кэша последних открытых страниц, или использование в пакетном менеджере для хранения списка установленных пакетов и связанных с ними зависимостей. Библиотека спроектирована с учетом возможности построения на её основе более высокоуровневых систем хранения. В частности, LevelDB планируется использовать в будущей версии браузера Chrome для организации работы IndexedDB HTML5 API. Более того, LevelDB уже поддерживается в качестве низкоуровневого хранилища в таких закрытых проектах Google, как Bigtable (в формате LevelDB хранятся конечные записи) и распределенной БД Riak (LevelDB может использоваться как хранилище для конечных узлов).
Положительной чертой LevelDB является минимальное число зависимостей, что позволяет легко портировать библиотеку для разнообразных систем. В настоящий момент LevelDB уже работает в Unix-подобных ОС, Mac OS X, Windows и Android. Отдельно отмечается, что LevelDB является достаточно специализированным решением, например, LevelDB не поддерживает выполнение SQL-запросов и подключение индексов; не поддерживается одновременный доступ к БД нескольких процессов - в заданный момент времени только один процесс может работать с файлом базы (возможна работа в многопоточных программах); отсутствует встроенное решение для организации клиент-серверного доступа, работа сервера может быть организована в виде приложения-надстройки.
Основные возможности LevelDB:
- В качестве ключей и привязанных к ним значений может использоваться произвольный байтовый массив;
- Данные хранятся отсортированными по связанному с ними ключу;
- Пользователь может переопределить метод сортировки, указав собственную функцию сравнения;
- Управление данными производится через базовые операторы Put(key,value), Get(key) и Delete(key);
- В рамках одной атомарной операции в базу может быть внесено сразу несколько изменений;
- Поддерживается создание снапшотов, представляющих собой неизменный срез состояния БД на текущий момент времени. Со снапшотом можно работать в штатном режиме, но в нём не будут отражаться изменения базы, производимые после его создания;
- Над данными можно использовать прямые и обратные итерации (переходить к следующему или предыдущему элементу отсортированного списка);
- Данные хранятся в сжатом виде, для сжатия используется библиотека Snappy;
- Все внешние операции на уровне операционной системы, такие как работа с файлами, производится через виртуальный программный интерфейс, который позволяет пользователю изменить поведение библиотеки при взаимодействии с операционной системой.
Библиотека достаточно хорошо оптимизирована и демонстрирует высокую производительность при различных видах использования. Разработчики Google провели сравнение производительности LevelDB c такими системами, как SQLite, Kyoto Cabinet и InnoDB. В результате тестирования было выявлено, что существенное преимущество LevelDB наблюдается при пакетном обновлении данных (изменение сразу порции записей), затрагивающем большое число ключей, распределенных по всему хранилищу.
Результаты тестирования производительности базы LevelDB (ключ - 16 байт, значение - 100 байт, изначальное число записей - 1 миллион, итоговый размер базы с учетом сжатия - 62 Мб):
- Последовательная запись: 1.765 micros/op; 62.7 MB/s;
- Запись со сбросом изменений на диск (выполнение вызова fsync) после каждой операции: 268.409 micros/op; 0.4 MB/s (10000 операций в секунду);
- Записи в случайном порядке: 2.460 micros/op; 45.0 MB/s;
- Перезапись существующих ключей: 2.380 micros/op; 46.5 MB/s;
- Случайное чтение в режиме холодного старта: 60 тыс операций в секунду;
- Последовательное чтение в режиме холодного старта: 232.3 MB/s;
- Последовательное чтение в обратном порядке в режиме холодного старта: 152.9 MB/s;
- Случайное чтение после проведения большого числа случайных записей: 85 тыс операций в секунду;
- Случайное повторяющиеся чтение: 100 тыс операций в секунду;
- Случайное повторяющиеся чтение с кэшем в который вмещаются все распакованные данные: 190 тыс операций в секунду.