<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## MongoDB Sharded Cluster 原理 如果你還不了解 MongoDB Sharded cluster,可以先看文檔認識一下 * 中文簡介:[MongoDB Sharded cluster架構原理](https://yq.aliyun.com/articles/32434?spm=5176.8091938.0.0.myHNU1) * 英文匯總:[https://docs.mongodb.com/manual/sharding/](https://docs.mongodb.com/manual/sharding/) ![](https://docs.mongodb.com/manual/_images/sharded-cluster-production-architecture.png) ## 什么時候考慮用 Sharded cluster? 當你考慮使用 Sharded cluster 時,通常是要解決如下2個問題 1. 存儲容量受單機限制,即磁盤資源遭遇瓶頸。 2. 讀寫能力受單機限制(讀能力也可以在復制集里加 secondary 節點來擴展),可能是 CPU、內存或者網卡等資源遭遇瓶頸,導致讀寫能力無法擴展。 如果你沒有遇到上述問題,使用 MongoDB 復制集就足夠了,管理維護上比 Sharded cluster 要簡單很多。 ## 如何確定 shard、mongos 數量? 當你決定要使用 Sharded cluster 時,問題來了,應該部署多少個 shard、多少個 mongos?這個問題首富已經指點過我們,『先定一個小目標,比如先部署上1000個 shard』,然后根據需求逐步擴展。 回到正題,shard、mongos 的數量歸根結底是由應用需求決定,如果你使用 sharding 只是解決 『海量數據存儲』的問題,訪問并不多,那么很簡單,假設你單個 shard 能存儲 M, 需要的存儲總量是 N。 ~~~ numberOfShards = N / M / 0.75 (假設容量水位線為75%) numberOfMongos = 2+ (因為對訪問要求不高,至少部署2個 mongos 做高可用即可) ~~~ 如果你使用 sharding 是解決高并發寫入(或讀取)數據的問題,總的數據量其實很小,這時你部署的 shard、mongos 要能滿足讀寫性能需求,而容量上則不是考量的重點。假設單個 shard 最大 qps 為 M,單個 mongos 最大 qps 為 Ms,需要總的 qps 為 N。 (注:mongos、mongod 的服務能力,需要用戶根據訪問特性來實測得出) ~~~ numberOfShards = Q * / M * / 0.75 (假設負載水位線為75%) numberOfMongos = Q * / Ms / 0.75 ~~~ 如果sharding 要解決上述2個問題,則按需求更高的指標來預估;以上估算是基于sharded cluster 里數據及請求都均勻分布的理想情況,但實際情況下,分布可能并不均衡,這里引入一個『不均衡系數 D』的概念(個人 YY 的,非通用概念),意思是系統里『數據(或請求)分布最多的 shard 是平均值的 D 倍』,實際需要的 shard、mongos 數量,在上述預估上再乘上『不均衡系數 D』。 而為了讓系統的負載分布盡量均勻,就需要合理的選擇 shard key。 ## 如何選擇shard key ? MongoDB Sharded cluster 支持2種分片方式,各有優劣 * [范圍分片](https://docs.mongodb.com/manual/core/ranged-sharding/),通常能很好的支持基于 shard key的范圍查詢 * [Hash 分片](https://docs.mongodb.com/manual/core/hashed-sharding/),通常能將寫入均衡分布到各個 shard 上述2種分片策略都不能解決的問題包括 1. shard key 取值范圍太小(low cardinality),比如將數據中心作為 shard key,而數據中心通常不會很多,分片的效果肯定不好。 2. shard key 某個值的文檔特別多,這樣導致單個 chunk 特別大(及 jumbo chunk),會影響chunk 遷移及負載均衡。 3. 根據非 shard key 進行查詢、更新操作都會變成 scatter-gather 查詢,影響效率。 好的 shard key 應該擁有如下特性: * key 分布足夠離散 (sufficient cardinality) * 寫請求均勻分布 (evenly distributed write) * 盡量避免 scatter-gather 查詢 (targeted read) 舉個例子,某物聯網應用使用 MongoDB Sharded cluster 存儲『海量設備』的『工作日志』,假設設備數量在百萬級別,設備每10s向 MongoDB匯報一次日志數據,日志包含deviceId,timestamp 信息,應用最常見的查詢請求是『查詢某個設備某個時間內的日志信息』。(讀者可以自行預估下,這個量級,無論從寫入還是數據量上看,都應該使用 Sharding,以便能水平擴張)。 * 方案1: 時間戳作為 shard key,范圍分片 * Bad * 新的寫入都是連續的時間戳,都會請求到同一個 shard,寫分布不均 * 根據 deviceId 的查詢會分散到所有 shard 上查詢,效率低 * 方案2: 時間戳作為 shard key,hash 分片 * Bad * 寫入能均分到多個 shard * 根據 deviceId 的查詢會分散到所有 shard 上查詢,效率低 * 方案3:deviceId 作為 shardKey,hash分片(如果 id 沒有明顯的規則,范圍分片也一樣) * Bad * 寫入能均分到多個 shard * 同一個 deviceId 對應的數據無法進一步細分,只能分散到同一個 chunk,會造成 jumbo chunk * 根據 deviceId的查詢只請求到單個 shard,不足的時,請求路由到單個 shard 后,根據時間戳的范圍查詢需要全表掃描并排序 * 方案4:(deviceId, 時間戳)組合起來作為 shardKey,范圍分片(Better) * Good * 寫入能均分到多個 shard * 同一個 deviceId 的數據能根據時間戳進一步分散到多個chunk * 根據 deviceId 查詢時間范圍的數據,能直接利用(deviceId, 時間戳)復合索引來完成。 ## 關于jumbo chunk及 chunk size jumbo chunk 的意思是chunk『太大或者文檔太多』 且無法分裂。 ~~~ If MongoDB cannot split a chunk that exceeds the specified chunk size or contains a number of documents that exceeds the max, MongoDB labels the chunk as jumbo. ~~~ MongoDB 默認的 chunk size 為64MB,如果 chunk 超過64MB 并且不能分裂(比如所有文檔 的 shard key 都相同),則會被標記為jumbo chunk ,balancer 不會遷移這樣的 chunk,從而可能導致負載不均衡,應盡量避免。 一旦出現了 jumbo chunk,如果對負載均衡要求不高,不去關注也沒啥影響,并不會影響到數據的讀寫訪問。如果一定要處理,可以嘗試[如下方法](https://docs.mongodb.com/manual/tutorial/clear-jumbo-flag/) 1. 對 jumbo chunk 進行 split,一旦 split 成功,mongos 會自動清除 jumbo 標記。 2. 對于不可再分的 chunk,如果該 chunk 已不再是 jumbo chunk,可以嘗試手動清除chunk 的 jumbo 標記(注意先備份下 config 數據庫,以免誤操作導致 config 庫損壞)。 3. 最后的辦法,調大 chunk size,當 chunk 大小不再超過 chunk size 時,jumbo 標記最終會被清理,但這個是治標不治本的方法,隨著數據的寫入仍然會再出現 jumbo chunk,根本的解決辦法還是合理的規劃 shard key。 關于 chunk size 如何設置的問題,絕大部分情況下,請直接使用默認 chunk size ,以下場景可能需要調整 chunk size(取值在1-1024之間)。 * 遷移時 IO 負載太大,可以嘗試設置更小的 chunk size * 測試時,為了方便驗證效果,設置較小的 chunk size * 初始 chunk size 設置不合適,導致出現大量 jumbo chunk,影響負載均衡,此時可以嘗試調大 chunk size * 將『未分片的集合』轉換為『分片集合』,如果集合容量太大,可能需要(數據量達到T 級別才有可能遇到)調大 chunk size 才能轉換成功。參考[Sharding Existing Collection Data Size](https://docs.mongodb.com/manual/core/sharded-cluster-requirements/) ## Tag aware sharding [Tag aware sharding](https://docs.mongodb.com/manual/core/tag-aware-sharding/)?是 Sharded cluster 很有用的一個特性,允許用戶自定義一些 chunk 的分布規則。Tag aware sharding 原理如下 1. sh.addShardTag() 給shard 設置標簽 A 2. sh.addTagRange() 給集合的某個 chunk 范圍設置標簽 A,最終 MongoDB 會保證設置標簽 A 的 chunk 范圍(或該范圍的超集)分布設置了標簽 A 的 shard 上。 Tag aware sharding可應用在如下場景 * 將部署在不同機房的 shard 設置『機房標簽』,將不同 chunk 范圍的數據分布到指定的機房 * 將服務能力不通的 shard 設置『服務等級標簽』,將更多的 chunk分散到服務能力更前的 shard 上去。 * … 使用 Tag aware sharding 需要注意是, chunk 分配到對應標簽的 shard 上『不是立即完成,而是在不斷 insert、update 后觸發 split、moveChunk后逐步完成的,并且需要保證 balancer 是開啟的』。所以你可能會觀察到,在設置了 tag range 后一段時間后,寫入仍然沒有分布到tag 相同的 shard 上去。 ## 關于負載均衡 MongoDB Sharded cluster 的自動負載均衡目前是由 mongos 的后臺線程來做的,并且每個集合同一時刻只能有一個遷移任務,負載均衡主要根據集合在各個 shard 上 chunk 的數量來決定的,相差超過一定閾值(跟 chunk 總數量相關)就會觸發chunk遷移。 負載均衡默認是開啟的,為了避免 chunk 遷移影響到線上業務,可以通過設置遷移執行窗口,比如只允許凌晨`2:00-6:00`期間進行遷移。 ~~~ use config db.settings.update( { _id: "balancer" }, { $set: { activeWindow : { start : "02:00", stop : "06:00" } } }, { upsert: true } ) ~~~ 另外,在進行?[sharding 備份](https://docs.mongodb.com/manual/tutorial/backup-sharded-cluster-with-database-dumps/)時(通過 mongos 或者單獨備份config server 和所有 shard),需要停止負載均衡,以免備份出來的數據出現狀態不一致問題。 ~~~ sh.stopBalancer() ~~~ ## moveChunk 歸檔設置 使用3.0及以前版本的 Sharded cluster 可能會遇到一個問題,停止寫入數據后,數據目錄里的磁盤空間占用還會一直增加。 上述行為是由`sharding.archiveMovedChunks`配置項決定的,該配置項在3.0及以前的版本默認為 true,即在move chunk 時,源 shard 會將遷移的 chunk 數據歸檔一份在數據目錄里,當出現問題時,可用于恢復。也就是說,chunk 發生遷移時,源節點上的空間并沒有釋放出來,而目標節點又占用了新的空間。 在3.2版本,該配置項默認值也被設置為 false,默認不會對 moveChunk 的數據在源 shard 上歸檔。 ## recoverShardingState 設置 使用 MongoDB Sharded cluster 時,還可能遇到一個問題,就是啟動 shard后,shard 不能正常服務,『Primary 上調用 ismaster 時,結果卻為 true,也無法正常執行其他命令』,其狀態類似如下: ~~~ mongo-9003:PRIMARY> db.isMaster() { "hosts" : [ "host1:9003", "host2:9003", "host3:9003" ], "setName" : "mongo-9003", "setVersion" : 9, "ismaster" : false, // primary 的 ismaster 為 false??? "secondary" : true, "primary" : "host1:9003", "me" : "host1:9003", "electionId" : ObjectId("57c7e62d218e9216c70aa3cf"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2016-09-01T12:29:27.113Z"), "maxWireVersion" : 4, "minWireVersion" : 0, "ok" : 1 } ~~~ 查看其錯誤日志,會發現 shard 一直無法連接上 config server,上述行為是由 sharding.recoverShardingState 選項決定,默認為 true,也就是說,shard 啟動時,其會連接 config server 進行 sharding 狀態的一些初始化,而如果 config server 連不上,初始化工作就一直無法完成,導致 shard 狀態不正常。 有同學在將 Sharded cluster 所有節點都遷移到新的主機上時遇到了上述問題,因為 config server 的信息發生變化了,而 shard 啟動時還會連接之前的 config server,通過在啟動命令行加上?`--setParameter recoverShardingState=false`來啟動 shard 就能恢復正常了。 上述默認設計的確有些不合理,config server 的異常不應該去影響 shard,而且最終的問題的表象也很不明確,在3.4大版本里,MongoDB 也會對這塊進行修改,去掉這個參數,默認不會有 recoverShardingState 的邏輯,具體參考?[SERVER-24465](https://jira.mongodb.org/browse/SERVER-24465)。 ## 要關注的問題好多,hold 不住怎么破? 阿里云已經推出了[MongoDB 云數據庫](https://www.aliyun.com/product/mongodb)服務,幫助廣大開發者解決 MongoDB 運維管理的所有問題,讓開發者專注于業務開發。[MongoDB 云數據庫](https://www.aliyun.com/product/mongodb)?目前已支持三節點高可用復制集,Sharded cluster 的功能正在緊鑼密鼓的研發中,敬請關注。 使用 MongoDB sharding 遇到問題歡迎到?[云棲社區](https://yq.aliyun.com/users/1134812/own?spm=5176.100238.headermenu.5.LiI3la#information)?或[MongoDB 中文社區](http://www.mongoing.com/)?一塊交流探討。 ## 參考資料 * [Everything You Need to Know About Sharding](https://www.mongodb.com/presentations/webinar-everything-you-need-know-about-sharding?jmp=docs&_ga=1.113926660.2005306875.1453858874) * [MongoDB for Time Series Data: Sharding](https://www.mongodb.com/presentations/mongodb-time-series-data-part-3-sharding?jmp=docs&_ga=1.136350259.2005306875.1453858874) * [Hashed Sharding](https://docs.mongodb.com/manual/core/hashed-sharding/) * [Ranged Sharding](https://docs.mongodb.com/manual/core/ranged-sharding/) * [Dealing with Jumbo Chunks in MongoDB](https://www.percona.com/blog/2016/04/11/dealing-with-jumbo-chunks-in-mongodb/) * [Tag aware sharding](https://docs.mongodb.com/manual/core/tag-aware-sharding/) * [Sharding backup](https://docs.mongodb.com/manual/tutorial/backup-sharded-cluster-with-database-dumps/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看