溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MongoDB中怎么實現(xiàn)分片管理

發(fā)布時間:2021-07-16 16:00:58 來源:億速云 閱讀:153 作者:Leah 欄目:云計算

本篇文章為大家展示了MongoDB中怎么實現(xiàn)分片管理,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

一、分片概念

1.數(shù)據(jù)塊

塊也叫區(qū)間,可能存在一分片一區(qū)間和一分片多區(qū)間兩種情況。

一分片一區(qū)間:數(shù)據(jù)不會在片之間自動移動來保持分片的數(shù)據(jù)的均勻性,需要手動拆分分片來移動數(shù)據(jù)。

而一分片多區(qū)間情況:一個數(shù)據(jù)塊默認64MB,當(dāng)數(shù)據(jù)塊達到64MB時就會創(chuàng)建新的塊,當(dāng)然前提是當(dāng)前的粒度還允許再拆分,平衡器會保證每個分片數(shù)據(jù)塊的均勻。但是移動塊也遵循分片的原則,塊之間的數(shù)據(jù)集不能有交集。

比如一個塊[50-100)現(xiàn)在拆分成兩個塊,那么默認會拆分成[50-75)[75-100)兩個塊,如果當(dāng)前分片塊比其它分片的塊大于9那么可能[75-100)改塊會被移動到新的分片當(dāng)中。

2.平衡器

平衡器(balancer)負責(zé)數(shù)據(jù)的遷移。它會周期性地檢查分片間是否存在不平衡,如果存在,則會開啟塊的遷移。不平衡的表現(xiàn)指,一個分片明顯比其他分片擁有更多的塊。假如有一些集合達到了閾值,平衡器則會開始做塊遷移。它會從負載比較比較大的分片中選擇一個塊,并詢問該分片是否需要在遷移之前對塊進行拆分。完成必要的拆分后,就會將塊遷移至數(shù)量比較少的機器上。

二、分片查詢

1.查詢?nèi)杭癄顟B(tài)

需要顯示隱藏的分片信息執(zhí)行

2.檢查配置信息

所有的配置信息都保存在配置服務(wù)器的config數(shù)據(jù)庫中。

MongoDB中怎么實現(xiàn)分片管理

actionlog

記錄平衡器的相關(guān)操作日志。

changelog

跟蹤記錄集群的操作,包括集合分片操作、塊拆分和遷移、添加刪除分片等。例如塊拆分信息:

db.getCollection('changelog').find({"what":/split/}).sort({"time":-1}).limit(2)

每次數(shù)據(jù)庫塊移動都會創(chuàng)建插入4條記錄到changelog文檔總,分別是start、commit、from、to

{

    "_id" : "backup-2018-04-09T15:52:26.656+0800-5acb1bbaebfa528b3521327c",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:26.656Z"),

    "what" : "moveChunk.start",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "from" : "rs-b",

        "to" : "rs-a"

    }

}

 

/* 2 */

{

    "_id" : "backup-2018-04-09T15:52:29.289+0800-5acb1bbdebfa528b35213335",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:29.289Z"),

    "what" : "moveChunk.commit",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "from" : "rs-b",

        "to" : "rs-a"

    }

}

 

/* 3 */

{

    "_id" : "backup-2018-04-09T15:52:29.297+0800-5acb1bbdebfa528b3521333a",

    "server" : "backup",

    "clientAddr" : "192.168.137.30:53996",

    "time" : ISODate("2018-04-09T07:52:29.297Z"),

    "what" : "moveChunk.from",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "step 1 of 6" : 0,

        "step 2 of 6" : 10,

        "step 3 of 6" : 153,

        "step 4 of 6" : 2061,

        "step 5 of 6" : 402,

        "step 6 of 6" : 24,

        "to" : "rs-a",

        "from" : "rs-b",

        "note" : "success"

    }

}

 

/* 4 */

{

    "_id" : "master-2018-04-09T15:52:29.307+0800-5acb1bbd7bc60438ea626411",

    "server" : "master",

    "clientAddr" : "",

    "time" : ISODate("2018-04-09T07:52:29.307Z"),

    "what" : "moveChunk.to",

    "ns" : "test.person",

    "details" : {

        "min" : {

            "_id" : { "$minKey" : 1 }

        },

        "max" : {

            "_id" : 1.0

        },

        "step 1 of 6" : 22,

        "step 2 of 6" : 11,

        "step 3 of 6" : 4,

        "step 4 of 6" : 0,

        "step 5 of 6" : 2042,

        "step 6 of 6" : 373,

        "note" : "success"

    }

}

View Code

