RocksDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 15:24, 12 ноября 2017.
RocksDB
Rocksdb logo.png
Разработчики: Facebook
Выпущена: May 2012; 6 years ago (2012-05)
Постоянный выпуск: 5.8 / 28 September 2017 года; 8 months ago (2017-09-28)
Состояние разработки: Active
Написана на: C++
Операционная система: Linux, Windows, FreeBSD, Os X
Локализация: English
Тип ПО: Встраиваемая СУБД
Лицензия: Apache 2.0, GNU GPL 2
Веб-сайт rocksdb.org

RocksDB (англ. Rocks DataBase)) - это высокопроизводительная встраиваемая СУБД для данных типа ключ-значение. Проект RocksDB является ответвлением от LevelDB, оптимизированным для выполнения на многоядерных центральных процессорах (ЦП), рабочих нагрузок ввода/вывода (I/O) и эффективного использования быстрой памяти, например твердотельных накопителей (SSD). Он основан на журнально-структурированном дереве со слиянием (LSM tree). Написан на C++ и предоставляет официальные API для C ++, C и Java. RocksDB является программным обеспечением с открытым исходным кодом и был первоначально выпущен под лицензией BSD. Однако в июле 2017 года проект был перенесен на лицензию Apache 2.0.[Источник 1]

RocksDB используется в производственных системах на различных веб-предприятиях, включая Facebook[Источник 2]. , Yahoo![Источник 3] и LinkedIn[Источник 1]


Содержание

Назначение, совместимость и поддержка

Назначение

Основная цель разработки для RocksDB заключается в том, что она должна быть эффективной для быстрого хранения и для рабочих нагрузок сервера. Она должна использовать весь потенциал высоких скоростей чтения/записи, предлагаемых подсистемами Flash или RAM. RocksDB должна поддерживать поиск атомарных данных также эффективно, как и сканирование диапазонов. Она должна быть сконфигурирована для поддержки высоких рабочих нагрузок с произвольным считыванием, высокой рабочей нагрузки или комбинации обоих. Её архитектура должна поддерживать легкую настройку Read Amplification, Write Amplification и Space Amplification.[Источник 4]

Поддержка

RocksDB должна быть разработана таким образом, чтобы она имела встроенную поддержку инструментов и утилит, которые помогают развертывать и отлаживать производственные среды. Большинство основных параметров должны полностью настраиваться, чтобы их можно было использовать различными приложениями на разных аппаратных средствах.[Источник 4]

Совместимость

Более новые версии этого программного обеспечения должны быть обратно совместимы, поэтому существующие приложения не должны меняться при обновлении до более новых версий RocksDB.[Источник 4]


Особенности[Источник 4]

Get-ы, итераторы и снимки

Ключи и значения рассматриваются как чистые потоки байтов. Нет ограничений на размер ключа или значения. Get API позволяет приложению извлекать из базы данных одно значение ключа. API MultiGet позволяет приложению извлекать несколько ключей из базы данных. Все значения ключей, возвращаемые посредством вызова MultiGet, согласуются друг с другом.

Все данные в базе данных логически размещены в отсортированном порядке. Приложение может указать метод сравнения ключей, который определяет общий порядок ключей. Iterator API позволяет приложению делать RangeScan (сканирование диапазонов) в базе данных. Итератор может искать указанный ключ, а затем приложение может начать сканирование одного ключа за раз с этого места. Iterator API также можно использовать для обратной итерации ключей в базе данных.

Snapshot (снимки) API позволяет приложению создавать представление базы данных в определенный момент времени. Get API и Iterator API могут использоваться для чтения данных из указанного моментального снимка. В некотором смысле, Snapshot и Iterator обеспечивают представление базы данных в определенный момент времени, но их реализация отличается. Недолговечные проверки лучше всего делать с помощью итератора, тогда как длительные проверки лучше делать с помощью моментального снимка. Итератор хранит подсчет ссылок на все базовые файлы, соответствующие этому временному представлению базы данных; эти файлы не удаляются до тех пор, пока не будет выпущен Iterator. С другой стороны, моментальный снимок не препятствует удалению файлов; вместо этого процесс уплотнения понимает наличие моментальных снимков и гарантирует не удалять ключ до тех пор, пока он виден в любом существующем снимке.

