cockroachdb/

CockroachDB — это распределенная РСУБД, написанная на Go . Является представителем так называемых NewSQL баз данных , которые пытаются совместить в себе горизонтальную масштабируемость и высокую доступность NoSQL решений с интерфейсом (SQL) и строгостью (ACID) традиционных РСУБД. Помимо прочего, CockroachDB интересен тем, что реализует протокол PostgreSQL , что упрощает портирование на него существующих приложений. Давайте же попробуем поднять свой кластер CockroachDB и поработать с ним.

Предварительные шаги

Для экспериментов было создано три дроплета (VDS) в горячо любимом мной DigitalOcean . Приведенная ссылка является реферальной. Что она дает описано в FAQ .

Дроплеты получились следующими:

Droplet Name    Internal IP
————    ————
cockroach1      10.129.1.14
cockroach2      10.129.1.54
cockroach3      10.129.0.228

Между дроплетами был включен private networking. В качестве ОС была использована Ubuntu Linux 18.04 LTS.

На каждом из VDS выполняем следующие шаги. Качаем апдейты:

apt update
apt upgrade

Документация на CockroachDB рекомендует поставить NTP. Не вижу причин этого не сделать:

apt install ntp
ntpq -pn

Чтобы постоянно не сидеть под рутом, создаем пользователя с правом на sudo:

adduser eax
usermod -a -G sudo eax
mkdir / home / eax / .ssh
cp / root / .ssh / authorized_keys / home / eax / .ssh /
chown -R eax:eax / home / eax

Ребутаемся:

shutdown -r now

Теперь мы готовы перейти к следующему этапу.

Обратите внимание, что в рамках этой статьи не рассматривается настройка фаервола . Отмечу лишь, что CockroachDB использует всего два порта. На TCP-порту 8080 живет его веб-интерфейс. Через TCP-порт 26257 происходит общение между нодами, а также между нодами и клиентами по протоколу PostgreSQL.

Далее будет рассмотрена так называемая insecure конфигурация CockroachDB. Она предполагает, что весь ваш кластер работает в относительно доверенном окружении. Если вам нужна конфигурация с шифрованием, сертификатами и вот этой всей историей, обращайтесь к официальной документации .

Установка CockroachDB

На момент написания статьи последней стабильной версией CockroachDB была v19.2.2, на которой и проводились эксперименты. К моменту, когда вы будете читать эти строки, данная версия может потерять актуальность, и шаги по установке могут измениться. Самую свежую информацию вы всегда найдете на официальном сайте проекта .

Повторяем на всех трех машинах:

wget https: // binaries.cockroachdb.com / cockroach-v19.2.2.linux-amd64.tgz
tar -xvzf cockroach-v19.2.2.linux-amd64.tgz
sudo cp cockroach-v19.2.2.linux-amd64 / cockroach / usr / local / bin

sudo mkdir / var / lib / cockroach
sudo useradd cockroach
sudo chown cockroach / var / lib / cockroach

Берем шаблон сервиса отсюда . В нем --advertise-addr= нужно заменить на внутренний IP-адрес машины, а список --join= указать пустой для первой ноды, внутренний IP 1-ой ноды для второй ноды, и адреса 1-ой и 2-ой ноду для третьей. Результат сохраняем в /etc/systemd/system/cockroachdb.service.

Далее:

sudo systemctl enable cockroachdb
sudo systemctl start cockroachdb
sudo systemctl status cockroachdb

Получить доступ к веб-интерфейсу CockroachDB проще всего через ssh port forwarding:

LocalForward 8081 10.129.1.14:8080

Вот так он примерно выглядит (кликабельно, PNG 3072 x 1920, 573 Кб):

Веб-интерфейс CockroachDB

Из веб-интерфейса можно узнать текущее состояние нод, посмотреть статистику по таблицам, динамические графики по разным типам запросов (SELECT’ы, UPDATE’ы, …) и так далее.

Поздравляю, кластер настроен!

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

Для подключения к РСУБД выполняем команду:

cockroach sql —insecure

Далее говорим, например:

