Налаштування CockroachDB для веб-додатку
CockroachDB — розподілена SQL-база, сумісна з PostgreSQL-протоколом. Горизонтальне масштабування без ручного шардування, автоматична реплікація даних та multi-region deployments — це те, чого не умієстандартний PostgreSQL без серйозних доповнень. Якщо додаток уже використовує Postgres-драйвери, перемикання на CockroachDB мінімально за кодом.
Коли CockroachDB має сенс
Глобальні додатки з користувачами в кількох регіонах, де потрібна низька latency скрізь. Системи, які неможна зупинити — CockroachDB переживає втрату вузлів без downtime. Масштабування запису горизонтально — стандартний Postgres цього не умією. Compliance-вимоги з зберіганням даних у конкретному регіоні.
Встановлення (однозвузловий для розробки)
wget -qO - https://binaries.cockroachdb.com/cockroach-latest.linux-amd64.tgz | tar xz
mv cockroach-*/cockroach /usr/local/bin/
# Запуск без SSL для dev
cockroach start-single-node --insecure --background \
--store=/var/lib/cockroachdb \
--listen-addr=localhost:26257 \
--http-addr=localhost:8080 \
--log-dir=/var/log/cockroachdb
Створення бази:
cockroach sql --insecure
CREATE DATABASE myapp;
CREATE USER myapp WITH PASSWORD 'strong_password';
GRANT ALL ON DATABASE myapp TO myapp;
Production кластер (три вузла)
# На кожному вузлі — генерація сертифікатів
cockroach cert create-ca --certs-dir=/etc/cockroachdb/certs --ca-key=/etc/cockroachdb/certs/ca.key
cockroach cert create-node 10.0.0.1 localhost $(hostname) --certs-dir=/etc/cockroachdb/certs --ca-key=/etc/cockroachdb/certs/ca.key
cockroach cert create-client root --certs-dir=/etc/cockroachdb/certs --ca-key=/etc/cockroachdb/certs/ca.key
# Запуск вузла 1
cockroach start \
--certs-dir=/etc/cockroachdb/certs \
--advertise-addr=10.0.0.1 \
--join=10.0.0.1,10.0.0.2,10.0.0.3 \
--store=/var/lib/cockroachdb \
--background
# Після запуску всіх вузлів — ініціалізація кластера
cockroach init --certs-dir=/etc/cockroachdb/certs --host=10.0.0.1
Схема та міграції
Синтаксис практично ідентичний PostgreSQL:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email STRING NOT NULL UNIQUE,
name STRING NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
status STRING NOT NULL DEFAULT 'pending',
total DECIMAL(10,2) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
INDEX idx_orders_user (user_id, created_at DESC),
INDEX idx_orders_status (status, created_at DESC)
);
CockroachDB використовує UUID як PK за умовчанням — послідовні цілі числа створюють hotspots на одному вузлі.
Multi-region налаштування
-- Увімкнути geo-розбиття
ALTER DATABASE myapp SET PRIMARY REGION 'eu-central-1';
ALTER DATABASE myapp ADD REGION 'us-east-1';
ALTER DATABASE myapp ADD REGION 'ap-southeast-1';
-- Таблиця користувачів з регіональною прив'язкою
ALTER TABLE users SET LOCALITY REGIONAL BY ROW;
-- Після цього кожен рядок зберігається ближче до користувача
-- crdb_region визначає найближчий регіон
Підключення з Node.js
CockroachDB працює з будь-яким PostgreSQL-драйвером:
import { Pool } from 'pg'
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
// DATABASE_URL = postgresql://myapp:[email protected]:26257/myapp?sslmode=require
max: 25,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 5000,
})
// CockroachDB рекомендує retry логіку для серіалізованих транзакцій
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn()
} catch (err: any) {
// 40001 — serialization failure (транзакція потребує повтору)
if (err.code === '40001' && attempt < maxRetries - 1) {
const delay = Math.min(100 * Math.pow(2, attempt), 2000)
await new Promise(r => setTimeout(r, delay + Math.random() * 100))
continue
}
throw err
}
}
throw new Error('max retries exceeded')
}
// Транзакція з повторами
async function transferFunds(fromId: string, toId: string, amount: number) {
return withRetry(async () => {
const client = await pool.connect()
try {
await client.query('BEGIN')
const { rows: [from] } = await client.query(
'SELECT balance FROM accounts WHERE id = $1 FOR UPDATE', [fromId]
)
if (from.balance < amount) throw new Error('insufficient funds')
await client.query(
'UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, fromId]
)
await client.query(
'UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, toId]
)
await client.query('COMMIT')
} catch (e) {
await client.query('ROLLBACK')
throw e
} finally {
client.release()
}
})
}
Моніторинг через вбудований UI
# DB Console доступна на порту 8080
# Ключові розділи:
# - Statements: топ запитів за часом виконання
# - Network Latency: latency між вузлами
# - Replication: статус реплікації ренджів
# CLI моніторинг
cockroach node status --certs-dir=/etc/cockroachdb/certs --host=10.0.0.1
cockroach debug zip debug.zip --certs-dir=/etc/cockroachdb/certs --host=10.0.0.1
Бэкапи
-- Повний бэкап у S3
BACKUP INTO 's3://my-bucket/cockroachdb-backups?AWS_ACCESS_KEY_ID=...&AWS_SECRET_ACCESS_KEY=...'
AS OF SYSTEM TIME '-10s';
-- Інкрементальний
BACKUP INTO LATEST IN 's3://my-bucket/cockroachdb-backups?...';
-- Розписання
CREATE SCHEDULE daily_backup
FOR BACKUP INTO 's3://my-bucket/cockroachdb-backups?...'
RECURRING '@daily'
FULL BACKUP ALWAYS;
Терміни
Налаштування трьохвузлового кластера в одному регіоні з налаштуванням моніторингу: 2–3 дні. Конфігурація multi-region з geo-розбиттям: 3–5 днів. Міграція з PostgreSQL (схема, дані, додаток, тестування під навантаженням): 1–2 тижні.