Снимки не сохраняются при перезагрузке базы данных: перезагрузка библиотеки RocksDB (через перезагрузку сервера) освобождает все ранее созданные снимки.

Префикс-итераторы

Большинство механизмов LSM не могут поддерживать эффективный RangeScan API, потому что ему необходимо изучить каждый файл данных. Но большинство приложений не выполняют чисто-случайное сканирование диапазонов ключей в базе данных; вместо этого приложения обычно сканируют через префикс-ключи. RocksDB использует это в своих интересах. Приложения могут настроить префикс-экстрактор для указания префикс-ключа. RocksDB использует это для хранения bloom-ов для каждого префикс-ключа. Итератор, который задает префикс (через ReadOptions), будет использовать эти bloom-биты, чтобы не смотреть в файлы данных, которые не содержат ключей с указанным префикс-ключом.

Обновления

Put API вставляет единственное значение ключа в базу данных. Если ключ уже существует в базе данных, предыдущее значение будет перезаписано. Write API позволяет вводить атомарно несколько значений-ключей в базу данных. База данных гарантирует, что либо все ключи-значения в одном вызове Write будут вставлены в базу данных, либо ни одна из них не будет вставлена в базу данных. Если какой-либо из этих ключей уже существует в базе данных, предыдущие значения будут перезаписаны.

Живучесть

RocksDB имеет журнал транзакций. Все Put (вставки) хранятся в буфере памяти, называемом Memtable, а также опционально вставляются в журнал транзакций. Каждый Put имеет набор флагов, установленных через WriteOptions, которые определяют, следует ли вставить Put в журнал транзакций. WriteOptions также может указать, будет ли вызов синхронизации отправлен в журнал транзакций до того, как Put будет закоммитен (commit).

Внутри RocksDB использует механизм пакетной фиксации для пакетных транзакций в журнале транзакций, чтобы он мог совершать несколько транзакций с использованием одного вызова синхронизации.

Отказоустойчивость

RocksDB использует контрольную сумму для обнаружения сбоев в хранении. Эти контрольные суммы предназначены для каждого блока (обычно от 4 до 128 КБ). Блок, однажды записанный на хранение, никогда не изменяется. RocksDB динамически обнаруживает аппаратную поддержку вычислений контрольной суммы и использует эту поддержку, когда она доступна.

Режим ReadOnly

База данных может быть открыта в режиме ReadOnly, в которой база данных гарантирует, что приложение не может ничего изменять в базе данных. Это приводит к значительному повышению производительности чтения из-за того, что сквозные пути кода полностью исключают блокировки.

Журналы отладки базы данных

RocksDB записывает подробные журналы в файл с именем LOG*. Они в основном используются для отладки и анализа работающей системы. Этот журнал может быть настроен для ведения с определенной периодичностью.

Сжатие данных

RocksDB поддерживает сжатие, zlib, bzip2, lz4 и lz4_hc. RocksDB может быть настроен для поддержки различных алгоритмов сжатия на разных уровнях данных. Как правило, 90% данных на уровне Lmax. Типичная установка может настроить без сжатия для уровней L0-L2, мгновенное сжатие для средних уровней и сжатие zlib для Lmax.

Журналы транзакций

RocksDB хранит транзакции в файле журнала для защиты от сбоев системы. При перезапуске он обрабатывает все транзакции, записанные в файле журнала. Файл журнала может быть настроен для хранения в каталоге, отличном от каталога, в котором хранятся файлы _sstfile_s. Это необходимо для тех случаев, когда вы захотите хранить все файлы данных в неустойчивом быстром хранении. В то же время вы можете защитить данных от потери, поставив все журналы транзакций на более медленное, но постоянное хранилище.

Полное резервное копирование, инкрементное резервное копирование и репликация

RocksDB поддерживает полную резервную копию и инкрементное резервное копирование. RocksDB - это механизм базы данных LSM, поэтому после создания файлы данных никогда не перезаписываются, и это упрощает извлечение списка имен файлов, которые соответствуют мгновенному снимку базы данных в момент времени. API DisableFileDeletions ("ОтключитьУдалениеФайлов") инструктирует RocksDB не удалять файлы данных. Сжатие будет продолжаться, но файлы, которые не нужны базе данных, не будут удалены. Приложение резервного копирования может затем вызвать API GetLiveFiles/GetSortedWalFiles ("ПолучитьЖивыеФайлы/ПолучитьОсоритрованныеФайлы"), чтобы получить список живых файлов в базе данных и скопировать их в место резервного копирования. После завершения резервного копирования приложение может вызывать EnableFileDeletions("ВключитьУдалениеФайлов"); база данных теперь может свободно избавиться от файлов, которые больше не нужны.

Инкрементальные резервные копии и репликация должны иметь возможность находить и привязывать все последние изменения к базе данных. API GetUpdatesSince позволяет приложению задерживать журнал транзакций RocksDB. Он может непрерывно извлекать транзакции из журнала транзакций RocksDB и применять их к удаленной реплике или удаленной резервной копии.

Система репликации обычно стремится связать каждый Put с некоторыми произвольными метаданными. Эти метаданные могут использоваться для обнаружения циклов в конвейере репликации. Он также может использоваться для временных и последовательных транзакций. Для этой цели RocksDB поддерживает API под названием PutLogData, который приложение может использовать для аннотации каждого Put с метаданными. Эти метаданные хранятся только в журнале транзакций и не хранятся в файлах данных. Метаданные, вставленные через PutLogData, могут быть получены через API GetUpdatesSince.

Журналы транзакций RocksDB создаются в каталоге базы данных. Когда файл журнала больше не нужен, он перемещается в каталог архива. Причиной существования каталога архива является то, что поток репликации, который отстает, может потребоваться извлечь транзакции из файла журнала, который был в прошлом. API GetSortedWalFiles возвращает список всех файлов журнала транзакций.

Поддержка нескольких встроенных баз данных в одном процессе

Общим примером использования RocksDB является то, что приложения по своей сути разбивают свои данные на логические разделы или осколки. Этот метод обеспечивает балансировку нагрузки приложений и быстрое восстановление после сбоев. Это означает, что один серверный процесс должен иметь возможность одновременно работать с несколькими базами данных RocksDB. Это делается через объект окружения Env. Помимо прочего, пул потоков связан с Env. Если приложения хотят совместно использовать общий пул потоков (для фоновых компиляций) среди нескольких экземпляров базы данных, тогда он должен использовать тот же объект Env для открытия этих баз данных.

Аналогично, несколько экземпляров базы данных могут совместно использовать один и тот же кеш-блок.

Кэш-память - сжатые и несжатые данные

RocksDB использует кеш LRU для блоков для чтения. Кэш блока разбивается на два отдельных кэша: первый кэширует несжатые блоки, а второй кэширует сжатые блоки в ОЗУ. Если сконфигурирован кеш сжатого блока, то база данных избегает кэширования данных в буферах ОС.

Кэш таблицы

Table Cache - это конструкция, которая кэширует открытые дескрипторы файлов. Эти файловые дескрипторы предназначены для sst-файлов. Приложение может указать максимальный размер кэша таблиц.

Алгоритмы внешнего сжатия

Производительность базы данных LSM в значительной степени зависит от алгоритма уплотнения и его реализации. RocksDB имеет два поддерживаемых алгоритма сжатия: LevelStyle и UniversalStyle. RocksDB имеет соответствующие перехваты для отключения встроенного алгоритма уплотнения и имеет API, позволяющие приложениям работать с собственными алгоритмами уплотнения.

Options.disable_auto_compaction, если установлено, отключает собственный алгоритм уплотнения. API GetLiveFilesMetaData позволяет внешнему компоненту просматривать каждый файл данных в базе данных и решать, какие файлы данных объединяться и сжиматься. API DeleteFile позволяет приложениям удалять файлы данных, которые считаются устаревшими.

Неблокирующий доступ к базе данных

Существуют определенные приложения, которые архивируются таким образом, что они хотели бы получать данные из базы данных только в том случае, если вызов поиска данных не блокируется, то есть вызов поиска данных не должен считывать данные из хранилища. RocksDB кэширует часть базы данных в кэше блоков, и эти приложения хотели бы получить данные только в том случае, если они найдены в этом блочном кеше. Если этот вызов не находит данные в кеш-блоке, RocksDB возвращает соответствующий код ошибки в приложение. Затем приложение может планировать обычную операцию Get/Next, понимая тот факт, что этот запрос на получение данных может потенциально блокировать IO из хранилища (возможно, в другом контексте потока).

Резервная база данных

Одна функция, реализованная с использованием интерфейса StackableDB, - это BackupableDB, что делает резервную копию RocksDB простой.

Memtables (таблицы памяти)

Подключаемые Memtables

По умолчанию использование memtable для RocksDB является skiplist. Skiplist - это сортированный набор, который является необходимой конструкцией, когда рабочая нагрузка чередует записи с помощью сканирования по диапазону. Однако некоторые приложения не чередуют операции записи и сканирования, а некоторые приложения вообще не выполняют сканирование диапазонов. Для этих приложений сортированный набор может не обеспечивать оптимальную производительность. По этой причине RocksDB поддерживает подключаемый API, который позволяет приложению предоставлять свою собственную реализацию memtable. Три memtables являются частью библиотеки: библиотека памяти скипистов, векторная таблица заметок и префикс-хэш-память. Для массовых загрузок данных в базу данных подходит векторная таблица. Каждая запись вставляет новый элемент в конец вектора; когда пришло время сбросить память в память, элементы в векторе сортируются и записываются в файл в L0. Префикс-хэш-memtable позволяет эффективно обрабатывать get, puts и scan-in-key-prefix.

Конвейерная лента

RocksDB поддерживает настройку произвольного количества memtables для базы данных. Когда память заполнена, она становится неизменной памятью, а фоновый поток начинает промывать содержимое для хранения. Между тем, новые записи продолжают накапливаться в недавно выделенный memtable. Если вновь назначенный memtable заполняется до его предела, он также преобразуется в неизменяемую табличку с памятью и вставляется в поточный конвейер. Фоновый поток продолжает стирать все конвейерные неизменяемые memtables для хранения. Эта конвейерная обработка увеличивает пропускную способность записи RocksDB, особенно когда она работает на медленных устройствах хранения.

Уплотнение в Memtable

Когда память сбрасывается на хранение, процесс inline-уплотнение удаляет повторяющиеся записи из выходного потока. Аналогично, если предыдущий Put спрятан более поздним Delete, то Put не записывается в выходной файл вообще. Эта функция значительно уменьшает размер данных при хранении и усиление записи. Это важная функция, когда RocksDB используется как очередь-производитель-потребитель, особенно когда время жизни элемента в очереди очень короткое.

Оператор слияния

RocksDB изначально поддерживает три типа записей: Put, Delete и Merge. Когда процесс уплотнения встречает запись Merge, он вызывает указанный в приложении метод, называемый Оператором слияния. Слияние может объединять несколько записей Put и Merge в один. Эта мощная функция позволяет приложениям, которые обычно делают чтение-изменение-запись, чтобы избежать чтения в целом. Он позволяет приложению записывать операции как запись слияния, а процесс уплотнения RocksDB применяет эти операции к исходному значению.


