Одна база данных на одном сервере ограничена ресурсами узла и становится точкой отказа. При росте нагрузки система должна отвечать на большее число запросов, хранить больше данных и продолжать работу при сбое машины или зоны доступности. Репликация и шардинг решают разные части этой задачи. Репликация создаёт несколько копий одних и тех же данных, чтобы пережить отказ узла или перенести часть чтения на реплики. Шардинг распределяет разные части набора данных между узлами, чтобы один сервер не хранил и не обрабатывал весь объём.
Эти методы часто применяются вместе, но их нельзя смешивать. Репликация без шардинга повышает доступность, но не снимает ограничение на размер одной логической таблицы или пропускную способность записи на основном узле. Шардинг без репликации распределяет объём, но отказ одного шарда делает недоступной часть данных. Поэтому распределённая СУБД должна одновременно отвечать на два вопроса: сколько копий хранится у каждого фрагмента данных и по какому правилу данные попадают на конкретный шард.
Статья построена как обзор механизмов репликации и шардинга в современных СУБД. В корпус включены PostgreSQL и MySQL как распространённые реляционные СУБД со схемой с основным узлом и репликами, MongoDB и Cassandra как системы со встроенным распределением данных, ClickHouse как аналитическая СУБД с распределёнными таблицами, а также CockroachDB и YugabyteDB как распределённые SQL-системы, ориентированные на кворум — большинство реплик, достаточное для подтверждения операции [1–13]. Статья о Raft используется как базовый источник по консенсусу [14]. Сравнение проводится по четырём критериям: как выбирается узел записи, как подтверждается фиксация транзакции, как распределяются данные по шардам и что происходит при отказе или перераспределении нагрузки.
В схеме с основным узлом и репликами запись принимает один основной узел, а реплики получают изменения позже или в рамках протокола подтверждения. PostgreSQL поддерживает потоковую физическую репликацию на основе журнала предзаписи WAL: резервный сервер получает журнальные записи и воспроизводит их, а резервный сервер чтения может обслуживать запросы без изменения данных [1]. Такой подход подходит для резервирования и запросов только на чтение. Ограничение состоит в том, что запись всё равно проходит через основной узел, а при асинхронной передаче возможна потеря последних подтверждённых клиенту изменений при аварии основного узла.
Логическая репликация передаёт не физические страницы или журнал предзаписи как поток байтов, а изменения на уровне таблиц и строк. В PostgreSQL она строится через публикации и подписки: публикующий узел отдаёт изменения, а подписчик применяет их у себя [2]. Такой режим полезен для миграций, выборочной репликации таблиц, обмена между версиями и интеграционных сценариев. Ограничение такого режима — необходимость учитывать конфликты, ограничения схемы и поведение первичных ключей. Логическая репликация обычно хуже подходит как прозрачная замена физическому резервному серверу, но лучше подходит для выборочной передачи данных.
Синхронная и асинхронная репликация различаются моментом подтверждения записи. При асинхронной схеме основной узел может ответить клиенту до того, как реплика получила изменение. Это уменьшает задержку, но увеличивает окно потери данных при отказе. В синхронной репликации основной узел ждёт подтверждения от выбранных синхронных реплик; в полусинхронной схеме MySQL достаточно подтверждения о получении и записи событий в журнал передачи хотя бы одной репликой [3]. Это уменьшает риск потери данных, но добавляет сетевую задержку в путь записи. Поэтому выбор режима зависит от того, что важнее для конкретной системы: минимальная задержка записи или меньший риск отката последних операций.
В схемах с кворумом запись подтверждается после согласования с большинством реплик; в Raft большинство нужно для выбора лидера и фиксации записи в журнале. CockroachDB хранит диапазоны данных в нескольких репликах и использует Raft для согласования изменений [12; 14]. Такой подход позволяет автоматически переживать отказ меньшинства реплик, но требует связи между участниками кворума. Если сеть разделилась так, что ни одна часть не имеет большинства, запись должна остановиться, иначе система потеряет согласованность.
MongoDB использует набор реплик с основным узлом и вторичными узлами. Основной узел принимает запись, изменения попадают в журнал операций, а вторичные узлы применяют их асинхронно; при отказе основного узла участники набора реплик проводят выборы [5]. Это удобно для автоматического переключения и распределения чтения, но чтение с вторичного узла может вернуть устаревшие данные. Поэтому разработчик должен явно понимать предпочтение источника чтения, требование к подтверждению записи и риск задержки репликации.
Шардинг начинается с выбора ключа, по которому данные распределяются между узлами. Шардинг по диапазону делит данные по интервалам: например, заказы с идентификаторами от 1 до 1 000 000 попадают на один шард, следующие — на другой. Такой подход удобен для диапазонных запросов, но может создать горячий шард, если новые записи всегда попадают в конец диапазона. Шардинг по хешу применяет хеш-функцию к ключу и распределяет записи более равномерно. Он уменьшает риск перекоса записи, но усложняет диапазонные запросы, потому что соседние значения могут оказаться на разных узлах [6; 11].
MongoDB связывает шардинг с ключом шардинга. Если запрос содержит этот ключ или его префикс, система может направить операцию к нужному шарду. Если в условии нет ключа шардинга, запрос рассылается по нескольким шардам с последующим сбором результата [6]. Поэтому неправильный ключ шардинга не просто ухудшает баланс данных, а меняет стоимость запросов. Ключ должен учитывать кардинальность, распределение значений и типичные фильтры приложения.
ClickHouse использует движок распределённой таблицы для маршрутизации запросов к шарду и реплике внутри кластера [9]. В такой схеме локальные таблицы хранят данные на узлах, а распределённая таблица выступает как логический вход для запроса. Ключ шардинга определяет, куда отправлять запись. При внутренней репликации запись отправляется в одну здоровую реплику каждого шарда; без неё данные отправляются во все реплики, а репликацию обеспечивает сама распределённая таблица. Для аналитических запросов это позволяет читать данные параллельно с нескольких шардов, но требует аккуратного выбора ключа, чтобы одна часть кластера не стала постоянным узким местом.
Cassandra проектирует распределение данных через ключ партиции и стратегию репликации на уровне пространства ключей [7]. Коэффициент репликации задаёт число копий, а стратегия сетевой топологии позволяет распределять реплики по дата-центрам. Такой подход подходит для высокой доступности и горизонтального роста, но требует проектировать таблицы исходя из запросов. Если ключ партиции выбран плохо, одна партиция может стать слишком большой или слишком горячей, а запросы без ключа партиции будут требовать дорогого обхода.
Со временем распределение данных меняется. Один шард может получить больше записей из-за популярного клиента, региона или временного диапазона. MongoDB использует фрагменты диапазона и балансировщик, а также поддерживает перешардирование коллекции на другой ключ шардинга [6]. YugabyteDB описывает таблетки как единицы шардинга и поддерживает шардинг по хешу и диапазону, автоматическое разделение таблеток и балансировку по кластеру [11]. Эти механизмы уменьшают ручную работу администратора, но не отменяют исходного выбора ключа: если поток вставок концентрируется вокруг одного значения ключа шардинга или одного диапазона, нужно перешардирование или смена ключа; один балансировщик этого не исправит.
Отказ узла в распределённой СУБД обрабатывается по-разному в зависимости от модели репликации. В системе с основным узлом и репликами нужно выбрать новый основной узел или вручную переключить приложение. В системе с кворумом запись продолжается, если доступно большинство реплик. В ClickHouse ReplicatedMergeTree репликация выполняется на уровне таблиц, а координатор, например ClickHouse Keeper, хранит метаданные реплик [8]. Важно, что отказоустойчивость зависит не от самого факта наличия копий, а от того, как система обнаруживает отказ, выбирает новый источник записи и предотвращает расхождение данных.
Сочетание репликации и шардинга даёт типовую схему: каждый шард хранит свою часть данных, а внутри шарда есть несколько реплик. Тогда потеря одной машины не уничтожает данные, а рост объёма можно обслуживать добавлением шарда. Ограничение такой схемы — сложность маршрутизации, миграции данных, межшардовых транзакций и согласованного чтения. Запрос, который раньше работал внутри одной таблицы, после шардинга может превратиться в распределённую операцию с несколькими узлами и разными задержками.
Главный вывод состоит в том, что репликация закрывает доступность и чтение, шардинг — объём данных и масштабирование записи, а горячая точка возникает на границе ключа и маршрутизации. Репликация создаёт копии данных, уменьшает риск потери при отказе и может переносить часть чтения на реплики, но добавляет задержку, выбор режима подтверждения и проблему устаревшего чтения. Шардинг распределяет объём данных и нагрузку между узлами, но требует правильного ключа шардинга, механизмов ребалансировки и контроля горячих шардов. Кворум и Raft помогают согласовать запись между репликами, но останавливают запись при потере большинства. Поэтому архитектура распределённой СУБД должна проектироваться от профиля запросов, требований к задержке, допустимой потери данных и правил восстановления после отказа.
Литература:
- PostgreSQL Documentation. Log-Shipping Standby Servers. — 2026. — URL: https://www.postgresql.org/docs/current/warm-standby.html (дата обращения: 05.07.2026).
- PostgreSQL Documentation. Logical Replication. — 2026. — URL: https://www.postgresql.org/docs/current/logical-replication.html (дата обращения: 05.07.2026).
- MySQL 8.4 Reference Manual. Semisynchronous Replication. — 2026. — URL: https://dev.mysql.com/doc/refman/8.4/en/replication-semisync.html (дата обращения: 05.07.2026).
- MySQL 8.0 Reference Manual. Group Replication. — 2026. — URL: https://dev.mysql.com/doc/refman/8.0/en/group-replication.html (дата обращения: 05.07.2026).
- MongoDB Manual. Replication. — 2026. — URL: https://www.mongodb.com/docs/manual/replication/ (дата обращения: 05.07.2026).
- MongoDB Manual. Sharding. — 2026. — URL: https://www.mongodb.com/docs/manual/sharding/ (дата обращения: 05.07.2026).
- Apache Cassandra Documentation. Data Definition. — 2026. — URL: https://cassandra.apache.org/doc/latest/cassandra/cql/ddl.html (дата обращения: 05.07.2026).
- ClickHouse Docs. Движки таблиц Replicated*. — 2026. — URL: https://clickhouse.com/docs/ru/engines/table-engines/mergetree-family/replication (дата обращения: 05.07.2026).
- ClickHouse Docs. Движок Distributed. — 2026. — URL: https://clickhouse.com/docs/ru/engines/table-engines/special/distributed (дата обращения: 05.07.2026).
- CockroachDB Docs. Architecture Overview. — 2026. — URL: https://www.cockroachlabs.com/docs/stable/architecture/overview.html (дата обращения: 05.07.2026).
- YugabyteDB Docs. DocDB sharding. — 2026. — URL: https://docs.yugabyte.com/stable/architecture/docdb-sharding/ (дата обращения: 05.07.2026).
- CockroachDB Docs. Replication Layer. — 2026. — URL: https://www.cockroachlabs.com/docs/stable/architecture/replication-layer (дата обращения: 05.07.2026).
- YugabyteDB Docs. Raft consensus protocol. — 2026. — URL: https://docs.yugabyte.com/stable/architecture/docdb-replication/raft/ (дата обращения: 05.07.2026).
- Ongaro D., Ousterhout J. In Search of an Understandable Consensus Algorithm. — 2014. — URL: https://raft.github.io/raft.pdf.

