ActorDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 16:06, 23 января 2019.
Open book.svg Авторство
С. А. Гончаров
Согласовано: 23.01.2019
ActorDB
Actor.JPG
Разработчики: Biokoda
Постоянный выпуск: 0.10.25
Состояние разработки: активное
Операционная система: Кросс-платформенное
Локализация: Английский язык
Тип ПО: База данных
Веб-сайт actordb.com

ActorDB – распределённая база данных SQL, с масштабируемым Key-Value хранилищем, сохраняющая возможности реляционных БД. [1] ActorDB идеально подходит как серверная база данных для приложений. Например, крупные почтовые службы ( такие как: Dropbox, Evernote и т. д.) требуют наличия хранилища для пользовательских данных на стороне сервера, но подавляющее большинство запросов находятся в пределах определенного пользователя. У многих пользователей база данных на стороне сервера может быть очень большой. Используя ActorDB, вы можете хранить полную реляционную базу данных для каждого пользователя и не прибегать к масштабированию, которое заставит вас забыть обо всёх хороших качествах реляционных БД [Источник 1].

Обзор платформы

Традиционные БД SQL монолитны. Они хорошо работают на одном сервере, но им они и ограничены. Конечно, они могут использовать концепции мастер/слейв или мастер/мастер, но на каждом сервере всё равно должен быть весь набор данных. Традиционные базы данных SQL требуют чрезвычайно сложных и обширных механизмов блокировки транзакций, даже если набор данных небольшой. Когда набор данных становится слишком велик или загрузка запроса - слишком высокой, появляется необходимость в существенных изменениях использования БД: данные необходимо денормализовать[2], сложность кода возрастает в разы. В конце концов, приходится искать пути в обход базы данных: резко возрастает сложность всего, что связано с использованием БД.[3]

ActorDB позволяет начать с БД, которая полностью нормализована в блоке actor и масштибируется горизонтально на столько серверов, сколько необходимо. Никаких единых точек отказа или глобальных блокировок. Транзакции влияют только на своих участников [Источник 2]. ActorDB - это база данных, которая не скрывает от вас фрагментацию внутри БД. Это делает работу наглядной, поэтому вы можете хранить полностью реляционные фрагменты для 99% запросов к базе данных.

Возможности

ActorDB это:

  • Распределенная реляционная база данных SQL;
  • Целостная;
  • Массово-параллельная архитектура;
  • Отсутствие единой точки отказа;
  • Отсутствие глобальных блокировок чтения или записи;
  • Горизонтальное масштабирование до сотен узлов и петабайта данных;
  • Возможность подключения через протокол MySQL и Thrift.

Это достигается с помощью:

  • Использование распределённого Raft-алгоритма[4];
  • Протестированный на практике и стабильный механизм СУБД SQL;
  • Разделение набора данных на небольшие независимые части, основанный на «модели актора»[5].

Key/Value хранилища обычно жертвуют целостностью и обширностью запросов ради достижения масштабируемости. Хранилища документов имеют более богатые возможности запросов, но не так хорошо масштабируемы. ActorDB является реляционной базой данных SQL, но она организует данные по-другому. Она требует немного другого типа мышления, но при этом является гораздо более мощной, чем хранилища Key/Value и документов.

Преимущества

Преимуществами ActorDB являются:

  • Полная горизонтальная масштабируемость. Все узлы эквивалентны, и вы можете иметь столько узлов, сколько вам нужно;
  • Полнофункциональная база данных ACID[6];
  • Подходит для очень объёмных наборов данных, для большого количества участников и серверов;
  • Никаких специальных драйверов не требуется. Используйте драйвер mysql выбранного вами языка;
  • Простота настройки и администрирования;
  • Нет глобальных блокировок. Только субъекты (один или многие), участвующие в транзакции, блокируются во время записи;
  • Использует стабильные надежные механизмы SQL и хранения: SQLite поверх LMDB;
  • Наследует функции SQLite, такие как поддержка JSON и общие выражения таблиц;

Принцип работы

ActorDB разбита на кластеры[Источник 3] (в одном кластере 1,3,5 узлов, как показано на рисунке 1). Кластеров может быть столько, сколько необходимо. Сами акторы объединены в шарды. Логически шард представляет собой часть hash-пространства имен. Это особый тип актора, который содержит список обычных акторов. Шарды существуют внутри кластеров, также как и акторы.

Рисунок 1 – Примеры кластеров в ActorDB