Примеры применения RocksDB

В качестве внедряемой базы данных RocksDB может использоваться как механизм хранения в рамках более крупной системы управления базами данных (СУБД). Например, CockroachDB использует RocksDB в качестве механизма хранения.

Следующие проекты были созданы, чтобы заменить или предложить альтернативные системы хранения для уже существующим системам баз данных с исползованием RocksDB:[Источник 1]

  • MongoDB. Проект MongoRocks предоставляет модуль хранения для MongoDB, где в качестве механизма храния выступает RocksDB. Связанная программа - Rocks Strata, инструмент, написанный на Go, который позволяет управлять инкрементными резервными копиями MongoDB, когда RocksDB используется в качестве механизма хранения.
  • MySQL. Проект MyRocks создает новый механизм хранения на основе RocksDB для MySQL. Подробные сведения о MyRocks были представлены в Percona Live 2016.
  • SSDB. Проект ssdb-rocks использует RocksDB в качестве механизма хранения базы данных NoSQL SSDB.


Примеры установки и использования

Установка и проверка

Все действия подробно описаны в титрах на видео:

Пример использования

Далее представлен код простого приложения, использующего RocksDB для записи, хранения и чтения информации:

#include <cstdio>
#include <string>
#include <iostream>

#include "rocksdb/db.h"
#include "rocksdb/slice.h"
#include "rocksdb/options.h"

using namespace rocksdb;

// Путь к файлу БД
std::string kDBPath = "/tmp/rocksdb_simple_example1";

int main() {
    DB* db;     // переменная для БД
    Options options;    // переменная для опций
    options.create_if_missing = true;     // "создать БД, если не существует"

    DB::Open(options, kDBPath, &db);     // открываем/создаем БД
    
    // Записываем три разных значения в БД
    db->Put(WriteOptions(), "key1", "Hello! I'm the 1st value!");
    db->Put(WriteOptions(), "key2", "Hi! I'm the 2nd value!");
    db->Put(WriteOptions(), "key3", "Salud! I'm the 3rd value!");

    // Считываем ранее записанные значения из БД и выводим их в консоль
    std::string value1;
    std::string value2;
    std::string value3;
    db->Get(ReadOptions(), "key1", &value1);
    db->Get(ReadOptions(), "key2", &value2);
    db->Get(ReadOptions(), "key3", &value3);
    std::cout « "In key1 was: " « value1 « std::endl;
    std::cout « "In key2 was: " « value2 « std::endl;
    std::cout « "In key3 was: " « value3 « std::endl;

    delete db;

    return 0;
}

Собрав программу запускаем ее из консоли:

./new_program
In key1 was: Hello! I'm the 1st value!
In key2 was: Hi! I'm the 2nd value!
In key3 was: Salud! I'm the 3rd value!

Больше примеров можно найти в папке Examples пакета RocksDB, расположенного в репозитории GitHub.

Cсылки

См. также

Источники

  1. 1,0 1,1 1,2 RocksDB. // Wikipedia. [2001—2017]. Дата обновления: 06.10.2017. URL: https://en.wikipedia.org/wiki/RocksDB#cite_note-15 (дата обращения: 08.10.2017).
  2. RocksDB. // Github. [2008—2017]. Дата обновления: 26.09.2017. URL: https://github.com/facebook/rocksdb/blob/master/USERS.md (дата обращения: 09.10.2017).
  3. RocksDB on Steroids. // I programmer. [2010—2017]. Дата обновления: 30.05.2015. URL: http://www.i-programmer.info/news/84-database/8542-rocksdb-on-steroids.html (дата обращения: 08.10.2017).
  4. 4,0 4,1 4,2 4,3 RocksDB Basics. // Github. [2008—2017]. Дата обновления: 30.06.2017. URL: https://github.com/facebook/rocksdb/wiki/RocksDB-Basics (дата обращения: 08.10.2017).