Серверные технологии: что для чего

Семь систем, из которых собирают бэкенд. Для каждой — как она устроена, когда её брать и когда она только помешает.

Листайте стрелками ← →, свайпом или кнопками внизу. В схемах нажимайте кнопки и двигайте ползунки.

Как это выглядит вместе

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

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

PostgreSQL

Транзакция: всё или ничего

Реляционная база — источник правды для данных бизнеса. Её главное свойство — транзакции: несколько изменений применяются вместе или не применяются вовсе.


BEGIN;
UPDATE accounts SET balance = balance - 30
  WHERE name = 'Алиса';
UPDATE accounts SET balance = balance + 30
  WHERE name = 'Боб';
COMMIT;

Уроните сервер посреди перевода — с транзакцией и без. А если переводить, пока у Алисы не кончатся деньги, сработает ограничение CHECK (balance >= 0).

PostgreSQL

Индекс: найти строку, не читая всю таблицу

Без индекса запрос WHERE user_id = 42 перебирает каждую строку. B-дерево находит нужную за несколько чтений, даже среди миллиардов строк.


CREATE INDEX orders_user_idx ON orders (user_id);

EXPLAIN SELECT * FROM orders WHERE user_id = 42;
-- Index Scan using orders_user_idx on orders

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

PostgreSQL

Когда брать PostgreSQL

Подходит

  • Основные данные: пользователи, заказы, деньги — всё, где важна целостность.
  • Связанные сущности и сложные запросы с JOIN, фильтрами и сортировкой.
  • Изменения, которые должны примениться вместе: транзакции.
  • Когда не знаете, что выбрать. Postgres умеет JSON (jsonb), полнотекстовый поиск, геоданные (PostGIS) и простые очереди.

Не подходит

  • Аналитика по миллиардам строк на лету. Лучше ClickHouse
  • Файлы и большие бинарные данные. Лучше S3
  • Сотни тысяч событий в секунду, которые читают несколько систем. Лучше Kafka
  • Сотни тысяч чтений в секунду одних и тех же горячих данных. Поставьте перед ним Redis
Redis

Данные в памяти: ответ за доли миллисекунды

Redis хранит ключи и значения в оперативной памяти. Классическое применение — кэш перед базой: прочитали из Postgres один раз, а следующие запросы получают готовый ответ из памяти.


GET product:1             → (nil), промах
SELECT … FROM products    → 30 мс
SET product:1 "…" EX 8    → живёт 8 секунд
GET product:1             → попадание, 0,4 мс

Самое сложное в кэше — инвалидация. Поднимите цену кофе: пока ключ жив, пользователи видят старую цену. Включите удаление ключа при изменении — или терпите устаревшие данные до конца TTL.

Redis

Когда брать Redis

Подходит

  • Кэш перед медленной базой или внешним API.
  • Сессии, токены, одноразовые коды — всё, что должно само исчезнуть по TTL.
  • Счётчики и ограничение частоты запросов: INCR атомарен.
  • Рейтинги (sorted set), распределённые блокировки, pub/sub для уведомлений.

Не подходит

  • Единственное хранилище важных данных: сохранение на диск есть, но гарантии слабее, чем у базы. Лучше PostgreSQL
  • Данные, которые не помещаются в оперативную память.
  • Сложные запросы: нет JOIN и произвольных фильтров, только доступ по ключу.
  • Надёжная очередь задач с подтверждениями и повторами. Лучше RabbitMQ
RabbitMQ

Очередь задач с подтверждениями

Приложение не делает долгую работу само, а публикует сообщение. Брокер раскладывает его по очередям, воркеры забирают сообщения и подтверждают обработку (ack). После ack сообщение удаляется.


exchange "events" (topic):
  order.*      → очередь «склад»
  order.paid   → очередь «письма»
  user.signup  → очередь «письма»

Выключите воркер посреди обработки: сообщение без ack вернётся в очередь и достанется снова. Поэтому обработчик должен быть идемпотентным: повторная обработка не должна, например, дважды списать деньги.

RabbitMQ

Когда брать RabbitMQ

Подходит

  • Фоновые задачи: письма, генерация PDF, обработка картинок.
  • Каждое сообщение нужно гарантированно обработать: подтверждения, повторы, очередь для неудачных сообщений (dead letter).
  • Гибкая маршрутизация: одно событие попадает в разные очереди по ключу.
  • Сглаживание пиков: очередь копится, воркеры спокойно её разбирают.

Не подходит

  • Нужно перечитать историю: после ack сообщения больше нет. Лучше Kafka
  • Огромный поток событий для многих независимых читателей. Лучше Kafka
  • Пара фоновых задач в маленьком проекте: таблица в Postgres и FOR UPDATE SKIP LOCKED часто справляются. Хватит PostgreSQL
  • Клиент ждёт ответа прямо сейчас. Проще обычный HTTP-вызов
Kafka

Журнал событий, который можно перечитать

Kafka не раздаёт сообщения, а дописывает их в конец журнала — топика. Каждая группа потребителей сама помнит, до какого места дочитала (offset). Чтение ничего не удаляет: события хранятся заданное время (retention).

Топик делится на партиции — так Kafka масштабируется на миллионы событий в секунду. Порядок гарантирован только внутри партиции, поэтому события одного заказа отправляют с одним ключом.

Kafka

Когда брать Kafka

Подходит

  • Поток событий, который читают несколько независимых систем.
  • Историю нужно хранить и перечитывать: новый сервис прочтёт события с самого начала.
  • Очень большой поток: Kafka масштабируется добавлением партиций и брокеров.
  • Поток изменений из базы (CDC), сбор логов и метрик, event sourcing.

Не подходит

  • Очередь задач с повтором отдельных сообщений и приоритетами. Лучше RabbitMQ
  • Небольшой проект: Kafka — это кластер, который надо эксплуатировать.
  • Нужен общий порядок всех событий: он есть только внутри партиции.
  • Нужны запросы к данным: Kafka — журнал, а не база. Лучше PostgreSQL или ClickHouse

RabbitMQ или Kafka

Обе системы передают сообщения, но решают разные задачи. RabbitMQ — почтальон: доставил и забыл. Kafka — архив: записал, а читатели приходят сами.

RabbitMQKafka
МодельОчередь: каждое сообщение получает один потребительЖурнал: каждая группа читает все события
После чтенияУдаляется после ackХранится до истечения retention
Перечитать историюНельзяМожно: сдвинуть offset назад
Повтор одного сообщенияВстроен: nack, повторы, dead letterНет: только управлять offset самому
МаршрутизацияГибкая: exchange, ключи, шаблоныТопик и партиция по ключу
ПотокДесятки тысяч сообщений в секундуСотни тысяч и миллионы в секунду
Типичная задачаФоновые задачи и командыПоток событий между системами, аналитика
Elasticsearch

Поиск по словам, а не по подстроке

Поисковый движок строит обратный индекс: для каждого слова — список документов, где оно встречается. Слова приводятся к основе, поэтому «красные» находит «красная».

LIKE '%…%' в обычной базе ищет точную подстроку и читает всю таблицу. Elasticsearch находит слова в любом порядке и в любой форме и сортирует результаты по релевантности. В демо упрощённый стемминг; настоящий умеет больше, включая поиск с опечатками.

Elasticsearch

Когда брать Elasticsearch

Подходит

  • Полнотекстовый поиск: морфология, опечатки, синонимы, релевантность, подсветка.
  • Каталог с фильтрами и счётчиками по каждому фильтру (фасетами).
  • Поиск и анализ логов (стек ELK, OpenSearch).

Не подходит

  • Основная база: транзакций нет, данные копируются из основной базы. Источник правды — PostgreSQL
  • Простой поиск по небольшому каталогу. Хватит tsvector и pg_trgm в PostgreSQL
  • Частые обновления одних и тех же документов: каждое обновление — переиндексация.
ClickHouse

Хранить по колонкам, чтобы быстро считать

Postgres хранит таблицу построчно: чтобы сложить одну колонку, он читает строки целиком. ClickHouse хранит каждую колонку отдельно и читает только нужные. Одинаковые значения подряд ещё и отлично сжимаются.

Каждая полоса в схеме — то, что лежит на диске подряд. Выберите запрос и сравните, сколько данных прочитает каждая база. Для поиска одной строки по ключу всё наоборот: построчное хранение выигрывает.

ClickHouse

Когда брать ClickHouse

Подходит

  • Аналитика: суммы, средние и группировки по миллиардам строк за секунды.
  • События, логи, метрики: много вставок, данные почти не меняются.
  • Дашборды и отчёты, которые не должны тормозить рабочую базу.

Не подходит

  • Обычная работа приложения: чтение одной строки по ключу, частые UPDATE и DELETE. Лучше PostgreSQL
  • Транзакции между таблицами.
  • Небольшие объёмы: пока таблица в десятки миллионов строк, Postgres справится сам.
S3

Файлы — отдельно от базы

Объектное хранилище: кладёте файл по ключу и получаете его по ключу через HTTP. Дёшево, почти безгранично, легко раздавать через CDN. Это может быть AWS S3 или совместимое хранилище: MinIO, Cloudflare R2, Yandex Object Storage.


-- в базе только ключ файла
INSERT INTO photos (user_id, s3_key)
VALUES (42, 'users/42/cat.jpg');
-- сам файл клиент загружает напрямую в S3
-- по временной подписанной ссылке (presigned URL)

Подходит

  • Фото, видео, документы, выгрузки, бэкапы.
  • Статика сайта и раздача через CDN.
  • Дешёвое хранение огромных объёмов (data lake).

Не подходит

  • Частые мелкие правки: объект перезаписывается целиком.
  • Поиск и запросы по содержимому файлов.
  • Задержка в единицы миллисекунд: каждый запрос — это HTTP.

Что бы вы выбрали?

Девять задач из реальных проектов. Выберите технологию и сравните с ответом.

У некоторых задач несколько разумных решений. Обратите внимание, как часто «Postgres тоже справится».

Начните с Postgres

  • Почти любой проект начинается с одной базы. Postgres закрывает большинство задач: данные, транзакции, JSON, поиск, простые очереди.
  • Добавляйте систему, когда появилась конкретная проблема. База не выдерживает чтений — Redis. Долгие задачи тормозят ответы — очередь. Отчёты мешают рабочей базе — ClickHouse.
  • Каждая новая технология — это ещё бэкапы, мониторинг, обновления и ещё одна вещь, которая может упасть ночью.
  • Кэш, поисковый индекс и аналитика хранят копии данных. Источник правды один, и обычно это Postgres.
Выбирайте скучные технологии.Дэн Маккинли, «Choose Boring Technology»

К списку презентаций