Дата: 2025-02-10
Принято
Резервирование обязательно (вертикальное масштабирование - кластер с репликацией и автоматическим фейловером). Шардинг желателен (горизонтальное масштабирование на разные серверы или физические диски).
Особое требование: хранить и быстро находить big data (заказы).
В критерии выбора не входит полнотекстовый поиск - для этого есть ElasticSearch, куда данные из основной БД будут зеркалиться через Kafka (Outbox pattern). Бизнес-события вида “продукт добавлен”, “заказ оплачен”, нужные для аудита и бизнес-аналитики, сюда тоже не относятся - для этого есть ClickHouse, куда события будут попадать из Kafka (Outbox pattern).
Для надёжности: Postgres 17 с кластером от Percona.
Для производительности:
Приемлемое (не более 1 сек.) время обработки типичных запросов. Резервирование - кластеризация с репликацией и автоматическим (прозрачным для приложений) переходом на другой сервер в случае сбоя.
[наверх]
См. партиции. В терминах CAP-теоремы это CA, т.к. все партиции (фактически самостоятельные таблицы обслуживаются одним сервером. Но их можно ускорить с помощью RAID с чередованием (например RAID6), что рекомендуется, либо подключая разные диски к разным партициям, которых надо столько, чтобы в каждой партиции было не более 50 млн. записей:
CREATE TABLE orders
(
id uuid PRIMARY KEY DEFAULT gen_random_uuid()
) PARTITION BY HASH (id);
-- хранение партиций в отдельной схеме, чтобы не засорять основное пространство имён
CREATE SCHEMA parts;
CREATE TABLESPACE disk1
LOCATION '/mnt/disk1';
CREATE TABLE parts.orders_part1
PARTITION OF orders
FOR VALUES WITH (MODULUS 2, REMAINDER 0)
TABLESPACE disk1;
CREATE TABLESPACE disk2
LOCATION '/mnt/disk2';
CREATE TABLE parts.orders_part2
PARTITION OF orders
FOR VALUES WITH (MODULUS 2, REMAINDER 1)
TABLESPACE disk2;
[наверх]
См. например Citus.
[наверх]
Поиск происходит в ElasticSearch, кроме того продукты - практически read-only ресурс, поэтому можно рассматривать ElasticSearch как основное их хранилище (шардинг там поддерживается, но нет транзакций и запись происходит с задержкой), а в Postgres’е хранить только id - для вторичных ключей и джойнов
[наверх]
Если трактовать момент сохранения записи (заказа / продукта) в БД как временной ряд, то можно рассмотреть Postgres 17 с расширением TimescaleDB, которое предоставляет hypertables для автосоздания партиций и компрессию данных для снижения объёма на диске до 20 раз (сжатые данные становятся read-only, но момент сжатия можно отсрочить на, к примеру, 90 дней, тем самым получив hot storage и архив).
Можно добавить tablespaces для хранения партиций на разных дисках (хотя рекомендуется один tablespace и под ним RAID с чередованием+зеркалированием). К одной hypertable можно присоединить ряд tablespaces; TimescaleDB это понимает и будет шардить:
CREATE TABLESPACE disk1
LOCATION '/mnt/disk1';
CREATE TABLESPACE disk2
LOCATION '/mnt/disk2';
ALTER TABLE orders
SET (
timescaledb.compress,
timescaledb.compress_segmentby = 'id',
timescaledb.compress_orderby = 'created_date'
);
SELECT attach_tablespace('disk1', 'orders');
SELECT attach_tablespace('disk2', 'orders');
SELECT add_compression_policy('orders', INTERVAL '90 days');
[наверх]
См. сайт производителя.
[наверх]
В терминах CAP-теоремы это CP, т.к. во время выбора ноды-лидера кластер недоступен.
Лицензия MongoDB 8 (см. пункт 13) запрещает предоставлять продукт в виде сервиса (чтобы облака не перепродавали изначально бесплатный продукт), а для внутреннего использования в проектах - позволяет.