Pull to refresh
VK
Building the Internet

Использование опыта тестирования реляционной СУБД для технологии NoSQL

Reading time 5 min
Views 10K
Tarantool — это открытое, высокопроизводительное хранилище данных. Такие характеристики системы, как простота и производительность, во многом определяют область её применимости. На шкале решений для хранения данных Tarantool находится где-то посередине между традиционными реляционными системами, такими как MySQL, и решениями для кэширования данных, такими как memcached. В основе системы лежит персистентное хранилище данных, полностью отображённое в оперативную память, и высокопроизводительные индексы для доступа к данным на основе хэшей и бинарных деревьев.

В мои первые месяцы работы над Tarantool я попытался создать инструментарий тестирования, похожий на тот, что был в моём предыдущем проекте с открытым исходным кодом — MySQL.

Т.к. такие инструменты как mysql-test-run, mysqltest, pushbuild малоизвестны за пределами экосистемы MySQL, я опишу то, что удалось создать, в нескольких блог-постах, каждый будет посвящен отдельному компоненту.

Если кратко, в современных проектах с открытым исходным кодом применяется набор инструментов, которые позволяют вести разработку «цивилизованно». Некоторые проекты используют только часть инструментария, но автоматизация полного цикла разработки, на мой взгляд, позволяет добиться наилучших результатов.

Речь идёт о следующих компонентах автоматизации:

— автоматизированном регрессионном тестировании,
— инструментарии для функционального и юнит- тестирования,
— автоматическом непрерывном интеграционном тестировании,
— автоматическом создании пакетов и дистрибутивов для инсталляции продукта.

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

Должен признать, что когда я начал работать над задачей автоматизации, то не до конца знал, с чем придётся столкнуться.

Tarantool — это key/value хранилище, которое может быть распределённым, я же подходил к задаче, уделяя максимальное внимание вопросам функционального регрессионного тестирования, то есть так, как это было сделано в MySQL.

Моё изначальное представление о NoSQL заключалось в том, что это просто более производительное хранилище, которое, однако, предоставляет лишь часть функционала полноценной СУБД.
Я был не совсем прав.

Функциональное тестирование Tarantool

Tarantool предоставляет своим клиентам простой бинарный протокол, поддерживающий базовый набор команд для работы с данными — GET, PUT, SET, DELETE.

Административные команды, такие как 'SAVE SNAPSHOT', 'SHOW STAT', посылаются в текстовом видена отдельный административный порт.

Отдельный порт для администрации необходим хотя бы потому, что в настоящий момент Tarantool не поддерживает какой-либо схемы авторизации.

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

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

Также было важно иметь возможность создавать в новой среде тестовые сценарии для всех найденных ошибок.

Конечно же, для экс-SQL программиста SQL выглядел очень привлекательно. В конце концов, для SQL хотя бы существует стандарт, тогда как «языки» современных NoSQL систем не имеют даже общего подмножества.

Итак, SQL был выбран в качестве языка для написания тестов. Выражаясь терминами SQL, Tarantool предоставляет 4 оператора работы с данными: INSERT, SELECT, UPDATE, DELETE.

Конечно же, грамматика SQL существенно богаче, чем функциональность Tarantool'а, но это, по-моему мнению, было приемлемо. Не слишком приятным сюрпризом оказалось скорее то, что часть функционала key/value хранилища в терминах SQL выразить невозможно.

Прежде всего, Tarantool оперирует не реляциями (множествами кортежей), как стандарт SQL, а парами ключ/значение. Множественных операций нет, и даже те операции, что работают с несколькими кортежами, по сути, объединяют несколько операций в пакет, а не работают со множеством в целом.
В терминах SQL это означает, что все операторы, манипулирующие данными, должны содержать WHERE клаузу и ссылку на уникальный ключ.

Далее, объекты базы Tarantool'а адресуются по индексу, а не по имени. Вместо SQL «таблиц» используются «пространства ключей» (namespaces), пронумерованные от 0 до N.

При этом в каждом пространстве, которое, по сути, представляет из себя множество разноразмерных кортежей, может существовать несколько индексов по различным полям или комбинациям полей.
Доступ к данным осуществляется по номеру индекса (вместо «индекса» также часто используют термин «ключ», однако я предпочитаю называть «ключом» индивидуальное значение, а не структуру данных), а не по номеру или имени столбца. Индекс №0 всегда считается первичным ключом.

ОК, SQL-грамматика Tarantool'а была сокращена, чтобы допускать только те идентификаторы, что заканчиваются цифрами.

Затем, т.к. пространство ключей не имеет размерности или фиксированной структуры, нет возможности работать лишь с частью кортежа — все операторы, за исключением разве что UPDATE, работают с кортежем целиком.

SELECT SQL, таким образом, может принимать только '*'.

Когда с сокращением грамматики было закончено, я обнаружил, что Tarantool позволяет INSERT, UPDATE и DELETE в качестве возвращаемого значения передать старое значение кортежа. Для этого в стандартном подмножестве SQL подходящей конструкции не нашлось.
Но в целом, я добился своей цели — создание микро-языка с простым, известным, легким для восприятия синтаксисом.

Т.к. в качестве языка программирования для инфраструктуры автоматизации я выбрал Python, для создания синтаксического анализатора SQL была использована библиотека YAPPS. О преимуществах и недостатках этого решения я писал отдельно в своём блоге.

Для того чтобы не пропускать административные команды через синтаксический анализатор, я просто добавил регулярное выражение, позволяющее отфильтровать их на раннем этапе от SQL запросов. Такие команды напрямую посылались на сервер через административный порт.

В итоге получился достаточно удобный клиент командной строки, на котором можно было легко писать тесты:

kostja@shmita:~/work/tarantool/test$ ./tarantool
tarantool> select * from t0 where k0 = 1
No match
tarantool> insert into t0 values (1, "My first tuple"
Insert OK, 1 row affected
tarantool> select * from t0 where k0 = 1
Found 1 tuple:
[1, 'My first tuple']
tarantool> save snapshot
---
ok
...
tarantool> show info
---
info:
version: "1.3.2-264-ga7bb270"
uptime: 73
pid: 22101
wal_writer_pid: 22102
lsn: 2
recovery_lag: 0.000
recovery_last_update: 0.000
status: primary
...


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

P.S. Да, Tarantool — продукт с открытым исходным кодом, и всё, что я сделал, уже доступно в основном дереве проекта на github.

Попробовать, как это работает, достаточно просто: склонировать исходный код, установить необходимые библиотеки (в основном речь идёт о библиотеках Python), скомпилировать (cmake. && make) запустить сервер (cd test && ./run --start-and-exit) и подключиться к нему с помощью нового клинета (cd test && ./tarantool).
Tags:
Hubs:
+32
Comments 17
Comments Comments 17

Articles

Information

Website
vk.com
Registered
Founded
Employees
5,001–10,000 employees
Location
Россия
Representative
Миша Берггрен