Актор - это мини-версия полной реляционной базы данных SQL. Он имеет ведущий узел, который обрабатывает чтение и запись, имеет узлы-последователи на других серверах в кластере, которые получают записи от лидера. Реплики тиражируются с использованием распределенного согласованного протокола Raft. Если сервер отключен, один из последователей автоматически станет лидером для этого актора. Процесс записи будет функционировать, пока большинство серверов в кластере находятся в сети.

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

Синхронизация узлов

Глобальное состояние

ActorDB разработана таким образов, чтобы межсерверная синхронизация была минимальной. Это означает, что каждый сервер должен быть как можно более независимым, а глобальное состояние и смена этого глобального состояния должны быть сведены к минимуму.

Все в ActorDB является акторами, в том числе и глобальное состояние. Это специальный актор, который занимает до 7 узлов (в нескольких кластерах). Эти 7 узлов поддерживают согласованность[7], используя распределенный алгоритм Raft. Если ActorDB имеет более 7 узлов, остальные получают свое состояние периодическими пингами от текущего ведущего узла.

Глобальное состояние ActorDB это:

  • Список узлов (задаётся пользователем вручную);
  • Схема БД (задаётся пользователем вручную);
  • Список шардов и того, какой узел каким шардом владеет (вызвано изменением в списке узлов);
  • Список узлов, входящих в группу глобального состояния.

Акторы

Все запросы ActorDB всегда отправляются актору. Всё происходит по следующему алгоритму:

  1. Вычислить хеш от имени актора;
  2. Проверить хэш-таблицу шардов, чтобы найти, на каком узле находится актор;
  3. Отправить запрос на узел, который должен быть лидером в данный момент;
  4. Если данный узел не является лидером, запрос будет перенаправлен фактическому лидеру.

У ActorDB есть два разных механизма: SQLite для запуска SQL-запросов и LMDB для хранения. Механизм SQL использует страницы для хранения данных (модули объёмом 4096 байт). Эти страницы не хранятся в файлах SQLite, они хранятся внутри LMDB. Реализацию SQLite WAL заменена на авторскую, которая работает быстрее на отдельном акторе, а затем просто использует SQLite. В отличие от обычного режима WAL, больше нет необходимости в контрольных точках в дальнейшем. Как только страница занесена в хранилище, она будет оставаться там. Также она сжимается с использованием lz4.

В отличие от большинства других ДБ (особенно SQL), ActorDB не требует переноса контрольных точек из WAL в основной файл БД. Используя LMDB, мы можем хранить страницы в стиле append-only. Таким образом, контрольные точки заменяются очистками, которые освобождают место для дальнейшего использования.

Акторы реплицируются с использованием распределенного согласованного протокола Raft. Для работы Raft необходим журнал логов. Поскольку наши два двигателя подключены через модуль SQLite WAL, репликация Raft естественна. Каждая запись в базу данных добавляется к WAL. Для каждого добавления мы отправляем эти данные всему реплицируемому кластеру. Страницы просто вставляются в WAL на всех узлах. Это означает, что узел-лидер выполняет SQL, но узлы-последователи просто присоединяются к WAL.

Если сервер очень устарел или добавлен новый, ActorDB сначала отправит страницы базового актора на новый сервер, а затем отправит страницы WAL (если они есть).

Вы можете настроить сервер на использование нескольких независимых жестких дисков, и ActorDB будет балансировать акторов на всех. Это значительно улучшит пропускную способность, если процессор и сеть не будут переполнены.

Мультиакторные транзакции

Мультиакторные транзакции должны соответствовать требованиям ACID. Они выполняются менеджером транзакций. Менеджер сам по себе является актором. Он имеет имя и номер транзакции, который увеличивается для каждой транзакции.

Последовательность событий с точки зрения менеджера транзакций:

  1. Запустить транзакцию, записав номер и состояние (не подтвержденное) в таблицу транзакций исполнителя транзакционного менеджера;
  2. Проверить всех акторов транзакции на предмет возможности её выполнения;
  3. Все акторы успешно прошли проверку. Измените состояние в таблице транзакций для совершения транзакции;
  4. Сообщите всем задействованным акторам о совершении транзакции.

Последовательность событий с точки зрения акторов:

  1. Актор получает SQL с идентификатором транзакции, номером транзакции и менеджером транзакций узла.
  2. Хранить фактический оператор SQL с информацией о транзакции в таблице транзакций (не выполняя ее).
  3. Как только он будет сохранен, SQL будет выполнен. Если ошибки не было, вернуть подтверждение успеха.
  4. Актор ждет подтверждения или отмены от менеджера транзакций. Он также будет периодически проверять работу менеджера транзакций в случае утери узла, в котором он был запущен, или если сообщение подтверждения утеряно.
  5. Как только появилось сообщение подтверждения или отмены, он выполняет его и разблокирует.

Проблемные сценарии:

# Узел, в котором работает менеджер транзакций, прекратит работу перед совершением транзакции. Акторы будут проверять, в каком состоянии находится транзакция. Если оператор транзакционного агента возобновляется на другом узле и видит незафиксированную транзакцию, он отметит её как прерванную. Акторы, в свою очередь, также прекратят транзакцию.
#  Узел, в котором существует менеджер транзакций,прекратит работу после передачи транзакции в локальное состояние, но прежде чем информировать участников о том, что транзакция подтверждена. Акторы, проведя проверку, обнаружат подтвержденную транзакцию и совершат ее.
#  Узел, в котором существуют один или несколько акторов,прекратит работу после подтверждения того, что они могут выполнять транзакцию. Фактические операторы SQL хранятся в своих базах данных. В следующий раз, когда будут вызваны эти акторы, они заметят эту транзакцию.

Механизм SQL

ActorDB опирается на один из наиболее хорошо проверенных и стабильных фрагментов кода: SQLite

SQLite не является отдельной программой. Это программная библиотека, которая входит в состав ActorDB. Запуск многих или только одного актора на сервере не имеет значения. Глобальная блокировка SQLite не блокирует работу отдельного актора. ActorDB может легко обрабатывать тысячи запросов в секунду для одного актора.

  • Приложения Client / Server - ActorDB заботится о сетевом протоколе. Он наилучшим образом подходит для клиент- серверного сетевого приложения.
  • Сайты большого объема - ActorDB способна распространять нагрузку на столько серверов и экземпляров SQLite, сколько необходимо. Таким образом, она удобна для сайтов большого объема.
  • Большие наборы данных. До тех пор, пока у вас нет слишком большого набора данных внутри одного актора (несколько GB), а данные распространены среди нескольких акторов, ActorDB будет работать эффективно даже с петабайтами данных.
  • Высокий параллелизм - ActorDB использует массовый паралеллизм. Не на уровне отдельного актора, а во всей базе данных.

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

Прекрасным вариантом использования для ActorDB является приложение для синхронизации файлов (Dropbox, EmitCloud, ownCloud, ..). База данных для приложения синхронизации файлов должна хранить:

  • структуру каталога файлов для каждого пользователя;
  • журнал событий для каждого пользователя;
  • список файлов, загруженных пользователями

Схема:

-- У пользователей есть файлы и папки. Файлы всегда должны иметь родительскую папку. Все папки, кроме корневой папки, имеют родителей.
actor user
CREATE TABLE file (id PRIMARY KEY INTEGER, parent INTEGER NOT NULL, name TEXT NULL, fsid TEXT, FOREIGN KEY (parent) REFERENCES dir(id) ON UPDATE CASCADE)
CREATE TABLE dir (id PRIMERY KEY INTEGER, parent INTEGER, name TEXT NOT NULL, FOREIGN KEY (parent) REFERENCES dir(id) ON UPDATE CASCADE)

-- Распределенная файловая система является глобальной. Создайте kv-хранилище для хранения позиции файлов.
-- Для каждого файла нам также нужна таблица узлов, которые хранят этот файл.
actor filesystem kv
CREATE TABLE actors (id TEXT PRIMARY KEY, hash INTEGER, crc INTEGER NULL, mime TEXT NULL, size INTEGER NULL) WITHOUT ROWID
CREATE TABLE nodes (id TEXT, node TEXT NOT NULL, FOREIGN KEY(id) REFERENCES actors(id) ON DELETE CASCADE, PRIMARY KEY (id,node)) WITHOUT ROWID

Примечания

Источники

  1. ActorDB // GitHub. [2018]. Дата обновления: 01.10.2018. URL: https://github.com/biokoda/actordb/ (дата обращения:01.10.2018)
  2. About ActorDB // Документация ActorDB. [2018]. Дата обновления: 01.10.2018. URL: http://www.actordb.com/docs-about.html/ (дата обращения: 01.10.2018)
  3. How it works // ActorDB. [2018]. Дата обновления: 01.10.2018. URL:http://www.actordb.com/docs-howitworks.html#overview/ (дата обращения 01.10.2018)

Ссылки

  • ActorDB [Электронный ресурс]: Официальный сайт/ Дата обращения: 01.10.2018. Режим доступа: http://www.actordb.com/
  • GitHub [Электронный ресурс]: ActorDB/ Дата обращения: 01.10.2018. Режим доступа: https://github.com/biokoda/actordb/
  • Wikipedia [Электронный ресурс]:Actor model/ Дата обращения: 01.10.2018. Режим доступа: https://en.wikipedia.org/wiki/Actor_model/