小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

MongoDB 事務(wù) — 基礎(chǔ)入門篇

 黃爸爸好 2020-04-16

文章來源:Nodejs技術(shù)棧 / 原文鏈接

MongoDB 單文檔原生支持原子性,也具備事務(wù)的特性,但是我們說起事務(wù),通常是指在多文檔中的實(shí)現(xiàn),因此,MongoDB 在 4.0 版本支持了多文檔事務(wù),4.0 對(duì)應(yīng)于復(fù)制集的多表、多行,后續(xù)又在 4.2 版本支持了分片集的多表、多行事務(wù)操作。

事務(wù)四大特性

  • 原子性(Atomicity):事務(wù)必須是原子工作單元,對(duì)于其數(shù)據(jù)修改,要么全執(zhí)行,要么全不執(zhí)行。類似于 Redis 中我通常使用 Lua 腳本來實(shí)現(xiàn)多條命令操作的原子性。

  • 一致性(Consistency):事務(wù)在完成時(shí),必須使所有的數(shù)據(jù)都保持一致狀態(tài)。

  • 隔離性(Isolation):由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所作的修改隔離(簡而言之:一個(gè)事務(wù)執(zhí)行過程中不應(yīng)受其它事務(wù)影響)。

  • 持久性(Durability):事務(wù)完成之后,對(duì)于系統(tǒng)的影響是永久性的。

Read Concern/Write Concern/Read Preference

在事務(wù)操作中會(huì)分別使用到 readConcern、writeConcern、readPreference 這幾個(gè)選項(xiàng),用于控制 Session 的行為,下面分別予以介紹。

事務(wù)和 Write Concern

事務(wù)使用事務(wù)級(jí)別的 writeConcern 來提交寫操作,決定一個(gè)事務(wù)的寫入成功與否要看 writeConcern 選項(xiàng)設(shè)置了幾個(gè)節(jié)點(diǎn),默認(rèn)情況下為 1。

幾個(gè)選項(xiàng)值:

  • w:0 設(shè)置為 0 無需關(guān)注寫入成功與否。
  • w:1 ~ 任意節(jié)點(diǎn)數(shù) 自定義節(jié)點(diǎn)數(shù)設(shè)置,復(fù)制集中不得大于最大節(jié)點(diǎn)數(shù)。默認(rèn)情況下為 1,表示寫入到 Primary 節(jié)點(diǎn)就開始往客戶端發(fā)送確認(rèn)寫入成功。
  • w:'majority' 大多數(shù)節(jié)點(diǎn)成功原則,例如一個(gè)復(fù)制集 3 個(gè)節(jié)點(diǎn),2 個(gè)節(jié)點(diǎn)成功就認(rèn)為本次寫入成功。
  • w:'all' 所以節(jié)點(diǎn)都成功,才認(rèn)為寫入成功。
  • j:true 默認(rèn)情況 j:false,寫操作到達(dá)內(nèi)存算作完成。如果設(shè)置為 j:true,寫操作只有到達(dá) journal 文件才算成功。
  • wtimeout: 寫入超時(shí)實(shí)踐

設(shè)置示例:

writeConcern: {
w:'majority'// 大多數(shù)原則
j:true,
wtimeout: 5000,
}

JavaScript 使用示例:

db.user.insert({name: 'Jack'}, {writeConcern: {w: 'majority'}})

建議

對(duì)于重要數(shù)據(jù)可以應(yīng)用 w:'majority' 設(shè)置,普通數(shù)據(jù) w:1 設(shè)置則可以保證性能最佳,w 設(shè)置的節(jié)點(diǎn)數(shù)越多,等待的延遲也就越大,如果 w 等于總節(jié)點(diǎn)數(shù),一旦其中某個(gè)節(jié)點(diǎn)出現(xiàn)故障就會(huì)導(dǎo)致整個(gè)寫入失敗,也是有風(fēng)險(xiǎn)的。

docs.mongodb.com/manual/reference/write-concern/?spm=a2c4e.10696291.0.0.68d519a4ob3Yya

事務(wù)和 Read Preference

在一個(gè)事務(wù)操作中使用事務(wù)級(jí)別的 readPreference 來決定讀取時(shí)從哪個(gè)節(jié)點(diǎn)讀取??煞奖愕膶?shí)現(xiàn)讀寫分離、就近讀取策略。

可選值以下 5 個(gè):

  • primary 只從主節(jié)點(diǎn)讀取,默認(rèn)值。
  • primaryPreferred 優(yōu)先選擇主節(jié)點(diǎn),不可用時(shí)選擇從節(jié)點(diǎn)
  • secondary 只在從節(jié)點(diǎn)讀取
  • secondaryPreferred 優(yōu)先在從節(jié)點(diǎn)讀取,從節(jié)點(diǎn)不可用時(shí)選擇主節(jié)點(diǎn)。
  • nearest 選擇附近節(jié)點(diǎn)

場景選擇

  • primary/primaryPreferred:適合于數(shù)據(jù)實(shí)時(shí)性要求較高的場景,例如,訂單創(chuàng)建完畢直接跳轉(zhuǎn)到訂單詳情,如果選擇從節(jié)點(diǎn)讀取,可能會(huì)造成主節(jié)點(diǎn)數(shù)據(jù)寫入之后,從節(jié)點(diǎn)還未復(fù)制的情況,因?yàn)閺?fù)制過程是一個(gè)異步的操作。
  • secondary/secondaryPreferred:適應(yīng)用于數(shù)據(jù)實(shí)時(shí)性要求不高的場景,例如,報(bào)表數(shù)據(jù)、歷史訂單。還可以減輕對(duì)主節(jié)點(diǎn)的壓力。

使用示例

  • 鏈接字符串配置:
mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/admin?replicaSet=myRepl&readPreference=secondary
  • Mongo Shell:
db.collection.find({}).readPref( 'secondary')

測試時(shí)可借助 db.fsyncUnlock() 對(duì)從節(jié)點(diǎn)鎖定,僅主節(jié)點(diǎn)寫入數(shù)據(jù)。

docs.mongodb.com/manual/core/read-preference/#replica-set-read-preference

事務(wù)和 Read Concern

MongoDB 3.2 引入了 readConcern 來決定讀取的策略,但是與 readPreference 不同,readPreference 決定從哪個(gè)節(jié)點(diǎn)讀取,readConcern 決定該節(jié)點(diǎn)的哪些數(shù)據(jù)是可讀的。主要保證事務(wù)中的隔離性,避免臟讀。

可選值

  • available:讀取所有可用的數(shù)據(jù)。
  • local:僅讀取當(dāng)前分片的數(shù)據(jù)。
  • majority:讀取在大多數(shù)節(jié)點(diǎn)上提交完成的數(shù)據(jù)。
  • snapshot:讀取最近快照中的數(shù)據(jù)。

更新配置項(xiàng)

在啟動(dòng) Mongod 實(shí)例時(shí),指定 --enableMajorityReadConcern 選項(xiàng)或在配置文件中配置

enableMajorityReadConcern=true

重新啟動(dòng)實(shí)例,Mongo shell 登陸實(shí)例,使用 db._adminCommand( {getCmdLineOpts: 1}) 查看配置,可以看到在復(fù)制集中會(huì)多出一個(gè)配置,說明配置成功。

{
...
'parsed' : {
'replication' : {
'enableMajorityReadConcern' : true, // 變化之處
'oplogSizeMB' : 1024,
'replSet' : 'May'
},
},
}

使用示例

db.user.find().readConcern('majority')

readConcern 總結(jié)

MongoDB 的 readConcern 默認(rèn)情況下是臟讀,例如,用戶在主節(jié)點(diǎn)讀取一條數(shù)據(jù)之后,該節(jié)點(diǎn)未將數(shù)據(jù)同步至其它從節(jié)點(diǎn),就因?yàn)楫惓斓袅?,待主?jié)點(diǎn)恢復(fù)之后,將未同步至其它節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行回滾,就出現(xiàn)了臟讀。

readConcern 級(jí)別的 majority 可以保證讀到的數(shù)據(jù)已經(jīng)落入到大多數(shù)節(jié)點(diǎn)。所以說保證了事務(wù)的隔離性,所謂隔離性也是指事務(wù)內(nèi)的操作,事務(wù)外是看不見的。

readConcern 參考

  • docs.mongodb.com/manual/reference/read-concern/
  • MongoDB readConcern 原理解析

讀寫分離實(shí)踐

一個(gè)典型的應(yīng)用場景是用戶寫入訂單數(shù)據(jù)(數(shù)據(jù)寫入 Primary),立即調(diào)用查詢接口,由于采用讀寫分離模式,鏈接字符串設(shè)置 readPreference=secondaryPreferred 訂單寫入主節(jié)點(diǎn)之后并不能保證數(shù)據(jù)立即同步到從節(jié)點(diǎn),若此時(shí)直接由從節(jié)點(diǎn)讀取數(shù)據(jù), 偶爾會(huì)出現(xiàn)訂單數(shù)據(jù)無法找到,用戶就會(huì)感覺很奇怪,明明下了訂單,卻又查找不到,造成一些異常訂單。

一種導(dǎo)致下單之后再次查找丟失訂單的的寫法如下:

db.order.insert({'id': '123456789'})
db.order.find({'id': '123456789'}).readPref('secondaryPreferred')

解決方法一:

設(shè)置 readPreference=primary,將復(fù)制集的節(jié)點(diǎn)讀取由從節(jié)點(diǎn)轉(zhuǎn)換為主節(jié)點(diǎn)。

這種方式一個(gè)缺點(diǎn)是數(shù)據(jù)量大了之后會(huì)增加主節(jié)點(diǎn)的壓力,也就沒有了主從分離的模式。

解決方法二:

使用 writeConcern、readConcern 組合來解決,即保證讀寫分離模式,也保證了數(shù)據(jù)的一致性

// 寫入時(shí)保證大多數(shù)節(jié)點(diǎn)寫入成功
db.order.insert({'id': '123456789'}, {writeConern: {w: 'majority'}})

// 讀取時(shí)保證這條數(shù)據(jù)已在大多數(shù)節(jié)點(diǎn)存在
db.order.find({'id': '123456789'}).readPref('secondaryPreferred').readConcern('majority')

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多