新聞中心
MongoDB是開(kāi)源文檔型NoSQL數(shù)據(jù)庫(kù),它的數(shù)據(jù)模型靈活,具有高擴(kuò)展性、高可用性、易用性等特點(diǎn),能夠存儲(chǔ)半結(jié)構(gòu)化的數(shù)據(jù),并且有豐富的查詢(xún)語(yǔ)言和索引類(lèi)型,當(dāng)前MongoDB已廣泛的用在各企業(yè)的核心業(yè)務(wù)系統(tǒng)中。MongoDB也是db-engines排名最高的非關(guān)系型數(shù)據(jù)庫(kù)。

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司是一家服務(wù)多年做網(wǎng)站建設(shè)策劃設(shè)計(jì)制作的公司,為廣大用戶(hù)提供了做網(wǎng)站、網(wǎng)站制作,成都網(wǎng)站設(shè)計(jì),1元廣告,成都做網(wǎng)站選創(chuàng)新互聯(lián),貼合企業(yè)需求,高性?xún)r(jià)比,滿(mǎn)足客戶(hù)不同層次的需求一站式服務(wù)歡迎致電。
圖片來(lái)源:db-engines
在MongoDB讀取數(shù)據(jù)主要是受read concern(讀策略)、read preference (讀偏好設(shè)置 )兩個(gè)參數(shù)控制,其中readconcern決定在讀取副本集和分片集數(shù)據(jù)時(shí)的一致性和隔離性,而readpreference 決定客戶(hù)端驅(qū)動(dòng)讀取哪個(gè)數(shù)據(jù)節(jié)點(diǎn)的數(shù)據(jù)。它們的配合使用,可以提高M(jìn)ongoDB 集群的性能,以及在數(shù)據(jù)一致性和讀性能上做平衡。
readconcern 一致性讀策略
Readconcern 主要解決臟讀問(wèn)題,從3.2版本后開(kāi)始支持。比如PSA集群,用戶(hù)從 MongoDB 的 primary 上讀取數(shù)據(jù)后,這條數(shù)據(jù)并沒(méi)有同步從數(shù)節(jié)點(diǎn),然后 primary 就故障了。此時(shí)不同的Readconcern值,MongoDB 返回?cái)?shù)據(jù)的處理方式是不同的。
Readconcern有幾個(gè)不同的參數(shù),分別是local、available、majority、linearizable、snapshot ,數(shù)據(jù)庫(kù)在這些參數(shù)下的一致性是由弱到強(qiáng)遞增的。
?幾種模式介紹?
- Local
表示讀取的數(shù)據(jù)從實(shí)例中返回?cái)?shù)據(jù),但不保證數(shù)據(jù)是否被持久化(即可能被回滾)。該參數(shù)默認(rèn)值為local。
- Available
表示讀取的數(shù)據(jù)從實(shí)例中返回?cái)?shù)據(jù),但不保證數(shù)據(jù)是否被持久化(即可以回滾)。乍一看available和local沒(méi)有啥區(qū)別,對(duì)于副本集架構(gòu)兩者是相同的,主要區(qū)別場(chǎng)景是分片群集。在分片集群下,數(shù)據(jù)遷移會(huì)出現(xiàn)孤兒文檔(orphaned document),available模式可以從延遲最低的節(jié)點(diǎn)獲取數(shù)據(jù),而local則直接返回?cái)?shù)據(jù)。該參數(shù)是3.6版的新功能。
- Majority
表示讀取返回多數(shù)副本集成員已確認(rèn)的數(shù)據(jù),這個(gè)數(shù)據(jù)是持久化的不會(huì)被回滾。需要注意,在Majority下只能保證讀到的數(shù)據(jù)“不會(huì)發(fā)生回滾”,但并不能保證讀到的數(shù)據(jù)一定是最新的,官方也明確做了說(shuō)明。
Regardless of the read concern level, the most recent data on a node may not reflect the most recent version of the data in the system。
- linearizable
線(xiàn)性讀取數(shù)據(jù)。根據(jù)官方資料翻譯成中文:該查詢(xún)返回的數(shù)據(jù),反映了在讀取操作開(kāi)始之前完成的所有成功的多數(shù)確認(rèn)寫(xiě)入。查詢(xún)可能會(huì)等待并發(fā)執(zhí)行的寫(xiě)操作傳播到大多數(shù)副本集成員,然后返回結(jié)果。也就是在這種模式下,讀可能需要等待其他寫(xiě)操作完成。
- snapshot
從最新的快照中讀取數(shù)據(jù)。如果事務(wù)不是因果一致的會(huì)話(huà)的一部分,并且數(shù)據(jù)的寫(xiě)入?yún)?shù)writeconcern 值也是majority下,那將從多數(shù)提交數(shù)據(jù)的快照中讀取數(shù)據(jù)。
一般在生產(chǎn)推薦配置成Majority,這種模式是在數(shù)據(jù)安全和性能上相對(duì)平衡的選擇,但是使用Majority也有要求和問(wèn)題。首先它只支持WiredTiger引擎,其次需要寫(xiě)入?yún)?shù)writeconcern 也是majority 才會(huì)生效,最后在Majority下也不能完全保證解決了臟讀問(wèn)題。
?Majority 實(shí)現(xiàn)?
MongoDB 在readconcern majority 下,數(shù)據(jù)庫(kù)會(huì)起一個(gè)單獨(dú)的snapshot 線(xiàn)程,周期性的對(duì)當(dāng)前的數(shù)據(jù)集進(jìn)行 snapshot,并記錄 snapshot 最新 oplog的時(shí)間戳,得到一個(gè)映射表。
|
最新 oplog 時(shí)間戳 |
snapshot |
狀態(tài) |
|
t0 |
snapshot0 |
committed |
|
t1 |
snapshot1 |
uncommitted |
|
t2 |
snapshot2 |
uncommitted |
|
t3 |
snapshot3 |
uncommitted |
當(dāng) oplog 同步到大多數(shù)節(jié)點(diǎn)時(shí),對(duì)應(yīng)節(jié)點(diǎn)的 snapshot 才會(huì)標(biāo)記為 commmited,用戶(hù)讀取時(shí),從最新的 commited 狀態(tài)的 snapshot 讀取數(shù)據(jù),就能保證讀到的數(shù)據(jù)一定已經(jīng)同步到的大多數(shù)節(jié)點(diǎn)。那如何判斷oplog 已經(jīng)同步到大多數(shù)節(jié)點(diǎn)?
對(duì)于primary來(lái)說(shuō),當(dāng)secondary 節(jié)點(diǎn)的oplog發(fā)生變化時(shí),會(huì)通過(guò)命令將 oplog 進(jìn)度立即通知給 primary,同時(shí)節(jié)點(diǎn)間的心跳消息里也會(huì)包含最新 oplog 的信息。這樣primary 節(jié)點(diǎn)能很快知道數(shù)據(jù)是否已經(jīng)同步到大多數(shù)節(jié)點(diǎn)的,并更新 snapshot 的狀態(tài)。比如當(dāng)t2已經(jīng)寫(xiě)入到大多數(shù)據(jù)節(jié)點(diǎn)時(shí),snapshot1、snapshot2都可以更新為 commited 狀態(tài)。
對(duì)于secondary 節(jié)點(diǎn)來(lái)說(shuō),在拉取 oplog 時(shí),primary 節(jié)點(diǎn)會(huì)將“最新的數(shù)據(jù)已同步到大多數(shù)節(jié)點(diǎn)的”的信息返回給 secondary 節(jié)點(diǎn),然后secondary 節(jié)點(diǎn)通過(guò)這個(gè)oplog時(shí)間戳來(lái)更新自身的 snapshot 狀態(tài)。
readpreference 讀偏好設(shè)置
MongoDB 讀控制策略除了readconcern策略外,還有readpreference 。它主要控制數(shù)據(jù)庫(kù)客戶(hù)端驅(qū)動(dòng)從哪個(gè)節(jié)點(diǎn)讀取數(shù)據(jù)。這個(gè)特性可以方便地實(shí)現(xiàn)讀寫(xiě)分離、就近讀取等策略。
readpreference 是由三部分組成,分別是mode、maxStalenessSeconds 、tag set,其中mode支持五種類(lèi)型,分別是:primary、primaryPreferred、Secondary、secondaryPreferred、nearest,我們先看幾種模式的具體含義。
?幾種模式介紹?
- primary
默認(rèn)模式。讀操作只在主節(jié)點(diǎn),如果主節(jié)點(diǎn)不可用,報(bào)錯(cuò)或者拋出異常。這種策略適用于應(yīng)用程序需要嚴(yán)格的一致性,但可用性不是首要考慮因素的情況。
- primaryPreferred
大多情況下讀操作在主節(jié)點(diǎn),如果主節(jié)點(diǎn)不可用,如故障轉(zhuǎn)移,讀操作在從節(jié)點(diǎn)。
- secondary
僅從secondary節(jié)點(diǎn)中讀取,如果secondary節(jié)點(diǎn)不可用,讀將會(huì)報(bào)錯(cuò)。
- secondaryPreferred
大多情況下讀操作在從節(jié)點(diǎn),特殊情況(如沒(méi)有從節(jié)點(diǎn))讀操作在主節(jié)點(diǎn)。
- nearest
根據(jù)指定的延遲閾值,隨機(jī)地從符合條件的數(shù)據(jù)節(jié)點(diǎn)中讀取操作,不管該節(jié)點(diǎn)是主還是從節(jié)點(diǎn)。
?maxStalenessSeconds?
MongoDB 3.4 以后版本新增maxStalenessSeconds參數(shù)。集群的從節(jié)點(diǎn)可能因?yàn)榫W(wǎng)絡(luò)阻塞、磁盤(pán)吞吐低、長(zhǎng)時(shí)間執(zhí)行等原因,使從節(jié)點(diǎn)落后于主節(jié)點(diǎn)。當(dāng)從節(jié)點(diǎn)延遲時(shí)間超過(guò)了該參數(shù)定義的值,客戶(hù)端不會(huì)從該節(jié)點(diǎn)讀取數(shù)據(jù)。maxStalenessSeconds 不能與primary 模式兼容,只能在其他四種模式下使用。
當(dāng)選擇了使用該參數(shù)控制讀取數(shù)據(jù),客戶(hù)端會(huì)通過(guò)比較從節(jié)點(diǎn)和主節(jié)點(diǎn)的最后一次寫(xiě)時(shí)間來(lái)估計(jì)從節(jié)點(diǎn)的過(guò)期程度??蛻?hù)端會(huì)把連接指向小于等于maxStalenessSeconds的從節(jié)點(diǎn)。另外,需要注意maxStalenessSeconds最小值是90秒,如果小于該值將報(bào)錯(cuò)。
You must specify a maxStalenessSeconds value of 90 seconds or longer: specifying a smaller maxStalenessSeconds value will raise an error.
?標(biāo)簽集?
如果一個(gè)復(fù)制集中的成員有tag,就可以通過(guò)下面的辦法讀取到帶有具體標(biāo)簽的成員上。例如,如果某個(gè)節(jié)點(diǎn)有這樣的成員標(biāo)簽:
{ "region": "South", "datacenter": "A" }
那么以下tag set可以將讀操作指到上述成員(或具有相同標(biāo)記的其他成員):
[ { "region": "South", "datacenter": "A" }, { } ] // Find members with both tag values. If none are found, read from any eligible member.
[ { "region": "South" }, { "datacenter": "A" }, { } ] // Find members with the specified region tag. Only if not found, then find members with the specified datacenter tag. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { "region": "South" }, { } ] // Find members with the specified datacenter tag. Only if not found, then find members with the specified region tag. If none are found, read from any eligible member.
[ { "region": "South" }, { } ] // Find members with the specified region tag value. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { } ] // Find members with the specified datacenter tag value. If none are found, read from any eligible member.
[ { } ] // Find any eligible member.
?訪(fǎng)問(wèn)案例?
總結(jié)上面的內(nèi)容,可以通過(guò)下面三種方式去定義不同的readpreference策略。
復(fù)制集訪(fǎng)問(wèn)方式:
mongodb://db0.test.com,db1.test.com,db2.test.com/?replicaSet=myRepl&readPreference=secondaryPreferred&maxStalenessSecnotallow=150
分片集群方式:
mongodb://mongos1.test.com,mongos2.test.com/?readPreference=secondaryPreferred&maxStalenessSecnotallow=150
帶tag的定式:
mongodb://mongos1.test.com/?readPreference=secondaryPreferred&readPreferenceTags=dc:ny,rack:r1&readPreferenceTags=dc:ny&readPreferenceTags=xxx
總結(jié)
通過(guò)上文介紹,我們知道MongoDB讀數(shù)據(jù)策略,有readconcern和readpreference兩個(gè)重要的概念。其中readconcern是讀數(shù)據(jù)時(shí)的數(shù)據(jù)一致性級(jí)別,它決定了決定讀取數(shù)據(jù)時(shí)讀到什么樣的數(shù)據(jù)。通常結(jié)合可用性和性能,會(huì)將readconcern設(shè)置為majority。而readpreference決定讀哪個(gè)節(jié)點(diǎn)的數(shù)據(jù),主要用于實(shí)現(xiàn)讀寫(xiě)分離上。另外,MongoDB還提供了其他的配置選項(xiàng),如寫(xiě)數(shù)據(jù)策略(writeconcern)這將在后面的文章中介紹。
作者介紹
司馬遼太杰是 NineData 工程師。NineData 向企業(yè)和個(gè)人提供高效、安全的數(shù)據(jù)庫(kù)SQL開(kāi)發(fā)、數(shù)據(jù)庫(kù)備份、數(shù)據(jù)復(fù)制/遷移/集成、數(shù)據(jù)對(duì)比等能力的產(chǎn)品,它是開(kāi)箱即用的SaaS服務(wù),可以快速提升企業(yè)SQL開(kāi)發(fā)效率,保障企業(yè)數(shù)據(jù)安全。近期,NineData 即將會(huì)支持MongoDB、Redis等NoSQL數(shù)據(jù)庫(kù)。NineData 官網(wǎng)地址:??https://ninedata.cloud??。
本文轉(zhuǎn)載自微信公眾號(hào)「云數(shù)據(jù)庫(kù)技術(shù)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系云數(shù)據(jù)庫(kù)技術(shù)公眾號(hào)。
網(wǎng)站標(biāo)題:MongoDB讀數(shù)據(jù)策略
本文URL:http://m.fisionsoft.com.cn/article/cdoijdp.html


咨詢(xún)
建站咨詢(xún)
