真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MongoDB的應(yīng)用是怎樣的

MongoDB的應(yīng)用是怎樣的,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

成都創(chuàng)新互聯(lián)公司專注于臨武網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供臨武營銷型網(wǎng)站建設(shè),臨武網(wǎng)站制作、臨武網(wǎng)頁設(shè)計、臨武網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造臨武網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供臨武網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

前言

偶然機會看到mongo中文社區(qū)辦了場征文活動,覺得挺有意思的,雖說自己還在成為大佬的路上,但參與一下未嘗不可。于是就有了這篇文章。

活動已規(guī)定了選題框架,我思索了小會兒,覺得從0到1+

  • web app

這個范圍太廣了。不過確實MongoDB在web應(yīng)用里應(yīng)用挺多,web應(yīng)用特點本要求擴展性高,靈活豐富的查詢,動態(tài)地添加字段等

  • 敏捷開發(fā)

這里主要強調(diào)的是由于沒有固定的schema的優(yōu)勢使得很適用敏捷開發(fā)方法論

  • 分析型和logging

capped collection適合于放日志數(shù)據(jù),至于分析型我倒見不多,莫非還可比dedicated OLAP db更好?

  • caching

  • 可變schema

腳本搭建

個人建議呢,自己寫一個搭建集群的腳本,方便一鍵生成,非常方便,而不要每次一個命令一個命令地敲。我的腳本供參考[7]

后面我會談到在快速創(chuàng)建定制化集群的基礎(chǔ)上用gdb調(diào)試內(nèi)核。

分布式概念及原理


這一塊領(lǐng)域太大了!

MongoDB屬于分布式數(shù)據(jù)庫,相比于單機數(shù)據(jù)庫,節(jié)點之間有了網(wǎng)絡(luò)距離,于是乎,各種不靠譜的事就會發(fā)生了(google一下"分布式系統(tǒng)里常見的8個fallacies")。我根據(jù)mongo實際情況講點皮毛 _^^_ 更多有趣的資料務(wù)必參考DDIA[6],這個是迄今最通俗的版本。

我非常簡單地用自己的語言從背景、為什么需要它, Mongo怎么做的三方面來談?wù)?,談到的詞匯建議讀者多多google。

共識協(xié)議(Consensus)

背景

簡單理解就是要多方達到一致。稍微接觸這塊的都知道raft,這個Stanford 教授  John Ousterhout 和其博士生 Diego Ongaro 弄出來的,已經(jīng)在多種分布式數(shù)據(jù)庫上應(yīng)用了如TiDB, PolarDB。

當(dāng)然業(yè)界還有其它協(xié)議,Lamport的Paxos(被應(yīng)用到Chubby),Zookeeper的ZAB,MongoDB的pv1。

為什么需要它

簡單來看,當(dāng)多個節(jié)點共同來做決定時,如果你說你的,我說我的,還怎么決定?。烤拖褚蝗喝嗽诜块g開會,七嘴八舌,就是沒統(tǒng)一,最后這會只能白開了。同理在分布式系統(tǒng)中,我們需有一套規(guī)則讓各節(jié)點對事件以及結(jié)果達成一致,這樣才能正常運轉(zhuǎn)。這其實與現(xiàn)實世界模型是很吻合的。

Mongo怎么做的

mongo用的是MongoDB pv1 ,是一種類raft 協(xié)議,不過它進行了豐富的擴展,如rs.conf()中就可配置各節(jié)點的priority,hidden, vote等屬性,有非常大的靈活性;增加了PreVote, DryRun等動作等。詳細(xì)細(xì)節(jié)讀者可參考相關(guān)文檔。

隔離級別/一致性(ACID/Consistency/CAP)

背景

這幾個概念有相似性,就放在一起了。貌似分布式系統(tǒng)里我們一般不談ACID,這是在單機關(guān)系型數(shù)據(jù)庫常用的詞匯,且這里面的C 與分布式系統(tǒng)所說的Consistency不是一回事!

CAP是Brewer 92年就提出的詞匯了,很多論文現(xiàn)在都不推薦使用這個詞匯,因為它很有歧義;

在眾多論文里,還有與一致性很多的詞匯,如

- causal consistency,因果一致性,Mongo中有

- linearizability,線性一致性,針對于single object的,始終讀到最新的數(shù)據(jù)

- serializability,串行化,強調(diào)多個事務(wù)操作多個object的,在關(guān)系型db屬最強的隔離級別

- strict serializability,linearizability + serializability,在google spanner中有提到

- sequence consistency: 順序一致性,比linearizability弱點,比如x86 CPU默認(rèn)一致性是它,我們常在C++ Memory Model里見到`std::memory_order_seq`

在數(shù)據(jù)安全性方面,要有持久化的保證,一般常用技巧是定期做checkpoint,且有write-ahead log,這在WiredTiger引擎層有原生的支持。

為什么需要它

凡是有副本,有讀寫,就必然存在讀能否讀到最新數(shù)據(jù)的問題,這就屬于一致性的問題。有的業(yè)務(wù)要求必須讀到最新寫入的數(shù)據(jù),此為strongconsistency,但有些業(yè)務(wù)不要求,那數(shù)據(jù)庫可以放開這種強約束,于是有最終一致性eventualconsistency,即意味著給定一定的時間,最終各副本數(shù)據(jù)都會一樣的,這樣的實現(xiàn)比起強一致復(fù)雜度要低很多。

Mongo怎么做的

關(guān)于一致性,我得談?wù)劗?dāng)初自己存在已久的誤解。原來mongo里的quorom 不是我們常說的那種quorum !

以前深入了解過Cassandra,和其C++產(chǎn)品Scylladb,它們的原型是amazon 的Dynamo,論文里談到quorum模型:當(dāng)有N個節(jié)點,如果寫大多數(shù),即 W > N/2,讀也大多數(shù) > N/2,則讀一定可以讀到最新寫入的數(shù)據(jù)。然而mongo雖然也有majority的說法,但其內(nèi)涵完全是另外一回事。

寫mongo時,客戶端只可能寫主,不可能寫從,這與leader-less 系統(tǒng)(無主系統(tǒng),各節(jié)點都是對等的)就不一樣了,從是從主拉數(shù)據(jù)過去的;主從節(jié)點都在維護著一個majoritycommitted 的時間點,當(dāng)寫已經(jīng)到達大多數(shù)時,這個點就會向前推進;

當(dāng)客戶端指定 readConcern: majority 時,能不能讀成功,就看發(fā)起操作的時間點是不是在majoritycommitted 時間點后面,如果是,則majority 讀就是成功的;

Mongo事務(wù)支持快照隔離,即事務(wù)可讀最近穩(wěn)定的一個點,它可能是老數(shù)據(jù),但是它與其它數(shù)據(jù)是一致的,這樣就避免了讀寫沖突。

復(fù)制和故障冗余(Replication, Fault Tolerance)

背景

在分布式系統(tǒng)中,復(fù)制是提高可用性的重要、常規(guī)手段。在復(fù)雜分布式環(huán)境下,總有個別組件就會崩,卡住,不響應(yīng),此時為了不影響用戶的請求,就需要將請求轉(zhuǎn)到正常的節(jié)點上,那數(shù)據(jù)就得有多份,要不然怎么訪問先前訪問的數(shù)據(jù)呢?

故障冗余是個經(jīng)典概念了,分布式里的故障千奇百怪,軟件的,硬件的,人為的;在典型的單主系統(tǒng)里,主節(jié)點要是沒有,就會影響用戶的讀寫,所以在前一個的主節(jié)點沒了的那很短的時刻就必須有新的主來替代它,完美的時候用戶根本感受不到切主。

為什么需要它

正如前面所說保證系統(tǒng)可用性,數(shù)據(jù)安全性。

Mongo怎么做的

Mongo是單主系統(tǒng),寫只能寫主節(jié)點,因此它有選舉機制,靠的是前面的所說的類raft協(xié)議。這是保證故障冗余;

復(fù)制方面,從節(jié)點從主節(jié)點拉oplog,oplog就可理解為raft里的log,它反映了主節(jié)點的mutation,從節(jié)點將這在本地apply,就可達到與主節(jié)點一致的狀態(tài)。

非常詳細(xì)的說明見官方源碼[12]。

內(nèi)核


個人接觸內(nèi)核也沒多久,在此拋磚引玉。

內(nèi)核其實分Server層和Storage Engine層,由于Server接觸不完備,暫只講講引擎層的事兒。

存儲引擎

這里有一份由doxygen生成的文檔[11],值得一閱。

引擎層技術(shù)可謂是數(shù)據(jù)庫系統(tǒng)的核心技術(shù),里面涉及了數(shù)據(jù)庫的核心原理的實現(xiàn)。首先我們要明白,數(shù)據(jù)的組織可以是多種方式,究竟哪個方式好,在代碼未實現(xiàn)出來之前,恐怕還沒法說。

明顯這里我們需要插拔的特性,數(shù)據(jù)庫層(也就是干sql,cql,查詢優(yōu)化,執(zhí)行計劃等的)可以靈活接入多種存儲引擎,這樣最后誰好誰差,比一比就知道了。所以引擎層必須很獨立,提供最原始的接口供上層調(diào)用即可,這也是計算機分層思想在數(shù)據(jù)庫領(lǐng)域的完美體現(xiàn)。

MongoDB引擎從3.x開始就是WiredTiger了,官方似乎一直沒考慮把RocksDB兼容性的代碼放進去,所以MongoRocks是一個第三方的存在;當(dāng)然還有一個in-memory引擎。

WiredTiger

這里簡稱為WT[8]。WT最初是一家由大佬 Michael Cahill 創(chuàng)立的,某一年被MongoDB收購,從此一直是mongo默認(rèn)的存儲引擎。我們可以在這兒[2]看到WT的基本介紹,挺豐富的,沒事可多查閱。

WT首先是一個kv存儲引擎,類別上與Rocksdb一致,不過名氣確實小很多,原因可能是比較小眾,貌似只有mongo用,且代碼看著確實不太易讀;

引擎索引實現(xiàn)是B tree,而不是B+ tree,這一點網(wǎng)上也有不少的討論,至于為何用B tree,據(jù)我所知:

1.mongo著重于提高point query性能,而非range query,這樣不像B+ tree那樣每次都得去葉子節(jié)點拿數(shù)據(jù),平均來看,走更短的路徑;

2.優(yōu)化讀多寫少的場景;

3.其他。

WT API的使用

WT在mongo使用,其實基本的調(diào)用就那么幾個:

1.創(chuàng)建連接conn

wiredtiger_open(home, NULL,"create,cache_size=**, transaction_sync=**, checkpoint_sync=**,...",&conn)

這在啟動時就需調(diào)用,生成一個指向db的WT_CONN,它作為WiredTigerKVEngine的私有成員。

2.創(chuàng)建session

mongo里的操作都有session上下文的,文檔里的session,其實就對應(yīng)引擎層的WT_SESSION ; 代碼里為了高效利用session,有個sessionCache供使用,不用每次都去open

conn->open_session(conn,NULL, "isolation=**", &session)

3.創(chuàng)建表/索引

當(dāng)mongo層執(zhí)行createCollection/createIndex時,即有:
sesssion->create(session, "table::access", "key_format=S,value_format=S"))

4.在session上創(chuàng)建cursor


session->open_cursor(session, "table:mytable", NULL,NULL,&cursor)

5.支持事務(wù)時,在session上開啟事務(wù)


session->begin_transaction(session, "isolation=**, read_timestamp=**,sync=**,...")

6.用cursor set/get key/value

用戶看到的json,mongo server層看到的BSON,其實在底層都轉(zhuǎn)成了(key, value) pair

cursor->set_key(cursor,"key")

cursor->set_value(cursor,"value")

cursor->update(cursor);

7.提交/回滾事務(wù)

session->commit_transaction(session,"commit_timestamp=**, durable_timestamp=**, sync=**,...")

session->rollback_transaction(session,NULL);

對于以上步驟,幾點澄清:

·WT API調(diào)用就像那種風(fēng)格,特別明顯的是會有一參數(shù)char* config,里面就用a=b這種格式來指定各種配置參數(shù)。雖說挺原始的做法;

·有關(guān)時間戳的參數(shù)較為復(fù)雜,需要深入文檔;

·參數(shù)含義還是得參考[2]。

時間戳機制

從官方文檔和視頻[14]中來看,從3.6開始引入 logical session,在WT 的update structure里添加timestamp field等這些動作都是逐漸在為支持事務(wù)、分布式事務(wù)為鋪路。

我為熟悉MongoRocks對事務(wù)的支持接觸過WT的時間戳一些概念,目前還不能很系統(tǒng)地論述各個時間戳之間是如何運作的。這方面可多多參考[2] ,我不在此講了。

MongoRocks

