Компания 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 наблюдается при пакетном обновлении данных (изменение сразу порции записей), затрагивающем большое число ключей, распределенных по всему хранилищу.
A. Sequential Reads
LevelDB |
4,030,000 ops/sec |
|
Kyoto TreeDB |
1,010,000 ops/sec |
|
SQLite3 |
186,000 ops/sec |
|
B. Random Reads
LevelDB |
129,000 ops/sec |
|
Kyoto TreeDB |
151,000 ops/sec |
|
SQLite3 |
146,000 ops/sec |
|
C. Sequential Writes
LevelDB |
779,000 ops/sec |
|
Kyoto TreeDB |
342,000 ops/sec |
|
SQLite3 |
26,900 ops/sec |
|
D. Random Writes
LevelDB |
164,000 ops/sec |
|
Kyoto TreeDB |
88,500 ops/sec |
|
SQLite3 |
420 ops/sec |
|
Результаты тестирования производительности базы 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 тыс операций в секунду.