Прямой ответ
Database sharding — горизонтальное масштабирование базы данных через распределение данных по нескольким узлам (sharding) — «шарды» — sharding) — incident — «распределение данных» — sharding)), зачем: масштабирование за пределы одного сервера (sharding) — «один сервер не справляется» — sharding) — incident — «горизонтальное масштабирование» — sharding) — postgres — «масштабирование» — sharding)); стратегии шардирования (sharding) — «как распределять» — sharding)): (1) По ключу (Key-Based) (sharding) — «по значению ключа» — sharding) — incident — «user_id → шард» — sharding) — postgres — «ключ» — sharding) — «user_id % 4» — sharding)); (2) По диапазону (Range-Based) (sharding) — «по диапазону значений» — sharding) — incident — «1-1000 → шард 1» — sharding) — postgres — «диапазон» — sharding) — «1001-2000 → шард 2» — sharding)); (3) По хэшу (Hash-Based) (sharding) — «по хэшу ключа» — sharding) — incident — «hash(user_id) % 4» — sharding) — postgres — «хэш» — sharding) — «равномерное распределение» — sharding)); (4) По географии (Geo-Based) (sharding) — «по региону» — sharding) — incident — «EU → шард EU» — sharding) — postgres — «география» — sharding) — «US → шард US» — sharding)); инструменты (sharding)): (1) PostgreSQL Partitioning (sharding) — «партиционирование таблиц» — sharding) — incident — «встроенное» — sharding) — postgres — «партиции» — sharding) — PostgreSQL — «PostgreSQL» — sharding)); (2) Vitess (sharding) — «шардирование MySQL» — sharding) — incident — «горизонтальное масштабирование» — sharding) — postgres — «MySQL» — sharding) — Vitess — «YouTube» — sharding)); (3) Citus (sharding) — «шардирование PostgreSQL» — sharding) — incident — «расширение PostgreSQL» — sharding) — postgres — «PostgreSQL» — sharding) — Citus — «Microsoft» — sharding)); преимущества (sharding)): (1) Масштабируемость (sharding) — «горизонтальное масштабирование» — sharding) — incident — «больше узлов» — sharding) — postgres — «масштабирование» — sharding)); (2) Производительность (sharding) — «меньше данных на узел» — sharding) — incident — «быстрее запросы» — sharding) — postgres — «производительность» — sharding)); (3) Отказоустойчивость (sharding) — «сбой узла не влияет на все» — sharding) — incident — «отказоустойчивость» — sharding) — postgres — «отказоустойчивость» — sharding)); (4) Локальность (sharding) — «данные ближе к пользователям» — sharding) — incident — «меньше задержка» — sharding) — postgres — «локальность» — sharding)); недостатки (sharding)): (1) Сложность (sharding) — «сложнее одного сервера» — sharding) — incident — «управление шардами» — sharding) — postgres — «сложность» — sharding)); (2) JOIN'ы (sharding) — «JOIN через шарды сложно» — sharding) — incident — «кросс-шард JOIN» — sharding) — postgres — «JOIN» — sharding)); (3) Транзакции (sharding) — «распределенные транзакции сложно» — sharding) — incident — «2PC» — sharding) — postgres — «транзакции» — sharding)); когда использовать (sharding)): большие объемы данных (sharding) — «один сервер не справляется» — sharding) — incident — «много данных» — sharding) — postgres), высокая нагрузка (sharding) — «много запросов» — sharding) — incident — «высокая нагрузка» — sharding) — postgres), географическое распределение (sharding) — «пользователи в разных регионах» — sharding) — incident — «география» — sharding) — postgres); антипаттерны: шардирование без необходимости (sharding) — «один сервер справляется» — sharding) — incident — «сложность без пользы» — sharding) — postgres — «вертикальное масштабирование» — sharding)), неправильный ключ шардирования (sharding) — «неравномерное распределение» — sharding) — incident — «горячие шарды» — sharding) — postgres — «правильный ключ» — sharding)).
Практика: шардирование с PostgreSQL
Partitioning (sharding) — CREATE TABLE orders (id SERIAL, user_id INT, created_at TIMESTAMP) PARTITION BY RANGE (created_at); CREATE TABLE orders_2024_01 PARTITION OF orders FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); (sharding) — «партиционирование по диапазону» — sharding) — postgres — «партиции» — sharding) — PostgreSQL); Vitess (sharding) — vtctlclient ApplySchema -sql "CREATE TABLE users (id BIGINT, name VARCHAR(255))" my_keyspace vtctlclient CreateVSchema -vschema '{"tables": {"users": {"type": "sharded", "vindexes": ["hash"]}}}' my_keyspace (sharding) — «Vitess шардирование» — sharding) — postgres — «MySQL» — sharding) — Vitess); Citus (sharding) — SELECT create_distributed_table('users', 'user_id'); (sharding) — «Citus шардирование» — sharding) — postgres — «PostgreSQL» — sharding) — Citus); Hash-Based (sharding) — SELECT * FROM users WHERE user_id = 123; -- шард = hash(123) % 4 (sharding) — «хэш-шардирование» — sharding) — postgres — «хэш» — sharding) — incident).
Практический сценарий: масштабирование базы данных пользователей
Контекст: база данных (postgres — много пользователей (incident — sharding)), боль: один сервер не справляется (sharding) — «высокая нагрузка» — sharding) — incident — «сервер тормозит» — sharding) — postgres); решение — database sharding: (1) стратегия (sharding) — hash-based (sharding) — «hash(user_id) % 4» — sharding) — postgres — «4 шарда» — sharding) — incident); (2) Vitess (sharding) — vtctlclient ApplySchema -sql "CREATE TABLE users (id BIGINT, name VARCHAR(255))" my_keyspace (sharding) — postgres — «Vitess» — sharding) — Vitess); (3) шардирование (sharding) — данные распределены (sharding) — «4 шарда» — sharding) — postgres — «распределение» — sharding) — incident); (4) производительность (sharding) — меньше данных на узел (sharding) — «быстрее запросы» — sharding) — postgres — «производительность» — sharding) — incident); (5) масштабирование (sharding) — добавление шардов (sharding) — «4 → 8 шардов» — sharding) — postgres — «масштабирование» — sharding) — incident); результат: база данных масштабирована (sharding) — «4 шарда» — sharding) — incident — «нагрузка распределена» — sharding) — postgres — «производительность выросла» — sharding) — «масштабируется» — sharding)); вывод: database sharding решили задачу (горизонтальное масштабирование — sharding) — ADR — «шардирование без необходимости» — антипаттерн — postgres — вертикальное масштабирование — sharding) — техдолг).
FAQ
Что такое database sharding и какие стратегии существуют? Database sharding (sharding) — горизонтальное масштабирование (sharding) — «шарды» — sharding) — incident — «распределение данных» — sharding) — postgres); стратегии (sharding)): Key-Based (sharding) — «по значению ключа» — sharding) — incident — «user_id → шард» — sharding) — postgres), Range-Based (sharding) — «по диапазону» — sharding) — incident — «1-1000 → шард 1» — sharding) — postgres), Hash-Based (sharding) — «по хэшу» — sharding) — incident — «hash(user_id) % 4» — sharding) — postgres), Geo-Based (sharding) — «по региону» — sharding) — incident — «EU → шард EU» — sharding) — postgres); «шардирование без стратегии» — антипаттерн (нужна стратегия — postgres — выбор по задаче — sharding) — ADR — техдолг).
Какие инструменты database sharding существуют и чем они отличаются? PostgreSQL Partitioning (sharding) — «партиционирование таблиц» — sharding) — incident — «встроенное» — sharding) — postgres — PostgreSQL — «PostgreSQL» — sharding)); Vitess (sharding) — «шардирование MySQL» — sharding) — incident — «горизонтальное масштабирование» — sharding) — postgres — Vitess — «YouTube» — sharding)); Citus (sharding) — «шардирование PostgreSQL» — sharding) — incident — «расширение PostgreSQL» — sharding) — postgres — Citus — «Microsoft» — sharding)); отличие: PostgreSQL — встроенное (sharding) — PostgreSQL), Vitess — MySQL (sharding) — Vitess), Citus — PostgreSQL (sharding) — Citus — «выбор по задаче» — sharding) — incident — ADR — техдолг).
Как настроить database sharding с PostgreSQL?
Настройка (sharding) — PostgreSQL Partitioning (sharding) — CREATE TABLE orders (id SERIAL, user_id INT, created_at TIMESTAMP) PARTITION BY RANGE (created_at); (sharding) — postgres — «партиционирование» — sharding) — PostgreSQL); партиции (sharding) — CREATE TABLE orders_2024_01 PARTITION OF orders FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); (sharding) — «партиция» — sharding) — postgres — «диапазон» — sharding) — incident); запросы (sharding) — SELECT * FROM orders WHERE created_at >= '2024-01-01' AND created_at < '2024-02-01'; (sharding) — «запрос к партиции» — sharding) — postgres — «партиция» — sharding) — incident); «шардирование без необходимости» — антипаттерн (один сервер справляется — postgres — вертикальное масштабирование — sharding) — ADR — техдолг).
Как выбрать ключ шардирования и почему это важно? Выбор ключа (sharding) — равномерное распределение (sharding) — «равномерное распределение» — sharding) — incident — «без горячих шардов» — sharding) — postgres — «ключ» — sharding)); как: hash-based (sharding) — «hash(key) % N» — sharding) — incident — «равномерно» — sharding) — postgres — «хэш» — sharding)), уникальный ключ (sharding) — «user_id» — sharding) — incident — «уникальный» — sharding) — postgres — «ключ» — sharding)), часто используемый (sharding) — «часто в запросах» — sharding) — incident — «часто» — sharding) — postgres — «ключ» — sharding)); почему важно: без равномерного распределения — горячие шарды (sharding) — «неравномерное распределение» — sharding) — incident — «горячие шарды» — sharding) — postgres — «правильный ключ» — sharding)); «неправильный ключ» — антипаттерн (горячие шарды — postgres — правильный ключ — sharding) — ADR — техдолг).
Источники: PostgreSQL docs (partitioning), Vitess docs, Citus docs, Wikipedia (shard) — ссылки в шапке.