日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MongoDB的分片集群

發(fā)布時間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MongoDB的分片集群 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

分片集群簡介

在之前有說過關(guān)于MongoDB的復(fù)制集,復(fù)制集主要用來實現(xiàn)自動故障轉(zhuǎn)移從而達(dá)到高可用的目的,然而,隨著業(yè)務(wù)規(guī)模的增長和時間的推移,業(yè)務(wù)數(shù)據(jù)量會越來越大,當(dāng)前業(yè)務(wù)數(shù)據(jù)可能只有幾百GB不到,一臺DB服務(wù)器足以搞定所有的工作,而一旦業(yè)務(wù)數(shù)據(jù)量擴(kuò)充大幾個TB幾百個TB時,就會產(chǎn)生一臺服務(wù)器無法存儲的情況,此時,需要將數(shù)據(jù)按照一定的規(guī)則分配到不同的服務(wù)器進(jìn)行存儲、查詢等,即為分片集群。分片集群要做到的事情就是數(shù)據(jù)分布式存儲。

分片部署架構(gòu)

架構(gòu)設(shè)計

先看一張圖:

先做一些解釋:
1.shard片:一般為一臺單獨的服務(wù)器,即為一個數(shù)據(jù)存儲節(jié)點,這個存儲節(jié)點需要做復(fù)制集,實現(xiàn)高可用以及自動故障轉(zhuǎn)移,一般一個分片集群有多個shard片;
2. config服務(wù)器:主要是記錄shard的配置信息(元信息metadata),如數(shù)據(jù)存儲目錄,日志目錄,端口號,是否開啟了journal等信息,為了保證config服務(wù)器的可用性,也做了復(fù)制集處理,注意,一旦配置服務(wù)器無法使用,則整個集群就不能使用了,一般是獨立的三臺服務(wù)器實現(xiàn)冗余備份,這三臺可能每一臺是獨立的復(fù)制集架構(gòu)。
3.Mongos路由進(jìn)程(Router):應(yīng)用程序通過驅(qū)動程序直接連接router,router啟動時從配置服務(wù)器復(fù)制集中讀取shared信息,然后將數(shù)據(jù)實際寫入或讀取(路由)到具體的shard中。

部署配置

注意:此處由于我這邊只有一臺服務(wù)器(PC機(jī)),所以這里實現(xiàn)的是一個偽集群,部署架構(gòu)如圖所示:

一個Shard(復(fù)制集模式),一個config進(jìn)程,一個router進(jìn)程,均在同一臺服務(wù)器上面

沿用上一節(jié)的復(fù)制集作為shard,

啟動:

mongod --dbpath=D:\MongoDB\Server\3.2\data\rs0_0 --logpath=D:\MongoDB\Server\3.2\logs\rs0_0.log --port=40000 --replSet=rs0 mongod --dbpath=D:\MongoDB\Server\3.2\data\rs0_1 --logpath=D:\MongoDB\Server\3.2\logs\rs0_1.log --port=40001 --replSet=rs0 mongod --dbpath=D:\MongoDB\Server\3.2\data\rs0_2 --logpath=D:\MongoDB\Server\3.2\logs\rs0_2.log --port=40002 --replSet=rs0

配置服務(wù)器啟動:

mongod --dbpath=D:\MongoDB\Server\3.2\data\db_config --logpath=D:\MongoDB\Server\3.2\logs\dbconfig.log --port=40003 --configsvr

路由服務(wù)器啟動

mongos --logpath=D:\MongoDB\Server\3.2\logs\dbrouter.log --port=40004 --configdb=linfl-PC:40003

添加分片信息到集群:

mongo --port 40004 mongos> use admin switched to db admin mongos> sh.addShard("rs0/linfl-PC:40000,linfl-PC:40001") {"ok" : 0,"errmsg" : "can't add shard 'rs0/linfl-PC:40000,linfl-PC:40001' because a local database 'config' exists in another config","code" : 96 }

報錯了,原來的rs0由于已經(jīng)存在config數(shù)據(jù)庫了,去把他刪掉:

D:\MongoDB\Server\3.2\bin>mongo --port 40000 2017-02-27T16:14:51.454+0800 I CONTROL [main] Hotfix KB2731284 or later update is not installed, will zero-out data files MongoDB shell version: 3.2.9 connecting to: 127.0.0.1:40000/test rs0:PRIMARY> show dbs cms 0.000GB config 0.000GB local 0.000GB test 0.000GB rs0:PRIMARY> use config switched to db config rs0:PRIMARY> db.dropDatabase() { "dropped" : "config", "ok" : 1 }

然后重新連接到4004執(zhí)行添加分片即可,看下狀態(tài):

D:\MongoDB\Server\3.2\bin>mongo --port 40004 2017-02-27T16:15:17.286+0800 I CONTROL [main] Hotfix KB2731284 or later update is not installed, will zero-out data files MongoDB shell version: 3.2.9 connecting to: 127.0.0.1:40004/test mongos> sh.addShard("rs0/linfl-PC:40000,linfl-PC:40001") { "shardAdded" : "rs0", "ok" : 1 } mongos> sh.status() --- Sharding Status ---sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("58b3d9df84493cb599359c8b") }shards:{ "_id" : "rs0", "host" : "rs0/linfl-PC:40000,linfl-PC:40001" }active mongoses:"3.2.9" : 1balancer:Currently enabled: yesCurrently running: noFailed balancer rounds in last 5 attempts: 5Last reported error: remote client 192.168.56.1:51845 tried to initiali ze this host as shard rs0, but shard name was previously initialized as configTime of Reported error: Mon Feb 27 2017 16:15:48 GMT+0800Migration Results for the last 24 hours:No recent migrationsdatabases:{ "_id" : "cms", "primary" : "rs0", "partitioned" : false }{ "_id" : "test", "primary" : "rs0", "partitioned" : false }

對config數(shù)據(jù)庫中的各個集合做如下解釋:

mongos> use config switched to db config mongos> show collections actionlog // changelog //保存被分片的集合的任何元數(shù)據(jù)的改變信息,如chunks的遷移,分割等 chunks //集群中所有的塊信息,塊的數(shù)據(jù)范圍以及塊所在的片 databases //集群中所有的數(shù)據(jù)庫 lockpings //追蹤集群中的激活組件 locks//均衡器產(chǎn)生的鎖信息 mongos//所有路由信息 settings//分片集群的配置信息,如chunk大小,均衡器狀態(tài)等 shards//集群中所有的片信息 tags version//元信息版本

注意:對集群的操作應(yīng)該都是通過客戶端連接mongos路由來執(zhí)行。

正常來講,一個完整的生產(chǎn)環(huán)境至少需要9個Mongod實例,一個Mongos實例,10臺機(jī)器才能組成,而由于可以對部分實例采用合并在一臺機(jī)器上進(jìn)行部署的操作(對資源消耗較低,或?qū)Y源消耗的類型不同),能夠得到典型的部署結(jié)構(gòu)如下:

以上部署方案使得每個shard(復(fù)制集)中的節(jié)點完全分開到不同的服務(wù)器上,并將config服務(wù)分開,使得其中任何一臺服務(wù)器宕機(jī),集群都可正常工作,當(dāng)然我認(rèn)為,最少只需要三臺服務(wù)器即可構(gòu)成穩(wěn)定的集群(3壞1可正常工作),然而卻非典型的架構(gòu)了。

分片工作機(jī)制

MongoDB的分片是基于集合(表)來進(jìn)行的,要對一個集合分片,就要像使其所在的數(shù)據(jù)庫支持分片。

集合分片

MongoDB的分片是基于返回的,即任何一個文檔一定位于指定片鍵的某個范圍內(nèi),一單片鍵選擇好以后,chunks就會按照片鍵將一部分documents從邏輯上組合在一起
如:對users集合選擇city作為片鍵來分片,如果city字段中存在 ‘beijing’,’guangzhou’,’changsha’,初始時隨機(jī)的向集群中插入文檔,由于初始時chunks比較小,沒有達(dá)到閾值64MB或10000個文檔,不需要分片,隨著繼續(xù)插入,超過chunk閾值后chunk被分割成兩個,最終分步可能如下所示:

開始鍵值 – 結(jié)束鍵值 –所在分片
開始鍵值 結(jié)束鍵值 所在分片

開始鍵值結(jié)束鍵值所在分片
-∞beijingrs0
beijingchangshars1
changshaguangzhours0
guangzhours1

