Однодокументность MongoDB изначально поддерживает атомарность, а также имеет характеристики транзакций, но когда мы говорим о транзакциях, то обычно имеем в виду реализацию в нескольких документах, поэтому MongoDB поддерживает многодокументные транзакции в версии 4.0, а 4.0 соответствует множественным таблицам в наборе реплик, многострочном, а позже в версии 4.2 поддерживаются операции многотабличных и многострочных транзакций сегментированных наборов.
Четыре характеристики бизнеса
-
Атомарность: транзакция должна быть атомарной единицей работы, которая либо выполняет все модификации своих данных, либо не выполняет ни одной. Как и в случае с Redis, я обычно использую сценарии Lua для достижения атомарности нескольких командных операций.
-
Непротиворечивость: когда транзакция завершается, все данные должны быть в согласованном состоянии.
-
Изоляция: изменения, сделанные параллельной транзакцией, должны быть изолированы от изменений, сделанных любой другой параллельной транзакцией (вкратце: одна транзакция не должна подвергаться влиянию других транзакций во время ее выполнения).
-
Долговечность: после завершения транзакции воздействие на систему является постоянным.
Read Concern/Write Concern/Read Preference
В операции транзакции параметры readConcern, writeConcern и readPreference используются для управления поведением сеанса, которые будут представлены отдельно ниже.
Транзакции и сообщение о беспокойстве
Транзакции используют writeConcern на уровне транзакции для отправки операций записи.Успех транзакции зависит от количества узлов, заданного параметром writeConcern, которое по умолчанию равно 1.
Несколько значений опции:
- w:0Установите на 0 и не волнуйтесь, успешна ли запись или нет.
- w: 1 на любое количество узловЗадайте количество пользовательских узлов. Набор реплик не должен превышать максимальное количество узлов. По умолчанию он равен 1, что означает, что запись на основной узел начинает отправлять клиенту подтверждение об успешной записи.
- w:"majority"Принцип успеха для большинства узлов.Например, если набор реплик имеет 3 узла, если 2 узла завершаются успешно, запись считается успешной.
- w:"all"Поэтому, если узлы работают успешно, запись считается успешной.
- j:trueПо умолчанию j:false операция записи считается завершенной, когда она достигает памяти. Если установлено значение j:true, запись будет успешной только в том случае, если она достигнет файла журнала.
- wtimeout: Практика тайм-аута записи
Пример настройки:
writeConcern: {
w:"majority" // 大多数原则
j:true,
wtimeout: 5000,
}
Пример использования JavaScript:
db.user.insert({name: "Jack"}, {writeConcern: {w: "majority"}})
предложение
Параметр w:"majority" может быть применен к важным данным, а параметр w:1 для обычных данных может обеспечить наилучшую производительность. Чем больше узлов установлено w, тем больше задержка ожидания. Если w равно общему количеству узлов, как только сбой узла может привести к сбою всей записи, что также рискованно.
docs.MongoDB.com/manual/ref E…
Транзакции и предпочтения чтения
Используйте readPreference уровня транзакции в транзакционной операции, чтобы определить, с какого узла читать при чтении. Он может легко реализовать разделение чтения-записи и ближайшую стратегию чтения.
Необязательными значениями являются следующие 5:
- primaryТолько чтение с главного узла, значение по умолчанию.
- primaryPreferredГлавный узел предпочтительнее, а подчиненный узел выбирается, когда он недоступен.
- secondaryчитать только с узла
- secondaryPreferredВедомый узел предпочтительнее для чтения, а главный узел выбирается, когда подчиненный узел недоступен.
- nearestвыбрать ближайшие узлы
выбор сцены
- primary/primaryPreferred: подходит для сценариев с высокими требованиями к данным в режиме реального времени. Например, после создания заказа он напрямую переходит к деталям заказа. Если вы решите читать с ведомого узла, это может привести к тому, что данные главный узел должен быть записан, а подчиненный узел еще не скопировал его, поскольку процесс копирования является асинхронной операцией.
- вторичный / вторичный предпочтительный: подходит для менее требовательных данных в реальном времени, например, данных отчета, истории заказов. Это также может снизить нагрузку на главный узел.
Пример использования
- Конфигурация строки ссылки:
mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/admin?replicaSet=myRepl&readPreference=secondary
- Оболочка Монго:
db.collection.find({}).readPref( "secondary")
Во время теста подчиненный узел можно заблокировать с помощью db.fsyncUnlock(), и только главный узел записывает данные.
Транзакция и чтение беспокойства
MongoDB 3.2 представила readConcern для определения стратегии чтения, но, в отличие от readPreference, readPreference решает, с какого узла читать, а readConcern решает, какие данные узла доступны для чтения. В основном это обеспечивает изоляцию в транзакциях и позволяет избежать грязных чтений.
необязательное значение
- available: прочитать все доступные данные.
- local: читать только данные текущего сегмента.
- большинство: читать данные, представленные на большинстве узлов.
- моментальный снимок: чтение данных из самого последнего моментального снимка.
Обновить элементы конфигурации
При запуске экземпляра MongoD укажите опцию --enableMajorityreadConcern или настройте его в файл конфигурации
enableMajorityReadConcern=true
Перезапустите экземпляр, войдите в экземпляр с оболочкой Mongo, используйтеdb._adminCommand( {getCmdLineOpts: 1})
Глядя на конфигурацию, вы можете увидеть, что в наборе репликации будет еще одна конфигурация, что указывает на то, что конфигурация прошла успешно.
{
...
"parsed" : {
"replication" : {
"enableMajorityReadConcern" : true, // 变化之处
"oplogSizeMB" : 1024,
"replSet" : "May"
},
},
}
Пример использования
db.user.find().readConcern("majority")
readConcern Резюме
По умолчанию readConcern в MongoDB является грязным чтением. Например, после того, как пользователь читает часть данных на главном узле, узел не синхронизирует данные с другими подчиненными узлами и зависает из-за исключения. После восстановления главного узла он не будет синхронизирован с ведомым узлом.Грязные чтения происходят при откате данных на других узлах.
Большинство на уровне readConcern может гарантировать, что прочитанные данные попадут на большинство узлов. Таким образом, гарантируется изоляция транзакции.Так называемая изоляция также относится к операции внутри транзакции, которая невидима вне транзакции.
Справочник по readConcern
Практика разделения чтения и записи
Типичный сценарий приложения заключается в том, что пользователь записывает данные заказа (данные записываются в Primary) и сразу же вызывает интерфейс запроса.Из-за режима разделения чтения-записи параметр строки ссылки readPreference=secondaryPreferred не гарантирует, что данные будут синхронизированы к основному узлу сразу после того, как заказ будет записан на основной узел.Подчиненный узел, если данные считываются непосредственно с подчиненного узла в это время, иногда данные заказа не могут быть найдены, и пользователь будет чувствовать себя очень странно, четко размещая заказ, но не смог его найти, что привело к некоторым ненормальным заказам.
Один из способов написания, который приводит к повторному нахождению потерянных заказов после размещения заказа, выглядит следующим образом:
db.order.insert({"id": "123456789"})
db.order.find({"id": "123456789"}).readPref("secondaryPreferred")
Решение первое:
Установите readPreference=primary, чтобы преобразовать чтение узла набора реплик с подчиненного узла на главный узел.
Одним из недостатков этого метода является то, что при большом объеме данных увеличивается нагрузка на главный узел, а режим разделения ведущий-ведомый отсутствует.
Решение второе:
использоватькомбинация writeConcern, readConcernРешить, то есть обеспечить режим разделения чтения-записи, но иОбеспечение согласованности данных.
// 写入时保证大多数节点写入成功
db.order.insert({"id": "123456789"}, {writeConern: {w: "majority"}})
// 读取时保证这条数据已在大多数节点存在
db.order.find({"id": "123456789"}).readPref("secondaryPreferred").readConcern("majority")
Эта статья представляет собой предварительное понимание транзакций MogoDB. Предпочтение чтения/записи беспокойства/чтения будет применяться в последующих практиках транзакций. Я надеюсь, что у вас есть понимание заранее. В следующей статье я расскажу о транзакциях MongoDB Как это должно быть применяется и сочетается с Node.js для практических инструкций, обратите внимание!