Транзакции, репликация и шардирование

Три механизма «взрослой» эксплуатации: целостность, отказоустойчивость и горизонтальное масштабирование.

Транзакции обеспечивают «всё или ничего» для операций над несколькими документами; репликация хранит копии данных; шардирование распределяет данные по серверам.

Транзакции: атомарность нескольких документов

Обновление одного документа в MongoDB атомарно само по себе. Но иногда нужно изменить несколько документов как единое целое — например, списать деньги с одного счёта и зачислить на другой. Если второе действие сорвётся, первое нужно откатить. Для этого есть многодокументные транзакции:

const session = client.startSession();
try {
  session.startTransaction();
  await accounts.updateOne({ _id: "a" }, { $inc: { balance: -100 } }, { session });
  await accounts.updateOne({ _id: "b" }, { $inc: { balance:  100 } }, { session });
  await session.commitTransaction();
} catch (e) {
  await session.abortTransaction();
} finally {
  await session.endSession();
}

Либо обе операции применятся (commit), либо ни одна (abort). Важная мысль документного дизайна: если данные правильно встроены в один документ, транзакция часто не нужна — одно обновление и так атомарно. Транзакции — для случаев, когда без нескольких документов не обойтись.

Репликация: копии ради надёжности

Replica set — это группа серверов с одинаковыми данными. Один из них primary (принимает записи), остальные secondary (хранят копии). Если primary выходит из строя, оставшиеся узлы автоматически выбирают нового primary — приложение продолжает работать. Репликация даёт:

  • Отказоустойчивость — потеря одного сервера не роняет базу.
  • Сохранность данных — копии на нескольких машинах.
  • Масштабирование чтения — часть чтений можно направить на secondary.

В Atlas replica set из трёх узлов — конфигурация по умолчанию, её даже не нужно настраивать вручную.

Шардирование: распределение данных

Когда данных столько, что они не помещаются на один сервер или нагрузка слишком велика, применяют шардирование — горизонтальное разбиение коллекции по нескольким серверам (шардам). Каждый шард хранит свою часть документов, определяемую ключом шардирования.

Это то самое масштабирование «вширь», ради которого создавалась документная модель: добавляете серверы — растёт ёмкость и пропускная способность. Шардирование сложнее репликации, и выбор ключа шардирования критичен, поэтому к нему прибегают, когда вертикального масштабирования (более мощный сервер) уже не хватает.

Итог

  • Транзакции дают «всё или ничего» для нескольких документов; при удачном встраивании часто не нужны.
  • Репликация (replica set: primary + secondary) обеспечивает отказоустойчивость и сохранность данных.
  • Шардирование распределяет данные по серверам для горизонтального масштабирования.
Проверьте себя
1. Когда в MongoDB обычно нужна многодокументная транзакция?
AДля любого обновления одного документа
BКогда несколько документов нужно изменить как единое целое («всё или ничего»)
CДля чтения данных
DДля создания индекса
2. Что такое replica set?
AСпособ распределить данные по серверам
BГруппа серверов с копиями данных: один primary и несколько secondary
CТип индекса
DФормат документа
3. Для чего применяют шардирование?
AДля отката транзакций
BДля горизонтального масштабирования: распределения данных по нескольким серверам
CДля проверки схемы
DДля ускорения одного документа
Поддержать проект