需要注意的是:chunks所包含的文檔并非物理上包含,而是一種邏輯包含,指標(biāo)是帶有片鍵的文檔會落在那個范圍內(nèi)。

使集合支持分片,必須先使數(shù)據(jù)庫支持分片:

sh.enableSharding('cms')

對于已有的集合如果要分片,那么選定片鍵后,需要在片鍵上面首先創(chuàng)建索引,如果集合初始狀態(tài)為空,則自動創(chuàng)建索引
查看rs.status()可以看到,如下信息片段:

databases:{ "_id" : "cms", "primary" : "rs0", "partitioned" : true }{ "_id" : "test", "primary" : "rs0", "partitioned" : false }

證明 cms已經(jīng)支持分片

在已存在的集合中分片
先創(chuàng)建索引:

db.user.ensureIndex({city:1}) sh.shardCollection("cms.users",{city:1})

注意:由于我本地是單臺PC,做分片后看不到效果,但如果有兩個分片,分別為rs0,與rs1,往users中插入數(shù)據(jù),最后的結(jié)果會是

通過

db.changelog.find()

可以看到具體的塊分割過程,當(dāng)存儲的chunk小于64MB時,不分割,當(dāng)大于64MB時,開始分割成兩部分,-∞~beijing,beijing~∞,隨著數(shù)據(jù)的進(jìn)一步增大,beijing~∞被繼續(xù)分割成beijing~guangzhou,guangzhou~∞,這樣,rs0就有三個chunk了,隨后,-∞到beijing的chunk開始發(fā)生轉(zhuǎn)移,從rs0遷移到rs1上面去,依次類推,MongDB就是這樣實現(xiàn)了海量數(shù)據(jù)的分布式存儲的。

集群平衡器

在上一步的操作中最后講到了塊chunk從rs0遷移到rs1的操作,這個動作是由 平衡器的后臺進(jìn)程自動完成的。

當(dāng)一個被分片的集合的所有chunk在集群中分布不均衡時(如200個chunk在rs0,50個在rs1上),平衡器就會將chunk從最多的片上遷移到最少的片上,直到chunk數(shù)量基本相等為止。平衡器會根據(jù)chunk數(shù)量的不同,有不同的規(guī)則觸發(fā)塊遷移,默認(rèn)配置為chunk<20,閾值為2,20 < chunk<79閾值為4,chunk>80,閾值為8,這也就是為什么我們在剛才要在chunk為3時才能看到遷移過程的變化。
基本的chunk遷移流程如下所示:

本示例中源片指的是rs0,目標(biāo)片指的是rs1

集群的寫、讀

集群的讀、寫與單個MongoDB的讀寫是一樣的,對應(yīng)用程序時透明的,這里主要看分片集群對性能的影響。

片鍵是決定查詢落到哪一個chunk上的依據(jù),這個信息保存在配置服務(wù)器上,而索引是針對每個片上的集合來說的,每個片都會為自己的集合創(chuàng)建索引數(shù)據(jù),因此,查詢語句中是否包含片鍵與索引對查詢性能影響較大
可以通過explain解釋執(zhí)行查看,需要注意幾個點:

nscanned:查詢用到索引時,索引中掃描的文檔數(shù)
nscannedObjects:在集合中掃描的文檔數(shù)
nscannedAllPlans:所有查詢計劃中掃描的文檔總數(shù)
nscanned:選定的某一種查詢計劃下掃描的文檔總數(shù)

片鍵選擇策略

好的片鍵應(yīng)該具有如下特質(zhì):

  • 分發(fā)寫操作
  • 讀操作不能太過隨機(jī)化(盡量局部化)
  • 保證chunk能夠一直被分割
  • 通常我們需要由幾個字段組合作為片鍵,如city+_id,既能夠保證同一city下的文檔盡量分布在同一個片上,_id則保證了chunk能夠一直被分割。

    在實際業(yè)務(wù)中可以考慮order表中 company_id與create_date或id共同組成片鍵。

    注意

    只有當(dāng)數(shù)據(jù)量很大、讀寫請求很高時才適合用分片集群。

    參考鏈接

    https://docs.mongodb.com/manual/core/sharded-cluster-components

    總結(jié)

    以上是生活随笔為你收集整理的MongoDB的分片集群的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。