Транзакции, репликация и шардирование
Три механизма «взрослой» эксплуатации: целостность, отказоустойчивость и горизонтальное масштабирование.
Транзакции обеспечивают «всё или ничего» для операций над несколькими документами; репликация хранит копии данных; шардирование распределяет данные по серверам.
Транзакции: атомарность нескольких документов
Обновление одного документа в 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) обеспечивает отказоустойчивость и сохранность данных.
- Шардирование распределяет данные по серверам для горизонтального масштабирования.