details字段中的每一步表示的都是時間,"step N of 6"信息以毫秒為單位顯示步驟耗時的長短。

當(dāng)from分片收到mongos發(fā)來的moveChunks命令時,它會做如下操作:

(1).檢查命令參數(shù);

(2)向配置服務(wù)器申請獲得一個分布鎖,以便進入遷移過程;

(3)嘗試連接到to分片;

(4)復(fù)制數(shù)據(jù)

(5)與to分片和配置服務(wù)器一起確認遷移是否成功完成。

當(dāng)to分片收到from分片發(fā)來的命令時,它會執(zhí)行如下操作:

(1)遷移索引;

(2)刪除塊范圍內(nèi)已經(jīng)存在的任何數(shù)據(jù);

(3)將塊中的所有文檔復(fù)制到to分片;

(4)在to分片上運行復(fù)制期間對這些文檔所執(zhí)行過的操作;

(5)等待to分片將遷移過來的數(shù)據(jù)復(fù)制到副本集的大多數(shù)服務(wù)器上。

(6)標(biāo)志遷移是否執(zhí)行成功。

chunks

存儲集合分片所有塊信息

collections

記錄所有分片集合信息,該記錄中的記錄不會因為分片集合被刪除而被清除。

databases

MongoDB中怎么實現(xiàn)分片管理

記錄集群中數(shù)據(jù)庫的信息,不管數(shù)據(jù)庫有沒有分片。如數(shù)據(jù)庫開啟了分片,那么"partitioned" :字段的值為true。"primary"記錄數(shù)據(jù)庫所屬的主分片。所有新集合默認創(chuàng)建在數(shù)據(jù)庫主分片上。比如當(dāng)前的集合在某個分片上面還沒有數(shù)據(jù)那么不會在該分片上創(chuàng)建集合。所以如果某個分片存在分片的集合,那么必須將集合的數(shù)據(jù)移走或者將集合刪除,否則該分片無法刪除。

lockpings

記錄分片運行是否正常的ping記錄信息

locks

記錄存儲分布式鎖操作信息。

migrations

mongos

記錄mongos的相關(guān)信息,記錄每一個mongos實例的信息。

settings

包含平衡器和塊的設(shè)置信息等。

shards

群集分片信息

tags

記錄分片標(biāo)簽信息

transactions

version

群集版本信息

注意:如果需要修改配置信息,需要通過連接到mongos切換到config數(shù)據(jù)庫操作而不是直接連接到配置服務(wù)器中操作。

參考:https://docs.mongodb.com/manual/reference/config-database/

3.查看網(wǎng)絡(luò)連接

db.adminCommand({"connPoolStats":1})

4.限制連接數(shù)量

mongos可以接受的最大并發(fā)連接數(shù)。如果此設(shè)置高于操作系統(tǒng)配置的最大連接跟蹤閾值,則此設(shè)置無效。

注意:在版本2.6中MongoDB刪除了maxIncomingConnections 設(shè)置的上限。

三、分片管理

1.添加分片

use admin

db.auth("dba","dba")

sh.addShard("rs-a/192.168.137.10:27010,192.168.137.10:27011,192.168.137.10:27012");

sh.addShard("rs-b/192.168.137.20:28010,192.168.137.20:28011,192.168.137.20:28012");

sh.addShard("rs-c/192.168.137.30:26010,192.168.137.30:26011,192.168.137.30:26012");

sh.status();

2.刪除分片

先當(dāng)前分片對應(yīng)數(shù)據(jù)庫挪到其它的分片上。這里的"products"指的是數(shù)據(jù)庫名

db.runCommand( { movePrimary: "products", to: "rs-b" })

然后再刪除分片

db.runCommand({"removeShard":"rs-c"});

MongoDB中怎么實現(xiàn)分片管理

 MongoDB中怎么實現(xiàn)分片管理

注意:需要多次執(zhí)行db.runCommand({"removeShard":"rs-c"});命令來刪除分片,首先平衡器會將分片上的數(shù)據(jù)進行遷移,可以通過sh.isBalancerRunning()命令查詢是否遷移完成,遷移完成之后再次執(zhí)行刪除分片命令徹底移除分片。

MongoDB中怎么實現(xiàn)分片管理

3.平衡器管理

3.1開啟平衡器

use admin
sh.startBalancer()
或者
sh.setBalancerState(true)

3.2關(guān)閉平衡器

use admin
sh.stopBalancer()
或者
sh.setBalancerState(false);

查看是否關(guān)閉,返回flase標(biāo)識平衡器已關(guān)閉,還需要查詢均衡器正在運行情況

sh.getBalancerState();