CREATE DATABASE phonebook;
CREATE USER IF NOT EXISTS phonebook;
GRANT ALL ON DATABASE phonebook TO phonebook;
SET DATABASE = phonebook;
CREATE TABLE phonebook ( id SERIAL PRIMARY KEY ,
name VARCHAR ( 64 ) , phone VARCHAR ( 64 ) ) ;
INSERT INTO phonebook ( name , phone ) VALUES ( ‘Alice’ , ‘123’ ) ;
INSERT INTO phonebook ( name , phone ) VALUES ( ‘Bob’ , ‘456’ ) ;
SELECT * FROM phonebook;
INSERT INTO phonebook ( name , phone )
SELECT ‘user_’ || n :: TEXT , ‘100’ || n :: TEXT
FROM generate_series ( 1 , 10000 ) AS n;
DROP TABLE phonebook;

В целом — все почти как в PostgreSQL. В том числе, есть команды l , d , q и ? . Команда c (подключение к базе данных) почему-то не реализована, но вместо нее есть SET DATABASE . Также, для тех, кто до этого работал с MySQL, поддерживаются команды SHOW DATABASES и SHOW TABLES . Автокомплит по именам таблиц и столбцов пока не реализован. Интересно, что в отличие от PostgreSQL, SERIAL PRIMARY KEY генерируются длинные и не последовательные:

root@:26257/phonebook> select * from phonebook;
id         | name  | phone
+———————+——-+——-+
528163249051893761 | Alice | 123
528163277677395969 | Bob   | 456
(2 rows)

После небольших доработок мне удалось запустить на CockroachDB пример микросерсиса на Go и pgx . В процессе было выявлено еще несколько отличий от PostgreSQL. Во-первых, в CockroachDB не реализован pg_advisory_lock() , на котором часто реализуется автоматическая миграция схемы базы данных. Решение заключается в том, чтобы выполнять миграцию в одну большую транзакцию (само собой разумеется, с ретраями).

Fun fact! Транзакции в CockroachDB всегда исполняются на уровне изоляции serializable. Еще вам может быть интересно узнать, что для хранения всех данных используется RocksDB .

Во-вторых, CockroachDB не понимает постгресовый синтаксис BEGIN ... [ NOT ] DEFERABLE :

root@:26257/phonebook> begin isolation level serializable
->   read write not deferable;
invalid syntax: statement ignored: at or near «not»: syntax error
DETAIL: source SQL:
begin isolation level serializable read write not deferable
^
HINT: try h BEGIN

При портировании / разработке приложения на CockroachDB необходимо убедиться, что оно не использует данный синтаксис.

Каких-то других проблем при портировании сервиса, вроде, не было. Помню, что мне пригодилась возможность включать и выключать логирование запросов:

SET CLUSTER SETTING sql.trace.log_statement_execute = true;
SET CLUSTER SETTING sql.trace.log_statement_execute = false;

Когда логирование включено, говорим:

tail -f / var / lib / cockroach / cockroach-data / logs / cockroach-sql-exec.log

В файле вы увидите все SQL-запросы к CockroachDB и сообщения об ошибках, если они возникают.

Разработка и тестирование

CockroachDB можно запустить локально в Docker таким образом:

docker run -d —name cockroach -p 5432 : 26257 -p 8080 : 8080
cockroachdb / cockroach:v19.2.3 start-single-node —insecure

Подключение к СУБД:

docker exec -it cockroach . / cockroach sql —insecure

Контейнеры могут быть использованы для тестирования приложения с помощью dockertest , как раньше мы это делали для PostgreSQL. Полный пример приложения вместе с тестами к нему вы найдете в этом репозитории на GitHub .

Заключение

В первом приближении выглядит так, как если бы все работало. Безусловно, перед тем, как выкатывать CockroachDB на прод, нужно пройти полный цикл тестирования приложения, с альфа- и бета-периодами, и вот этим вот всем. Но если вы не завязаны на какие-то PostgreSQL-специфичные возможности ( полнотекстовый поиск , PostGIS , самописные расширения ), а также уверены, что они вам не понадобятся, то особых проблем возникнуть не должно.

Следует однако иметь ввиду, что на момент написания этих строк транзакции в CockroachDB имели ряд известных ограничений . Также не внушает энтузиазма список issues на GitHub. Наконец, следует знать, что некоторые фичи CockroachDB отсутствуют в открытой версии и включены только в CockroachDB Enterprise и CockroachCloud . Среди таких фичей — снятие бэкапов.

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

EnglishRussianUkrainian