RethinkDB появилась как база документов с необычной идеей: клиент может подписаться на изменения запроса и получать обновления сразу, без опроса. Для дашбордов, чатов и домашней телеметрии это удобнее, чем периодически дергать SELECT. Сегодня проект развивается сообществом, но сама модель остаётся интересной и вполне рабочей.

Чем RethinkDB отличается

Это документная база с языком запросов ReQL. Запросы собираются из цепочки методов и выполняются на сервере, а не на клиенте. Данные хранятся в JSON-документах, схема не фиксирована, но первичный ключ и индексы задаются явно. Встроенный веб-интерфейс на порту 8080 показывает таблицы, запросы и состояние кластера.

Главная особенность — changefeed. Вместо polling клиент открывает поток и получает вставки, обновления и удаления по мере их появления. Это снимает нагрузку с базы и уменьшает задержку. Поток можно фильтровать, объединять с другими таблицами и ограничивать по времени.

  • Горизонтальное шардирование и репликация на уровне таблиц.
  • Атомарные операции с одним документом.
  • Геопространственные индексы и операции.
  • HTTP-интерфейс администратора.

Запуск в контейнере

Самый предсказуемый способ попробовать — Docker. Том сохраняет данные между перезапусками, а порты публикуются только на localhost: драйверный порт 28015 не должен смотреть в интернет. Порт 29015 нужен для связи узлов кластера и на одиночной машине не требуется.

docker volume create rethink_data
docker run -d --name rethinkdb \
  --restart unless-stopped \
  -p 127.0.0.1:8080:8080 \
  -p 127.0.0.1:28015:28015 \
  -v rethink_data:/data \
  rethinkdb:latest

После старта откройте http://127.0.0.1:8080 и убедитесь, что узел виден в разделе Servers. Если страница не открывается, смотрите docker logs: чаще всего не хватает прав на том или занят порт.

Подключение и первые запросы

Официальный драйвер для Python ставится в виртуальное окружение. Подключение указывает хост, порт и базу; для учебного примера достаточно localhost. На самых новых версиях Python драйвер иногда требует сборки из исходников, поэтому смотрите вывод pip при установке.

python3 -m venv .venv
. .venv/bin/activate
pip install rethinkdb
python -c "from rethinkdb import r; print(r.db_list().run(r.connect(host='127.0.0.1')))"
from rethinkdb import r

conn = r.connect(host="127.0.0.1", port=28015)
r.db_create("home").run(conn)
conn.use("home")
r.table_create("readings", primary_key="id").run(conn)

r.table("readings").insert({
    "id": "kitchen-2026-11-06T12:00",
    "sensor": "kitchen",
    "temperature": 21.4,
    "ts": r.now()
}).run(conn)

Идентификатор лучше формировать самому: это упрощает повторную запись и делает операцию идемпотентной. Поле ts заполняется серверным временем, поэтому часы клиента не влияют на сортировку.

Живые запросы

Changefeed открывается один раз и живёт до закрытия соединения. В примере отбрасываются служебные события состояния, чтобы обрабатывать только реальные изменения. Флаг squash объединяет частые правки одного документа, снижая поток.

feed = r.table("readings").changes(
    squash=True, include_states=True
).run(conn)

for change in feed:
    if change["type"] == "state":
        continue
    print(change["new_val"])

Каждый поток занимает соединение и очередь на сервере. Не открывайте changefeed на каждый HTTP-запрос: держите один фоновый процесс и рассылайте данные подписчикам через WebSocket или SSE.

Индексы и выборки

Фильтр по полю без индекса читает всю таблицу. Для временных рядов создайте индекс по ts и используйте between — он работает по диапазону и не требует полного перебора. После создания индекса дождитесь его готовности.

r.table("readings").index_create("ts").run(conn)
r.table("readings").index_wait("ts").run(conn)

rows = (r.table("readings")
        .between(r.time(2026, 11, 6, "Z"), r.time(2026, 11, 7, "Z"), index="ts")
        .order_by(index="ts")
        .limit(100)
        .run(conn))

Составной индекс задаётся списком полей и ускоряет выборки по паре «устройство + время». Для агрегатов используйте group и avg прямо в запросе: сервер посчитает результат без выгрузки всех документов.

(r.table("readings")
 .group("sensor")
 .avg("temperature")
 .run(conn))

Кластер и обслуживание

Таблицу можно разбить на шарды и держать несколько реплик. Для домашнего стенда это избыточно, но для нескольких узлов полезно: при потере машины данные останутся доступны. Состояние смотрите через служебные таблицы, а не только через веб-интерфейс.

r.db("rethinkdb").table("server_status").run(conn)
r.db("rethinkdb").table("current_issues").run(conn)
r.table("readings").index_list().run(conn)

Резервная копия делается утилитой rethinkdb внутри контейнера. Дамп включает данные и конфигурацию таблиц; restore возвращает их в чистый кластер. Проверяйте восстановление на тестовом узле, иначе копия останется теоретической.

docker exec rethinkdb rethinkdb dump -c 127.0.0.1:28015 -f /data/backup.tar.gz
docker cp rethinkdb:/data/backup.tar.gz ./backup.tar.gz
docker exec rethinkdb rethinkdb restore -c 127.0.0.1:28015 /data/backup.tar.gz

Ограничения и диагностика

RethinkDB не заменяет реляционную базу: межтабличных транзакций и привычного SQL здесь нет, а джойны ограничены eqJoin, innerJoin и outerJoin. Сложную аналитику лучше выгружать в специализированное хранилище. Также помните, что база не предназначена для прямого доступа из интернета: закройте порты файрволом.

docker logs --tail 100 rethinkdb
curl -s http://127.0.0.1:8080 | head -n 5
docker stats --no-stream rethinkdb
df -h /var/lib/docker

Если запрос «висит», проверьте, не открыт ли changefeed без читателя: буфер заполняется и сервер начинает тормозить. Если диск заполнен, смотрите docker system df и старые тома. Для наблюдения за задержкой добавьте в дашборд график по числу документов и времени ответа: рост без нагрузки обычно означает нехватку индекса, а не проблему с сетью.

Чек-лист

  • Порты 28015 и 8080 закрыты снаружи.
  • Индексы созданы под реальные запросы.
  • Changefeed один на приложение, а не на запрос.
  • Дампы снимаются по расписанию и проверяются.
  • Для одного узла не включайте лишние реплики.
  • Перед обновлением образа сделан дамп.

Итог

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

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте