婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > MongoDB中的一些坑(最好不要用)

MongoDB中的一些坑(最好不要用)

熱門標(biāo)簽:兗州電話外呼營(yíng)銷系統(tǒng) 機(jī)器人外呼系統(tǒng)軟件存在問(wèn)題 企業(yè)智能外呼系統(tǒng)價(jià)格多少 福州電銷機(jī)器人源代碼 徐州ai電銷機(jī)器人原理 高德地圖標(biāo)注商戶位置 智能電銷機(jī)器人銷售話術(shù) 南京400電話怎樣辦理 沈陽(yáng)營(yíng)銷電銷機(jī)器人招商

MongoDB 是目前炙手可熱的 NoSQL 文檔型數(shù)據(jù)庫(kù),它提供的一些特性很棒:如自動(dòng) failover 機(jī)制,自動(dòng) sharding,無(wú)模式 schemaless,大部分情況下性能也很棒。但是薄荷在深入使用 MongoDB 過(guò)程中,遇到了不少問(wèn)題,下面總結(jié)幾個(gè)我們遇到的坑。特別申明:我們目前用的 MongoDB 版本是 2.4.10,曾經(jīng)升級(jí)到 MongoDB 2.6.0 版本,問(wèn)題依然存在,又回退到 2.4.10 版本。

MongoDB 數(shù)據(jù)庫(kù)級(jí)鎖

坑爹指數(shù):5星(最高5星)

MongoDB的鎖機(jī)制和一般關(guān)系數(shù)據(jù)庫(kù)如 MySQL(InnoDB), Oracle 有很大的差異,InnoDB 和 Oracle 能提供行級(jí)粒度鎖,而 MongoDB 只能提供 庫(kù)級(jí)粒度鎖,這意味著當(dāng) MongoDB 一個(gè)寫鎖處于占用狀態(tài)時(shí),其它的讀寫操作都得干等。

初看起來(lái)庫(kù)級(jí)鎖在大并發(fā)環(huán)境下有嚴(yán)重的問(wèn)題,但是 MongoDB 依然能夠保持大并發(fā)量和高性能,這是因?yàn)?MongoDB 的鎖粒度雖然很粗放,但是在鎖處理機(jī)制和關(guān)系數(shù)據(jù)庫(kù)鎖有很大差異,主要表現(xiàn)在:

MongoDB 沒(méi)有完整事務(wù)支持,操作原子性只到單個(gè) document 級(jí)別,所以通常操作粒度比較小;
MongoDB 鎖實(shí)際占用時(shí)間是內(nèi)存數(shù)據(jù)計(jì)算和變更時(shí)間,通常很快;
MongoDB 鎖有一種臨時(shí)放棄機(jī)制,當(dāng)出現(xiàn)需要等待慢速 IO 讀寫數(shù)據(jù)時(shí),可以先臨時(shí)放棄,等 IO 完成之后再重新獲取鎖。
通常不出問(wèn)題不等于沒(méi)有問(wèn)題,如果數(shù)據(jù)操作不當(dāng),依然會(huì)導(dǎo)致長(zhǎng)時(shí)間占用寫鎖,比如下面提到的前臺(tái)建索引操作,當(dāng)出現(xiàn)這種情況的時(shí)候,整個(gè)數(shù)據(jù)庫(kù)就處于完全阻塞狀態(tài),無(wú)法進(jìn)行任何讀寫操作,情況十分嚴(yán)重。

解決問(wèn)題的方法,盡量避免長(zhǎng)時(shí)間占用寫鎖操作,如果有一些集合操作實(shí)在難以避免,可以考慮把這個(gè)集合放到一個(gè)單獨(dú)的 MongoDB 庫(kù)里,因?yàn)?MongoDB 不同庫(kù)鎖是相互隔離的,分離集合可以避免某一個(gè)集合操作引發(fā)全局阻塞問(wèn)題。

建索引導(dǎo)致數(shù)據(jù)庫(kù)阻塞

坑爹指數(shù):3星

上面提到了 MongoDB 庫(kù)級(jí)鎖的問(wèn)題,建索引就是一個(gè)容易引起長(zhǎng)時(shí)間寫鎖的問(wèn)題,MongoDB 在前臺(tái)建索引時(shí)需要占用一個(gè)寫鎖(而且不會(huì)臨時(shí)放棄),如果集合的數(shù)據(jù)量很大,建索引通常要花比較長(zhǎng)時(shí)間,特別容易引起問(wèn)題。

解決的方法很簡(jiǎn)單,MongoDB 提供了兩種建索引的訪問(wèn),一種是 background 方式,不需要長(zhǎng)時(shí)間占用寫鎖,另一種是非 background 方式,需要長(zhǎng)時(shí)間占用鎖。使用 background 方式就可以解決問(wèn)題。 例如,為超大表 posts 建立索引, 千萬(wàn)不用使用

復(fù)制代碼 代碼如下:

db.posts.ensureIndex({user_id: 1})

而應(yīng)該使用

復(fù)制代碼 代碼如下:

db.posts.ensureIndex({user_id: 1}, {background: 1})

不合理使用嵌入 embed document

坑爹指數(shù):5星

embed document 是 MongoDB 相比關(guān)系數(shù)據(jù)庫(kù)差異明顯的一個(gè)地方,可以在某一個(gè) document 中嵌入其它子 document,這樣可以在父子 document 保持在單一 collection 中,檢索修改比較方便。

比如薄荷的應(yīng)用情景中有一個(gè) Group document,用戶申請(qǐng)加入 Group 建模為 GroupRequest document,我們最初的時(shí)候使用 embed 方式把 GroupRequest 放置到 Group 中。 Ruby 代碼如下所示(使用了 Mongoid ORM):

復(fù)制代碼 代碼如下:

class Group
  include Mongoid::Document
  ...
  embeds_many :group_requests
  ...
end

class GroupRequest
  include Mongoid::Document
  ...
  embedded_in :group
  ...
end


這個(gè)使用方式讓我們掉到坑里了,差點(diǎn)就爬不出來(lái),它導(dǎo)致有接近兩周的時(shí)間系統(tǒng)問(wèn)題,高峰時(shí)段常有幾分鐘的系統(tǒng)卡頓,最嚴(yán)重一次甚至引起 MongoDB 宕機(jī)。

仔細(xì)分析后,發(fā)現(xiàn)某些活躍的 Group 的 group_requests 增加(當(dāng)有新申請(qǐng)時(shí))和更改(當(dāng)通過(guò)或拒絕用戶申請(qǐng)時(shí))異常頻繁,而這些操作經(jīng)常長(zhǎng)時(shí)間占用寫鎖,導(dǎo)致整個(gè)數(shù)據(jù)庫(kù)阻塞。原因是當(dāng)有增加 group_request 操作時(shí),Group 預(yù)分配的空間不夠,需要重新分配空間(內(nèi)存和硬盤都需要),耗時(shí)較長(zhǎng),另外 Group 上建的索引很多,移動(dòng) Group 位置導(dǎo)致大量索引更新操作也很耗時(shí),綜合起來(lái)引起了長(zhǎng)時(shí)間占用鎖問(wèn)題。

解決問(wèn)題的方法,說(shuō)起來(lái)也簡(jiǎn)單,就是把 embed 關(guān)聯(lián)更改成的普通外鍵關(guān)聯(lián),就是類似關(guān)系數(shù)據(jù)庫(kù)的做法,這樣 group_request 增加或修改都只發(fā)生在 GroupRequest 上,簡(jiǎn)單快速,避免長(zhǎng)時(shí)間占用寫鎖問(wèn)題。當(dāng)關(guān)聯(lián)對(duì)象的數(shù)據(jù)不固定或者經(jīng)常發(fā)生變化時(shí),一定要避免使用 embed 關(guān)聯(lián),不然會(huì)死的很慘。

不合理使用 Array 字段

坑爹指數(shù):4星

MongoDB 的 Array 字段是比較獨(dú)特的一個(gè)特性,它可以在單個(gè) document 里存儲(chǔ)一些簡(jiǎn)單的一對(duì)多關(guān)系。

薄荷有一個(gè)應(yīng)用情景使用遇到嚴(yán)重的性能問(wèn)題,直接上代碼如下所示:

復(fù)制代碼 代碼如下:

class User
  include Mongoid::Document
  ...
  field :follower_user_ids, type: Array, default: []
  ...
end

User 中通過(guò)一個(gè) Array 類型字段 follower_user_ids 保存用戶關(guān)注的人的 id,用戶關(guān)注的人從 10個(gè)到 3000 個(gè)不等,變化是比較頻繁的,和上面 embed 引發(fā)的問(wèn)題類似,頻繁的 follower_user_ids 增加修改操作導(dǎo)致大量長(zhǎng)時(shí)間數(shù)據(jù)庫(kù)寫鎖,從而引發(fā) MongoDB 數(shù)據(jù)庫(kù)性能急劇下降。

解決問(wèn)題的方法:我們把 follower_user_ids 轉(zhuǎn)移到了內(nèi)存數(shù)據(jù)庫(kù) redis 中,避免了頻繁更改 MongoDB 中的 User, 從而徹底解決問(wèn)題。如果不使用 redis,也可以建立一個(gè) UserFollower 集合,使用外鍵形式關(guān)聯(lián)。

先列舉上面幾個(gè)坑吧,都是害人不淺的陷阱,使用 MongoDB 過(guò)程一定要多加注意,避免掉到坑里。

您可能感興趣的文章:
  • MongoDB常用操作命令大全
  • MongoDB各種查詢操作詳解
  • MongoDB 語(yǔ)法使用小結(jié)
  • Mongodb 忘記密碼的解決辦法
  • mongos崩潰后無(wú)法重啟問(wèn)題的解決方法

標(biāo)簽:邯鄲 吉安 本溪 景德鎮(zhèn) 大理 昭通 鶴崗 丹東

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MongoDB中的一些坑(最好不要用)》,本文關(guān)鍵詞  MongoDB,中的,一些,坑,最,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MongoDB中的一些坑(最好不要用)》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于MongoDB中的一些坑(最好不要用)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 渭南市| 溧阳市| 巴林右旗| 西昌市| 波密县| 上犹县| 历史| 肥东县| 乐安县| 桐城市| 二连浩特市| 博客| 界首市| 孟州市| 攀枝花市| 开封市| 奇台县| 高平市| 股票| 台湾省| 丹东市| 青海省| 宁南县| 阿克陶县| 荔浦县| 乾安县| 天津市| 日喀则市| 志丹县| 梅河口市| 略阳县| 永州市| 昔阳县| 安乡县| 广宗县| 油尖旺区| 泰来县| 墨江| 仁寿县| 新疆| 四平市|