1、分片介紹
分片(sharding)是將數據拆分,將其分散存到不同機器上的過程。MongoDB 支持自動分片,可以使數據庫架構對應用程序不可見。對於應用程序來說,好像始終在使用一個單機的 MongoDB 服務器一樣,另一方面,MongoDB 自動處理數據在分片上的分布,也更容易添加和刪除分片。
請記住:復制是讓多台服務器擁有同樣的數據副本,每一台服務器都是其他服務器的鏡像,而每一個分片都與其他分片擁有不同的數據子集。
通常,分片可以用來:
- 增加可用的內存
- 增加可用的磁盤空間
- 減輕單台服務器的負載
- 處理單個 mongod 服務器無法承受的吞吐量
2、MongoDB 分片集群組成
MongoDB 的分片集群由以下部分組成:
shard:每個分片包含分片數據的一個子集,每個分片可以部署為一個副本集
mongos:作為一個查詢路由器,提供客戶端應用程序和分片集群之間的接口。
config servers:配置服務器存儲群集的元數據和配置信息。MongoDB 3.4 版本開始,配置服務器必須部署一個副本集。
分片集群的配置分為 Production Configuration 和 Development Configuration,一個用於生產環境下的配置,另個用於開發或者測試環境的配置。
2.1、Production Configuration(生產環境配置)
在生產集群(production cluster)中,如果集合數據是冗余的,並且系統配置夠用,生產分片集群部署,需滿足一下幾點:
- 部署配置服務器包含三個成員的副本集(Deploy Config Servers as a 3 member replica set)
- 部署每一個分片可以是三個成員的副本集(Deploy each Shard as a 3 member replica set)
- 部署可以有一個或多個路由(Deploy one or more mongos routers)
結構圖如下:

2.2、Development Configuration(開發環境配置)
測試或者開發環境,可以使用最少的組件部署一個分片集群,這些非生產集群包含以下組件:
- 具有一個成員的副本集配置服務器(A replica set config server with one member)
- 至少一個分片作為一個成員的副本集(At least one shard as a single-member replica set)
- 一個 mongos 實例(One mongos instance)
結構圖如下:

注意:使用測試集群結構,僅僅用於測試或者開發。
下面用較簡單的 Development Configuration 舉例說明一下。
3、范例
接下來我們就用范例具體說明一下分片的過程,這里准備三台服務器,分別為 218.245.4.11、218.245.4.12、218.245.4.13。
218.245.4.11 作為配置服務器(config server),在該服務器上創建一個成員的副本集。實際項目中,需要三個成員的副本集。
218.245.4.12 作為分片(shard)服務器,在該服務器上也創建一個成員的副本集。實際項目中,可以創建多個分片,每個分片也可以是副本集。
218.245.4.13 作為 mongos 服務器。實際項目中,可以創建多個 mongos。
3.1 創建配置服務器副本集(Create the Config Server Replica Set)
3.1.1 啟動配置服務器副本集中的成員(Start a member of the config server replica set),這里定義副本集名字為“configRep”,需要指定 --configsvr 參數,實際項目中用 --bind_ip 指定具體的IP地址
mongod --port 27017 --bind_ip 218.245.4.11 --configsvr --replSet configRep --dbpath c:\data\db
3.1.2 連接到其中一個配置服務器,用 rs.initiate() 初始化副本集
rs.initiate(
{
_id: "configRep",
configsvr: true,
members: [
{ _id: 0, host : "218.245.4.11:27017" }
]
}
)
3.2 創建 Shard 副本集(Create the Shard Replica Sets)
3.2.1 啟動 Shard 服務器副本集中的成員(Start a member of the shard replica set),這里定義副本集名字為“shardRep”,需要指定 --shardsvr 參數。這里可以不用是一個副本集,可以是單台 mongod 服務器。
mongod --port 27017 --bind_ip 218.245.4.12 --shardsvr --replSet shardRep --dbpath c:\data\shard
3.2.2 連接到 Shard 服務器,用 rs.initiate() 初始化副本集
rs.initiate(
{
_id: "shardRep"
members: [
{ _id: 0, host : "218.245.4.12:27017" }
]
}
)
3.3 啟動 mongos 實例
mongos --configdb configRep/218.24.5.4.11:27017 --port 27017
MongoDB 3.4 版本中,參數 --configdb 的值必須包含副本集的名稱,這也是 MongoDB 3.4 版本為什么配置服務器要部署為副本集的原因。
3.4 給集群添加分片
添加分片的操作,必須在 mongos 下操作,也就是要先連上 mongos。可以用 sh.addShard() 方法添加分片
sh.addShard("shardRep/218.245.4.12:27017")
如果分片不用副本集,可以這樣添加分片
sh.addShard("218.245.4.12:27017")
3.5 設置分片存儲的數據庫
MongoDB 中用 sh.enableSharding() 方法設置需要分片存儲的數據庫,連上 mongos。
sh.enableSharding("liruihuan")
3.6 設置需要分片的集合
在設置分片集合之前,我們有必要了解一下片鍵(shard key)的概念。MongoDB是怎么對集合分片的呢?這時候就用到了片鍵。片鍵是集合的一個鍵,MongoDB 根據這個鍵拆分數據。例如,如果選擇基於“name”進行分片,MongoDB 對根據不同名字進行分片:“name1”到“name100”位於第一片,“name101”到“name200”位於第二片,以此類推。
給集合分片,需要用 sh.shardCollection() 方法指定需要分片的集合和片鍵,下面例子是給 user 集合分片,片鍵為 name,連上 mongos。
sh.shardCollection("liruihuan.user", { name : 1 } )
注意,如果這個集合包含有數據,在用 shardCollection() 之前,我們必須用 db.collection.createIndex() 方法給片鍵創建索引。如果這個集合為空,MongoDB 在用 shardCollection() 時會創建索引。
3.7 給 user 集合添加20萬條數據
給 user 集合添加20萬條數據,看看集合是這么分片的
for(var i = 0; i <200000; i++)
{
db.user.insert({"name":"lrh"+i,"age":18})
}
用 sh.status() 查看分片情況
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("58fcb9e3f6420984b3570e11")
}
shards:
{ "_id" : "shardRep", "host" : "shardRep/218.245.4.12:27017", "state" : 1 }
active mongoses:
"3.4.3" : 1
databases:
{ "_id" : "liruihuan", "primary" : "shardRep", "partitioned" : true }
liruihuan.user
shard key: { "name" : 1 }
unique: false
balancing: true
chunks:
shardRep 3
{ "name" : { "$minKey" : 1 } } -->> { "name" : "liruihuan" } on : shardRep Timestamp(1, 1)
{ "name" : "liruihuan" } -->> { "name" : "lrh7" } on : shardRep Timestamp(1, 2)
{ "name" : "lrh7" } -->> { "name" : { "$maxKey" : 1 } } on : shardRep Timestamp(1, 3)
我們可以看出集合的數據被分到名為 shardRep 副本集的分片上了,我們這里只用了一個分片,大家可以啟動多個分片,看看數據是怎么分割的。
業精於勤,荒於嬉;行成於思,毀於隨。
如果你覺得這篇文章不錯或者對你有所幫助,可以通過右側【打賞】功能,給予博主一點點鼓勵和支持
