Движки базы данных
Движок базы данных представляет собой набор очень низкоуровневых процессов, которые фактически хранят и получают значения в кортежах. Tarantool предлагает два движка базы данных на выбор:
Чтобы указать, что следует использовать именно vinyl, необходимо при создании спейса добавить оператор engine = 'vinyl', например:
space = box.schema.space.create('name', {engine='vinyl'})
Как правило, in-memory движок быстрее (каждый запрос обычно выполняется меньше, чем за 1 мс), но если база данных больше объема доступной памяти, а добавление дополнительной памяти не представляется возможным, рекомендуется использовать дисковый движок vinyl.
| Характеристика | memtx | vinyl |
|---|---|---|
| Поддерживаемый тип индекса | TREE, HASH, RTREE или BITSET | TREE |
| Временные спейсы | Поддерживается | Не поддерживается |
| функция random() | Поддерживается | Не поддерживается |
| функция alter() | Поддерживается | Поддерживается с версии 1.10.2 (первичный индекс изменять нельзя) |
| функция len() | Возвращает количество кортежей в спейсе | Возвращает максимальное примерное количество кортежей в спейсе |
| функция count() | Занимает одинаковые периоды времени | Занимает различное количество времени в зависимости от состояния БД |
| функция delete() | Возвращает удаленный кортеж, если есть таковой | Всегда возвращает nil |
| передача управления | Does not yield on the select requests unless the transaction is committed to WAL | Передает управление на запросах выборки или аналогичных: get() или pairs() |
Кэширование
Многие привыкли считать кэширование панацеей от всех проблем с производительностью: «В любой непонятной ситуации добавляй кэш». В vinyl’е мы смотрим на кэш скорее как на средство снижения общей нагрузки на диск, и, как следствие, получения более предсказуемого времени ответов на запросы, которые не попали в кэш. В vinyl’е реализован уникальный для транзакционных систем вид кэша под названием «кэш диапазона кортежей» (range tuple cache). В отличие от RocksDB, например, или MySQL, этот кэш хранит не страницы, а уже готовые диапазоны значений индекса, после их чтения с диска и слияния всех уровней. Это позволяет использовать кэш для запросов как по одному ключу, так и по диапазону ключей. Поскольку в кэше хранятся только горячие данные, а не, скажем, страницы (в странице может быть востребована лишь часть данных), оперативная память используется наиболее оптимально. Размер кэша задается в параметре vinyl_cache.
Архитектура Tarantool-хранилища позволяет производить обновление только путем присоединения новых записей: сами файлы никогда не перезаписываются. Сборщик мусора Tarantool’а удаляет старые файлы после определенной контрольной точки. В настройках демона создания контрольных точек можно отложить или запретить работу сборщика мусора. Резервное копирование может проводиться в любое время с минимальной затратой ресурсов.
Для резервного копирования в определенных ситуациях используются две функции:
Горячее резервирование (memtx)
Это особый случай, когда все таблицы хранятся в памяти.
Последний созданный Tarantool’ом файл-снимок является резервной копией всей базы данных; а WAL-файлы, созданные следом за последним файлом-снимком, являются инкрементными копиями. Поэтому процедура резервирования сводится к копированию последнего файла-снимка и следующих за ним WAL-файлов.
tar создайте (зачастую сжатую) копию последнего .snap-файла и следующих за ним .xlog-файлов из директорий memtx_dir и wal_dir.В дальнейшем базу данных можно восстановить, разархивировав содержимое .tar-файла в директории memtx_dir и wal_dir.
Горячее резервирование (vinyl/memtx)
Vinyl хранит свои файлы в vinyl_dir и создает для каждого спейса в базе данных отдельную поддиректорию. Создание дампов и слияние – это процессы, которые могут лишь добавлять записи, поэтому в результате создаются новые файлы. Сборщик мусора Tarantool’а может удалять старые файлы после каждой контрольной точки.
Для создания смешанной резервной копии:
box.backup.stop().Непрерывное удаленное резервирование
Репликация используется не только для резервирования, но и для выравнивания нагрузки.
Поэтому процесс создания резервной копии сводится к обновлению (при необходимости) одной из реплик с последующим холодным резервированием. Так как все остальные реплики продолжают функционировать, с точки зрения конечного пользователя, этот процесс не является холодным резервированием. Такое резервирование можно выполнять регулярно с помощью планировщика cron или файбера Tarantool’а.
Непрерывное резервирование
По ходу работы системы необходимо сохранять записи об изменениях, внесенных со времени последнего холодного резервирования.
Для этого нужна специальная утилита для копирования файлов (например, rsync), которая позволит удаленно и на постоянной основе копировать только изменившиеся части WAL-файла, а не весь файл целиком.
Можно взять и обычную утилиту для копирования целых файлов, но тогда придется создавать файлы-снимки и WAL-файлы на каждое изменение, чтобы нужно было копировать только новые файлы.
Важным параметром для записи в WAL является wal_mode. Если запись в WAL отключена или задана запись с задержкой, но этот фактор не так важен. Если же запись в WAL производится при каждом запросе на изменение данных, то при каждом таком запросе приходится ждать, пока отработает обращение к более медленному диску, и данный фактор становится важнее всех остальных.