聽名字想必也能猜得到是與rocksdb有關(guān),想到它也很自然,既然底層接kv engine,rocksdb又是kv型,完全可接啊,正如MyRocks那樣??丛创a[3] stars也有300+,最初由開發(fā)者 Igor Canadi 及其他實現(xiàn)了3.2, 3.4的MongoRocks版。項目被擱置一段時間,幾個月前 Igor Canadi 接受了wolfkdy 對MongoRocks 4.0 的MR[16],我在其中參與了相關(guān)PR提交如[4]。

4.0 mongo-rocks 驅(qū)動層的實現(xiàn)主要集中于事務(wù)部分,正如 Igor 所說,3.6.x之后,mongo的內(nèi)部事務(wù)跳躍性大,若正確實現(xiàn)4.0版需很大一部分精力[5]。

MongoRocks 4.0 剛出不久,因此還需更多時間來穩(wěn)定,比如之前由我發(fā)現(xiàn)的oplog讀取有空洞的問題[13],已被作者修復(fù)[15]。個人還是非常期待Rocksdb能接入到Mongo的,相信會有比WT更亮的點!在這方面?zhèn)€人應(yīng)該會投入更多時間,期待有更多國內(nèi)開發(fā)者加入!

內(nèi)核gdb調(diào)試

大型代碼,如果用gdb單步著來學(xué)習(xí)肯定是不行的,單步只適用于調(diào)試bug的時候。我這里談gdb調(diào)試用來干嘛呢? get runtimepath !

我一直認(rèn)為,拿到一份大型C++項目,除了肉眼盯著代碼看半天了解code flow之外,用gdb bt 更是一大利器!在server端加一斷點,客戶端發(fā)一個命令過來,然后一bt ,立刻知道server 走的核心路徑,很方便!

劃重點:請用 >= 8.x 版本的gdb。好處是bt自帶顏色顯示,看著比以前舒服多了。

以下聊聊一般怎么用。

首先啟動一副本集或分片集群(取決于你關(guān)注哪個),對主進行以下設(shè)置:

cfg=rs.conf();cfg.settings.heartbeatTimeoutSecs=3600; cfg.settings.electionTimeoutMillis=3600000;rs.reconfig(cfg)

這里假設(shè)我們要調(diào)試主。為了防止調(diào)試時,默認(rèn)的時間內(nèi)就failover了,所以增大heartbeat,election的超時,這樣主就一直仍是主(當(dāng)然若想調(diào)試主從代碼的code,就不要這么做了)

當(dāng)我們想看看insert命令的請求路徑時,

隨便看看代碼,去搜索一下insert關(guān)鍵字,相信不難發(fā)現(xiàn)有CmdInsert這樣的字眼。再仔細(xì)一看,發(fā)現(xiàn)它繼承一個基類,它還有個run方法,有感覺的開發(fā)者其實這時就能猜一猜了:斷定server收到insert請求時,很可能run要被調(diào)用!

于是乎可在run處加個斷點,或者我們在grep中發(fā)現(xiàn)了insertRecords的字眼,更能判定插入文檔時很可能走了這里,于是有了這樣:

MongoDB的應(yīng)用是怎樣的

可以繼續(xù)enter,這個路徑從libc.so start_thread 到run,到insertRecords 很長的,這一段路徑夠我們分析是怎么走的了。

同樣,對于find, update,delete都是類似手段。

對于事務(wù)操作,可以去grep transaction字樣,也會發(fā)現(xiàn)可以被作為斷點的函數(shù),遇到begin_transaction,commit_transaction, rollback_transaction其實是很熟悉的函數(shù)名稱,適合加上斷點。

結(jié)語


MongoDB技術(shù)淺談在此,這方面知識量非常龐大,確不是由一篇文章能道盡的。對我自己而言,其內(nèi)涵本身是迷人的,因為它是數(shù)據(jù)庫,它是分布式系統(tǒng),它還有許多毛病。盡管Mongo官方縮緊了協(xié)議,一些云廠商沒法玩高版本了。但我想,只要它還是開源的,只要它代碼還是真的,對工程師而言這仍然是一件欣慰的事吧。由淺入深,從此刻開始!

看完上述內(nèi)容,你們掌握MongoDB的應(yīng)用是怎樣的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


網(wǎng)頁標(biāo)題:MongoDB的應(yīng)用是怎樣的
標(biāo)題鏈接:http://weahome.cn/article/jsshpi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部