mongodb分片介紹
分片是由副本集組成的系統
分片就是講數據庫進行拆分,將大型集合分割到不同服務器上,比如:將原本有100G的數據,進行分割成10份存儲到不同的服務器上,這樣每臺服務器只存儲有10G的數據
mongodb通過一個mongos的(路由)進程實現分片後的數據存儲與訪問,也就是說mongos是整個分片架構的核心,對前端的程序而言不會清楚是否有分片的,客戶端只需要把讀寫操作轉達給mongos即可
雖然分片會把數據分割到很多臺服務器上,但是每一個節點都需要有一臺備份的角色,這樣能保證數據的高可用性
當系統需要更多空間或資源的時候,分片可以讓我們按需方便擴展,只需要把mongodb服務的機器加入到分片集羣中即可
mongos分片結構
MongoDB分片相關概念
mongos:數據庫羣集請求的入口,所有的請求都是通過mongos進行協調,不需要在應用程序上添加一個路由選擇器,mongos自己就是一個請求分發中心,它負責把對應的數據請求轉發到對應的shard服務器上。在生產環境通常有洞mongos作爲請求入口,防止其中一個掛掉後所有的mongodb服務請求都無法訪問
config server :配置服務器,存儲所有的數據源信息(路由、分片)的配置。mongos本身不在硬盤中存儲分片服務器和數據路由信息,只是緩存在內存裏,配置服務器則實際存儲這些數據。mongos第一次啓動或者關閉重啓就會從config server中加載配置信息,如果以後配置服務器信息發生變化會通知所有的mongos更新自己的狀態,這樣mongos就能繼續準確的路由。在生產環境中通常有多個config server配置服務器,因爲它存儲了分片路由的元數據,防止意外宕機故障造成數據丟失
shard :存儲了一個集合部分數據的MongoDB實例,每個分片是單獨的mongodb服務或者是一個副本集,在生產環境中,所有的分片都應該是副本集
mongodb分片搭建
分片搭建主機
實驗規劃,這裏只爲了實現試驗需求,對測試中出現的情況實際上是一臺服務器相當於部署了一個副本集,實際情況中則是多臺服務器組成一個副本集,一臺服務器承當三個服務角色。這裏請注意區分
三臺服務器:1.115、1.223、1.234
以下是創建三個副本集的執行命令,使用如下命令需要注意副本集名稱和端口的設定!!
1.234搭建:mongods、config server、副本集1的主節點、副本集2的仲裁、副本集3的從節點
config={_id:"shard1",members:[{_id:0,host:"192.168.1.234:27001"},{_id:1,host:"192.168.1.115:27001"},{_id:2,host:"192.168.1.223:27001",arbiterOnly:true}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3
cfg.members[1].priority = 2
cfg.members[2].priority = 1 仲裁角色
shard2:PRIMARY> rs.reconfig(cfg)
1.115搭建:mongos、config server、副本集1的從節點、副本集2的主節點、副本集3的仲裁
config={_id:"shard2",members:[{_id:0,host:"192.168.1.115:27002"},{_id:1,host:"192.168.1.234:27002",arbiterOnly:true},{_id:2,host:"192.168.1.223:27002"}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3 主優先級
cfg.members[1].priority = 1 仲裁角色
cfg.members[2].priority = 2
shard2:PRIMARY> rs.reconfig(cfg)
1.223搭建:mongos、config server、副本集1的仲裁、副本集2的從節點、副本集3的主節點
config={_id:"shard3",members:[{_id:0,host:"192.168.1.223:27003"},{_id:1,host:"192.168.1.115:27003",arbiterOnly:true},{_id:2,host:"192.168.1.234:27003"}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3 主優先級
cfg.members[1].priority = 1 仲裁角色
cfg.members[2].priority = 2
shard2:PRIMARY> rs.reconfig(cfg)
端口:mongos端口爲20000,config server端口爲21000,副本集1端口27001、副本集2端口27002、副本集3端口27003
三臺服務器全部關閉selinux和firewalld服務,或者增加對應的端口規則
在三臺服務器上都創建mongos和應用集的存儲目錄
[root@localhost ~]# mkdir -p /data/mongodb/mongos/log
[root@localhost ~]# mkdir -p /data/mongodb/config/{data,log}
[root@localhost ~]# mkdir -p /data/mongodb/shard1/{data,log}
[root@localhost ~]# mkdir -p /data/mongodb/shard2/{data,log}
[root@localhost ~]# mkdir -p /data/mongodb/shard3/{data,log}
創建config server的配置文件,修改每臺配置。配置文件除了監聽ip其他配置都相同
[root@localhost ~]# mkdir /etc/mongod
[root@localhost ~]# vim /etc/mongod/config.cnf
pidfilepath = /var/run/mongodb/configsrv.pid
dbpath = /data/mongodb/config/data
logpath = /data/mongodb/config/log/congigsrv.log
logappend = true
bind_ip = 192.168.1.115
port = 21000
fork = true
configsvr = true #declare this is a config db of a cluster
replSet=configs #副本集名稱
maxConns=20000 #最大連接數
啓動config server服務,並查看的啓動端口
[root@localhost ~]# mongod -f /etc/mongod/config.conf
2018-11-21T04:04:46.882+0800 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
about to fork child process, waiting until server is ready for connections.
forked process: 3474
child process started successfully, parent exiting
[root@localhost ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1750/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2757/master
tcp 0 0 192.168.1.115:21000 0.0.0.0:* LISTEN 3474/mongod
tcp 0 0 192.168.1.115:27017 0.0.0.0:* LISTEN 2797/mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 2797/mongod
並登入到config server中,並初始化配置
[root@localhost ~]# mongo --host 192.168.1.115 --port 21000
MongoDB shell version v4.0.4
connecting to: mongodb://192.168.1.115:21000/
Implicit session: session { "id" : UUID("cb007228-2291-4164-9528-c68884a00cee") }
MongoDB server version: 4.0.4
Server has startup warnings:
> config = {_id:"configs",members:[{_id:0,host:"192.168.1.234:21000"},{_id:1,host:"192.168.1.223:21000"},{_id:2,host:"192.168.1.115:21000"}]}
{
"_id" : "configs",
"members" : [
{
"_id" : 0,
"host" : "192.168.1.234:21000"
},
{
"_id" : 1,
"host" : "192.168.1.223:21000"
},
{
"_id" : 2,
"host" : "192.168.1.115:21000"
}
]
}
初始化config server配置
> rs.initiate(config)
{
"ok" : 1,
"operationTime" : Timestamp(1542786565, 1),
"$gleStats" : {
"lastOpTime" : Timestamp(1542786565, 1),
"electionId" : ObjectId("000000000000000000000000")
},
"lastCommittedOpTime" : Timestamp(0, 0),
"$clusterTime" : {
"clusterTime" : Timestamp(1542786565, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
爲分片創建三個不同的副本集
添加副本集的配置文件,三臺服務器中都需要配置。每臺服務器都要啓動一個副本集,所以監聽的端口和ip都要配置成不同的
副本集1端口27001、副本集2端口27002、副本集3端口27003
shard1的副本集主上配置,剩下的幾臺也是同樣配置,不同地方在shard的名稱和bind_ip 監聽的端口
[root@nfs1 ~]# cat /etc/mongod/shard1.conf
pidfilepath = /var/run/mongodb/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log 每個副本集存儲數據目錄名、日誌及配置名,如副本集1和2:shard1、shard2
logappend = true
bind_ip = 192.168.1.234 每臺配置不一樣的監聽ip,ip爲本地ip
port = 27001 每條配置不一樣的監聽端口,shard1爲27001、shard2爲27002、shard3爲27003
fork = true
httpinterface=true 打開web監控
rest=true
replSet=shard2
shardsvr = true
maxConn=20000
接下來幾臺機器可以使用sed批量替換字符來處理配置內容
[root@nfs2 log]# sed -i 's/shard1/shard2/g' /etc/mongod/shard2.conf
啓動副本集,並查看監聽端口是否正確(此處只摘出副本集2的端口狀態,其他主機也是一樣的)
[root@nfs2 log]# mongod -f /etc/mongod/config.conf
2018-11-21T15:36:46.642+0800 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
about to fork child process, waiting until server is ready for connections.
forked process: 13109
child process started successfully, parent exiting
[root@nfs2 log]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1641/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 9267/nginx: master
tcp 0 0 192.168.1.223:21000 0.0.0.0:* LISTEN 13109/mongod
tcp 0 0 192.168.1.223:27017 0.0.0.0:* LISTEN 13040/mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 13040/mongod
完成每臺的副本集配置,副本集配置要對每臺機器都配置相同的副本集端口監聽,比如機器1監聽了27001和27002端口,同樣機器2也必須監聽27001和27002端口。而27001屬於副本集1的、27002屬於副本集2的端口
配置截圖cat參考如下(副本集架構請在文章上面瞭解):(補充,圖中服務器1.115的shard3配置出現一個低級錯誤,也請各位在配置時認真檢查自己的配置文件,以免出現查不到問題的情況。出現錯誤也可以看mongo產生的日誌)
配置中的bind_ip根據機器網卡ip來設定
(配置文件中的配置項:
httpinterface=true
rest=true
maxConn=20000
在添加這幾個配置項後啓動時不能識別這幾個參數,所以後續我沒有添加這幾個參數來啓動的):
[root@localhost /]# cat /etc/mongod/shard1.conf
pidfilepath = /var/run/mongodb/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log
logappend = true
bind_ip = 192.168.1.115 這裏ip隨機器ip做修改,因爲這裏是服務啓動監聽的ip
port = 27001 副本集1監聽端口
fork = true
httpinterface=true
rest=true
replSet=shard1
shardsvr = true
maxConn=20000
[root@localhost /]# cat /etc/mongod/shard2.conf
pidfilepath = /var/run/mongodb/shard2.pid
dbpath = /data/mongodb/shard2/data
logpath = /data/mongodb/shard2/log/shard2.log
logappend = true
bind_ip = 192.168.1.115
port = 27002 副本集2監聽端口
fork = true
httpinterface=true
rest=true
replSet=shard2
shardsvr = true
maxConn=20000
[root@localhost /]# cat /etc/mongod/shard3.conf
pidfilepath = /var/run/mongodb/shard3.pid
dbpath = /data/mongodb/shard3/data
logpath = /data/mongodb/shard3/log/shard3.log
logappend = true
bind_ip = 192.168.1.115
port = 27003 副本集3監聽端口
fork = true
httpinterface=true
rest=true
replSet=shard2
shardsvr = true
maxConn=20000
這裏先啓動shard1的副本集
初始化副本集可以在1.115或者1.234進行,爲什麼不能在1.223上進行初始化副本集:因爲1.223是作爲副本集shard1的仲裁者,所以需要把1.223排除在副本集之外,這也就是爲什麼測試至少需要三臺機器的原因,因爲如果開始只拿兩臺做這個測試會因爲1臺副本集、1臺仲裁的架構而不成立。
啓動完成後登入每臺的副本集中,指定副本集中的主從角色
在副本集中加入其他節點,並執行初始化副本集語句:
[root@nfs1 /]# mongo -host 192.168.1.234 --port 27001
MongoDB shell version v4.0.4
connecting to: mongodb://192.168.1.234:27001/
Implicit session: session { "id" : UUID("0cbd0b1e-db62-4fe2-b20f-a5d23a60fdf5") }
MongoDB server version: 4.0.4
use admin
> use admin
switched to db admin
> config={_id:"shard1",members:[{_id:0,host:"192.168.1.234:27001"},{_id:1,host:"192.168.1.115:27001"},{_id:2,host:"192.168.1.223:27001", arbiterOnly:true}]}
{
"_id" : "shard1",
"members" : [
{
"_id" : 0,
"host" : "192.168.1.234:27001"
},
{
"_id" : 1,
"host" : "192.168.1.115:27001"
},
{
"_id" : 2,
"host" : "192.168.1.223:27001",
"arbiterOnly" : true
}
]
}
初始化副本集,ok提示配置正確初始化成功
> rs.initiate(config)
{
"ok" : 1,
"operationTime" : Timestamp(1542796014, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1542796014, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看節點信息
shard1:SECONDARY> rs.status()
{
"set" : "shard1",
"date" : ISODate("2018-11-21T10:27:01.259Z"),
"myState" : 2,
"term" : NumberLong(0),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"appliedOpTime" : {
"ts" : Timestamp(1542796014, 1),
"t" : NumberLong(-1)
},
"durableOpTime" : {
"ts" : Timestamp(1542796014, 1),
"t" : NumberLong(-1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(0, 0),
"members" : [
{
"_id" : 0,
"name" : "192.168.1.234:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 606,
"optime" : {
"ts" : Timestamp(1542796014, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-11-21T10:26:54Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.1.115:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 7,
"optime" : {
"ts" : Timestamp(1542796014, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1542796014, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-11-21T10:26:54Z"),
"optimeDurableDate" : ISODate("2018-11-21T10:26:54Z"),
"lastHeartbeat" : ISODate("2018-11-21T10:27:01.231Z"),
"lastHeartbeatRecv" : ISODate("2018-11-21T10:27:00.799Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.1.223:27001",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 7,
"lastHeartbeat" : ISODate("2018-11-21T10:27:01.231Z"),
"lastHeartbeatRecv" : ISODate("2018-11-21T10:27:00.210Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1542796014, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1542796014, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
其他副本集按照文章頭給的架構來分配,後面只給出2、3副本集中執行的語句:
以下是創建三個副本集的執行命令,使用如下命令需要注意副本集名稱和端口的設定!!
1.234搭建:mongods、config server、副本集1的主節點、副本集2的仲裁、副本集3的從節點
config={_id:"shard1",members:[{_id:0,host:"192.168.1.234:27001"},{_id:1,host:"192.168.1.115:27001"},{_id:2,host:"192.168.1.223:27001",arbiterOnly:true}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3
cfg.members[1].priority = 2
cfg.members[2].priority = 1 仲裁角色
shard2:PRIMARY> rs.reconfig(cfg)
1.115搭建:mongos、config server、副本集1的從節點、副本集2的主節點、副本集3的仲裁
config={_id:"shard2",members:[{_id:0,host:"192.168.1.115:27002"},{_id:1,host:"192.168.1.234:27002",arbiterOnly:true},{_id:2,host:"192.168.1.223:27002"}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3 主優先級
cfg.members[1].priority = 1 仲裁角色
cfg.members[2].priority = 2
shard2:PRIMARY> rs.reconfig(cfg)
1.223搭建:mongos、config server、副本集1的仲裁、副本集2的從節點、副本集3的主節點
config={_id:"shard3",members:[{_id:0,host:"192.168.1.223:27003"},{_id:1,host:"192.168.1.115:27003",arbiterOnly:true},{_id:2,host:"192.168.1.234:27003"}]}
rs.initiate(config)
設定優先級,仲裁角色設置爲最低的優先級
cfg = rs.conf()
cfg.members[0].priority = 3 主優先級
cfg.members[1].priority = 1 仲裁角色
cfg.members[2].priority = 2
shard2:PRIMARY> rs.reconfig(cfg)
至此三個副本集都創建成功了,並且指定了主從、仲裁角色之間的優先級
mongodb分片-配置路由服務
mongos配置
mongos最後配置的原因是因爲需要使用到副本集和config server的信息
在三臺機器上創建mongos的配置文件,配置文件中的監聽ip根據不同機器進行修改
configdb配置中是每個機器的config server的ip和監聽端口
[root@nfs2 log]# cat /etc/mongod/mongos.conf
pidfilepath = /var/run/mongodb/mongos.pid
logpath = /data/mongodb/mongos/log/mongos.log
logappend = true
bind_ip = 192.168.1.223
port = 20000
fork = true
configdb = configs/192.168.1.234:21000,192.168.1.115:21000,192.168.1.223:21000
maxConns=20000
啓動三臺機器上的mongos服務並查看運行的監聽端口
[root@nfs2 log]# netstat -ntlp |grep mongos
tcp 0 0 192.168.1.223:20000 0.0.0.0:* LISTEN 14327/mongos
啓動每臺的mongos後,隨意登入一臺mongos中(監聽端口20000)
把所有的副本集的分片服務與路由器串聯起來(添加到服務分發表中)
添加每個副本集到mongos中的時候,需要注意副本集名稱和副本集服務器的監聽端口和ip是否寫入正確
mongos> sh.addShard("shard1/192.168.1.234:27001,192.168.1.115:27001,192.168.1.223:27001")
{
"shardAdded" : "shard1",
"ok" : 1,
"operationTime" : Timestamp(1542893389, 7),
"$clusterTime" : {
"clusterTime" : Timestamp(1542893389, 7),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.addShard("shard2/192.168.1.234:27002,192.168.1.115:27002,192.168.1.223:27002")
{
"shardAdded" : "shard2",
"ok" : 1,
"operationTime" : Timestamp(1542893390, 15),
"$clusterTime" : {
"clusterTime" : Timestamp(1542893390, 15),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.addShard("shard3/192.168.1.234:27003,192.168.1.115:27003,192.168.1.223:27003")
{
"shardAdded" : "shard3",
"ok" : 1,
"operationTime" : Timestamp(1542893415, 11),
"$clusterTime" : {
"clusterTime" : Timestamp(1542893415, 11),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看mongos分片羣集狀態信息,着重關注Currently enabled: yes和Currently enabled: yes信息提示。
Currently running: no 未運行是因爲這個分片羣集中還沒有運行任何庫跟集合,所以這裏顯示狀態爲 no running
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5bf50e12a32cd4af8077b386")
}
shards:
{ "_id" : "shard1", "host" : "shard1/192.168.1.115:27001,192.168.1.234:27001", "state" : 1 }
{ "_id" : "shard2", "host" : "shard2/192.168.1.115:27002,192.168.1.223:27002", "state" : 1 }
{ "_id" : "shard3", "host" : "shard3/192.168.1.223:27003,192.168.1.234:27003", "state" : 1 }
active mongoses:
"4.0.4" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
副本集添加完成後就可以創建數據庫來進行測試
mongodb分片測試
登入任意一臺的mongos20000端口
創建庫和集合,並向集合中插入內容。並且查看分片羣集狀態信息
創建兩個庫,名字爲testdb和db2的庫
使用db.runCommand({enablesharding:"庫名稱"})或者 sh.enableSharding("庫名稱")來創建
結果返回ok: 1表示創建庫成功
mongos> db.runCommand({enablesharding:"testdb"})
{
"ok" : 1,
"operationTime" : Timestamp(1542894725, 5),
"$clusterTime" : {
"clusterTime" : Timestamp(1542894725, 5),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.enableSharding("db2")
{
"ok" : 1,
"operationTime" : Timestamp(1542894795, 11),
"$clusterTime" : {
"clusterTime" : Timestamp(1542894795, 11),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
指定數據庫裏需要分片的集合和片鍵
執行db.runCommand({shardcollection:"庫名.集合名",key:{id:1鍵值}})或者sh.shardCollection("庫名2.集合名2",{"id":1鍵值})
創建操作結果如下:
mongos> db.runCommand({shardcollection:"testdb.table1",key:{id:1}})
{
"collectionsharded" : "testdb.table1",
"collectionUUID" : UUID("79968692-36d4-4ea4-b095-15ba3e4c8d87"),
"ok" : 1,
"operationTime" : Timestamp(1542895010, 17),
"$clusterTime" : {
"clusterTime" : Timestamp(1542895010, 17),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.shardCollection("db2.tl2",{"id":1})
{
"collectionsharded" : "db2.tl2",
"collectionUUID" : UUID("9a194657-8d47-48c9-885d-6888d0625f91"),
"ok" : 1,
"operationTime" : Timestamp(1542895065, 16),
"$clusterTime" : {
"clusterTime" : Timestamp(1542895065, 16),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
進入庫中,向集合內插入10000條數據
mongos> use testdb
switched to db testdb
mongos> for (var i=1;i<10000;i++)db.teble1.save({id:1,"test1":"testval1"})
WriteResult({ "nInserted" : 1 })
mongos> db.table1.stats() 查看teble1這個表的狀態信息,顯示信息較多,這裏就不再列舉
查看分片狀態
查看創建的庫被分片到了哪個副本集當中,以"_id:"格式開頭的行,在下面可以看到chunks : shard3或者chunks : shard2的內容,表示了創建數據庫會被分片到多個副本集當中存儲,簡單測試完成
db2庫存儲到了shard3副本集中。db3存儲到了shard2副本集當中
當數據量較大的時候,mongos才能更平均的分片存儲數據,測試的數據量太少,本次測試完成不了大數據量存儲的存儲狀態顯示
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
shard1 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
{ "_id" : "db2", "primary" : "shard3", "partitioned" : true, "version" : { "uuid" : UUID("35e3bf1c-cd35-4b43-89fb-04b16c54d00e"), "lastMod" : 1 } }
db2.tl2
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard3 1
{ "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard3 Timestamp(1, 0)
{ "_id" : "db3", "primary" : "shard2", "partitioned" : true, "version" : { "uuid" : UUID("a3d2c30b-0842-4d27-9de3-ac4a7710789a"), "lastMod" : 1 } }
db3.tl3
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard2 1
{ "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 0)
{ "_id" : "db4", "primary" : "shard2", "partitioned" : true, "version" : { "uuid" : UUID("25479d1b-b8b9-48bc-a162-e4da117c021e"), "lastMod" : 1 } }
db4.tl4
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard2 1
{ "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 0)
mongoDB備份
備份指定庫
這裏做的是備份分片羣集的操作,mongodump的格式
mongodump --host 集合、副本集或分片集的ip --port 監聽端口 -d 庫 -o 備份存放的路徑
備份之前首先把存儲備份的目錄創建好,然後執行mongodump開始備份。這裏以備份testdb庫爲例:
[root@nfs2 log]# mkdir /tmp/mongobak
[root@nfs2 log]# mongodump --host 192.168.1.223 --port 20000 -d testdb -o /tmp/mongobak/
2018-11-22T14:59:40.035+0800 writing testdb.teble1 to
2018-11-22T14:59:40.035+0800 writing testdb.table1 to
2018-11-22T14:59:40.037+0800 done dumping testdb.table1 (0 documents)
2018-11-22T14:59:40.095+0800 done dumping testdb.teble1 (9999 documents)
進入備份路徑下,查看備份的文件,其中bson是備份的數據文件,json是集合語句結構文件,bson數據文件爲不可讀的二進制文件
[root@nfs2 testdb]# pwd
/tmp/mongobak/testdb
[root@nfs2 testdb]# du -h *
0 table1.bson
4.0K table1.metadata.json
528K teble1.bson
4.0K teble1.metadata.json
使用mongodump備份所有庫
mongodump備份所有庫格式:
mongodump --host 集合、分片的ip --port 監聽端口 -o 備份路徑
備份並查看備份出來的所有庫,會創建多個庫名的目錄
[root@nfs2 testdb]# mongodump --host 192.168.1.223 --port 20000 -o /tmp/mongobak/alldatabase
2018-11-22T15:15:01.570+0800 writing admin.system.version to
2018-11-22T15:15:01.573+0800 done dumping admin.system.version (1 document)
2018-11-22T15:15:01.573+0800 writing testdb.teble1 to
2018-11-22T15:15:01.573+0800 writing config.changelog to
2018-11-22T15:15:01.573+0800 writing config.locks to
2018-11-22T15:15:01.574+0800 writing config.lockpings to
2018-11-22T15:15:01.582+0800 done dumping config.changelog (13 documents)
2018-11-22T15:15:01.582+0800 writing config.chunks to
-----------------------------------------------省略
[root@nfs2 alldatabase]# ls
admin config db2 db3 db4 testdb
備份指定集合
-d 指定庫名稱 -c 指定集合名稱 -o 指定保存路徑
備份集合到/tmp/mongobak/teble1/testdb目錄下,然後查看備份的文件
[root@nfs2 log]# mongodump --host 192.168.1.223 --port 20000 -d testdb -c teble1 -o /tmp/mongobak/teble1
2018-11-22T15:29:34.175+0800 writing testdb.teble1 to
2018-11-22T15:29:34.245+0800 done dumping testdb.teble1 (9999 documents)
[root@nfs2 testdb]# cd /tmp/mongobak/teble1/testdb
[root@nfs2 testdb]# pwd
/tmp/mongobak/teble1/testdb
[root@nfs2 testdb]# du -h *
528K teble1.bson
4.0K teble1.metadata.json
將指定集合導出爲json文件
集合導出後綴爲json的文件後,可以使用cat等命令工具在終端內進行查看或編輯。並使用head -n查看前10行內容
[root@nfs2 testdb]# mongoexport --host 192.168.1.223 --port 20000 -d testdb -c teble1 -o /tmp/mongobak/testdb/1.json
2018-11-22T15:37:10.508+0800 connected to: 192.168.1.223:20000
2018-11-22T15:37:10.743+0800 exported 9999 records
[root@nfs2 testdb]# du -h 1.json
704K 1.json
[root@nfs2 testdb]# head -n 10 1.json
{"_id":{"$oid":"5bf646a042feeb2b916e3b52"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b53"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b54"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b55"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b56"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b57"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b58"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b59"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b5a"},"id":1.0,"test1":"testval1"}
{"_id":{"$oid":"5bf646a042feeb2b916e3b5b"},"id":1.0,"test1":"testval1"}
mongodb數據恢復
聲明:以下所有測試是基於mongodb分片羣集中進行操作的,其他環境(單集合、單副本集)暫沒有測試過
恢復所有的庫
mongorestore --host ip --port 端口 --drop 路徑
其中路徑是指備份所有的庫目錄名字,其中--drop可選,含義是表示在恢復之前先把之前的數據刪除,不建議使用--drop選項
如:
[root@nfs2 mongobak]# mongorestore --host 192.168.1.223 --port 20000 --drop alldatabase/
2018-11-22T16:05:55.153+0800 preparing collections to restore from
2018-11-22T16:05:55.844+0800 reading metadata for testdb.teble1 from alldatabase/testdb/teble1.metadata.json
2018-11-22T16:05:56.093+0800 reading metadata for db2.tl2 from alldatabase/db2/tl2.metadata.json
2018-11-22T16:05:56.130+0800 reading metadata for db4.tl4 from alldatabase/db4/tl4.metadata.json
如果提示
2018-11-22T15:57:24.747+0800 preparing collections to restore from
2018-11-22T15:57:24.748+0800 Failed: cannot do a full restore on a sharded system - remove the 'config' directory from the dump directory first
表示config、admin庫是不能覆蓋恢復的,在恢復之前我們可以在alldatabase備份目錄下將這兩個備份庫刪除,這樣就在恢復操作時不會導入這兩個庫了
恢復指定庫
將庫恢復到之前備份的狀態,備份路徑就是庫的存儲目錄
mongorestore -d 庫名 備份路徑
[root@nfs2 mongobak]# mongorestore --host 192.168.1.223 --port 20000 -d db2 alldatabase/db2/
2018-11-22T16:09:09.127+0800 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2018-11-22T16:09:09.127+0800 building a list of collections to restore from alldatabase/db2 dir
2018-11-22T16:09:09.129+0800 reading metadata for db2.tl2 from alldatabase/db2/tl2.metadata.json
2018-11-22T16:09:09.129+0800 restoring db2.tl2 from alldatabase/db2/tl2.bson
2018-11-22T16:09:09.131+0800 restoring indexes for collection db2.tl2 from metadata
2018-11-22T16:09:09.131+0800 finished restoring db2.tl2 (0 documents)
2018-11-22T16:09:09.131+0800 done
恢復集合
mongorestore --host ip --port 端口 -d 庫 -c 集合 備份路徑
-c後面要跟恢復集合的名字,備份路徑是備份庫時生成的文件所在路徑,這裏是一個bson文件路徑,恢復數據時可以只指定bson文件的絕對路徑。如:
[root@nfs2 mongobak]# mongorestore --host 192.168.1.223 --port 20000 -d testdb -c table1 testdb/table1.bson
2018-11-22T16:14:38.027+0800 checking for collection data in testdb/table1.bson
2018-11-22T16:14:38.031+0800 reading metadata for testdb.table1 from testdb/table1.metadata.json
2018-11-22T16:14:38.039+0800 restoring testdb.table1 from testdb/table1.bson
2018-11-22T16:14:38.103+0800 restoring indexes for collection testdb.table1 from metadata
2018-11-22T16:14:38.105+0800 finished restoring testdb.table1 (0 documents)
2018-11-22T16:14:38.105+0800 done
導入集合
-d 指定庫 -c 指定恢復成的集合名稱 --file 指定要導入成集合的json備份文件的路徑,具體命令格式如下:
[root@nfs2 mongobak]# mongoimport --host 192.168.1.223 --port 20000 -d testdb -c table1 --file /tmp/mongobak/testdb/1.json
2018-11-22T16:17:41.465+0800 connected to: 192.168.1.223:20000
2018-11-22T16:17:42.226+0800 imported 9999 documents