while( sh.isBalancerRunning() ) {

          print("waiting...");

          sleep(1000);

}

在執(zhí)行數(shù)據(jù)庫管理操作之前應(yīng)該關(guān)閉平衡器,關(guān)閉平衡器之后,系統(tǒng)不會再進入平衡過程, 但是均衡器的關(guān)閉不是立即就完成,所以還需要查詢均衡器是否正在運行.

3.3查看平衡器開啟狀態(tài)

db.settings.find({"_id":"balancer"})
或者
sh.getBalancerState()

3.4查看平衡器是否在運行

返回ture代表正在運行,false代表當(dāng)前沒有在運行。

3.5指定平衡時間

必須先保證平衡器是開啟狀態(tài)

use config
sh.setBalancerState( true )

db.settings.update({"_id":"balancer"},
{"$set":{"activeWindows":{"start":"13:00","stop":"16:00"}}},
{upsert:true}
)
  • For HH values, use hour values ranging from 00 - 23.

  • For MM value, use minute values ranging from 00 - 59.

3.6關(guān)閉平衡時間

use config

db.settings.update({ _id : "balancer" }, { $unset : { activeWindows : true } })

3.7關(guān)閉開啟指定文檔的平衡器

關(guān)閉

sh.disableBalancing("test.aa")

開啟

sh.enableBalancing("test.aa")

查詢是否關(guān)閉文檔的平衡器,返回true代表關(guān)閉。沒有結(jié)果返回沒有關(guān)閉,返回報錯代表文檔不存在或者文檔沒有開啟分片

db.getSiblingDB("config").collections.findOne({_id : "test.aa"}).noBalance;

3.8.備份時注意事項

在執(zhí)行備份前需要關(guān)閉平衡器,但是均衡器的關(guān)閉不是立即就完成,所以還需要查詢均衡器是否正在運行,不要在平衡器處于活動狀態(tài)時備份,可以備份操作前執(zhí)行以下查詢:

sh.getBalancerState()

sh.isBalancerRunning()

注意:保證平衡器處于關(guān)閉狀態(tài)同時sh.isBalancerRunning()返回的不是ture ;也可以通過設(shè)置平衡器的平衡時間來維護備份。

參考:https://docs.mongodb.com/manual/tutorial/manage-sharded-cluster-balancer/

4.塊管理

1.修改數(shù)據(jù)塊大小

單位MB,默認塊大小為64MB。塊越大遷移至分片的耗時就越長。

use config;
查詢當(dāng)前塊大小
db.settings.find({"_id":"chunksize"})
修改塊大小
db.settings.save( { _id:"chunksize", value: 64 } );
2.手動移動數(shù)據(jù)塊

2.1查詢文檔塊信息

db.getCollection('chunks').find({"ns":"test.xxxx"})

MongoDB中怎么實現(xiàn)分片管理

2.2將塊"$minKey"移動到分片rs-c

移動塊只需要指定塊的返回內(nèi)的隨便一個值即可,注意塊的范圍不包含上限。

sh.moveChunk("test.xxxx",{"username":"$minKey"},"rs-c")

MongoDB中怎么實現(xiàn)分片管理

MongoDB中怎么實現(xiàn)分片管理

2.3拆分塊

如果塊的大小超過setting設(shè)置的最大塊大小時,系統(tǒng)會禁止移動塊,這時候需要將塊進行拆分。這里需要指定新的塊范圍,指定下限即可。

MongoDB中怎么實現(xiàn)分片管理

sh.splitAt("test.xxxx",{ "username" :"p" })

MongoDB中怎么實現(xiàn)分片管理

2.4查詢塊的大小

db.runCommand({ dataSize: "test.xxxx", keyPattern: { "username": 1 }, min: { "username" : "b" }, max: { "username" : "c" } })

單位字節(jié),需要指定塊的范圍。

2.5無法拆分的特大塊處理

假設(shè)使用year/month/day字段作為分片,某一天業(yè)務(wù)遭受攻擊導(dǎo)致這天的數(shù)據(jù)量暴增,但是由于分片的值已經(jīng)的最小單位了無法再拆分了,這個時候通過塊拆分已經(jīng)無法解決問題,可以手動將塊移動到非熱點的分片上。

5.刷新配置信息

mongos有時無法從配置服務(wù)器正確更新配置信息,可以使用flushRouterConfig命令手動刷新緩存,如果刷新還無法解決需要重啟mongos進程。

db.adminCommand({"flushRouterConfig":1})

6.刪除分片數(shù)據(jù)庫

use news

db.dropDatabase()

上述內(nèi)容就是MongoDB中怎么實現(xiàn)分片管理,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI