Mongodb-Cluster

  • Carter Ho
  • 13 Minutes
  • 2019年10月2日

Replica Set(副本集):

Sharded Cluster(分片):

docker 建立分片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 準備auth用的keyfile,並組裝成image(這部分也可以用mount的方式替代)
# Dockerfile腳本
## 基礎版本
FROM mongo:4.2.0
## 複製設定檔
COPY ./keyfile /opt/
RUN bash -c 'chmod 600 /opt/keyfile'
RUN bash -c 'chown 999 /opt/keyfile'
USER root

# 建立容器私有網段
docker network create --subnet=10.100.0.0/16 mongo

# 加入容器內往IP網段
route add 10.100.0.0 MASK 255.255.255.0 10.0.75.2

# 若是在Windows須將mongodb mount到獨立的volume,若直接monut在宿主實體路徑會有檔案權限問題
# config server rs volumes
docker volume create csrs1
docker volume create csrs2
docker volume create csrs3
# router volumes
docker volume create mongos1
docker volume create mongos2
# shard1 rs volumes
docker volume create sh1rs1
docker volume create sh1rs2
docker volume create sh1rs3
# shard2 rs volumes
docker volume create sh2rs1
docker volume create sh2rs2
docker volume create sh2rs3

# 分片群集之間auth須由特定keyfile組成,在keyfile加入前須先設定好user跟CSRS還有SHRS設定,一開始先註解掉--keyfile指令
# config server rs volumes
docker run -d --network mongo --ip 10.100.0.2 -v csrs1:/data/configdb --name csrs1 --hostname 10.100.0.2 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --configsvr --replSet csrs --port 27017 --oplogSize 16
docker run -d --network mongo --ip 10.100.0.3 -v csrs2:/data/configdb --name csrs2 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --configsvr --replSet csrs --port 27017 --oplogSize 16
docker run -d --network mongo --ip 10.100.0.4 -v csrs3:/data/configdb --name csrs3 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --configsvr --replSet csrs --port 27017 --oplogSize 16
# router volumes
# 這邊要注意啟動時要指定bind_ip,否則預設為localhost會無法expose
docker run -d --network mongo --ip 10.100.0.5 -v mongos1:/data/db --name mongos1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongos --keyFile /opt/keyfile --configdb csrs/10.100.0.2:27017,10.100.0.3:27017,10.100.0.4:27017 --bind_ip 10.100.0.5
docker run -d --network mongo --ip 10.100.0.6 -v mongos2:/data/db --name mongos1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongos --keyFile /opt/keyfile --configdb csrs/10.100.0.2:27017,10.100.0.3:27017,10.100.0.4:27017 --bind_ip 10.100.0.6
# 因為mongo跑起來時conf host名稱預設會帶containerId所以這邊先指定給容器內往IP,不然宿主在連副本集會找不到該hostname
# shard1 rs volumes
docker run -d --network mongo --ip 10.100.0.7 -v sh1rs1:/data/db --hostname 10.100.0.7 --name sh1rs1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh1rs --oplogSize 16
docker run -d --network mongo --ip 10.100.0.8 -v sh1rs2:/data/db --name sh1rs2 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh1rs --oplogSize 16
docker run -d --network mongo --ip 10.100.0.9 -v sh1rs3:/data/db --name sh1rs3 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh1rs --oplogSize 16
# shard2 rs volumes
docker run -d --network mongo --ip 10.100.0.10 -v sh2rs1:/data/db --hostname 10.100.0.10 --name sh2rs1 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh2rs --oplogSize 16
docker run -d --network mongo --ip 10.100.0.11 -v sh2rs2:/data/db --name sh2rs2 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh2rs --oplogSize 16
docker run -d --network mongo --ip 10.100.0.12 -v sh2rs3:/data/db --name sh2rs3 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" mongo:custom mongod --keyFile /opt/keyfile --shardsvr --port 27017 --replSet sh2rs --oplogSize 16

# 設定 config server
docker exec -it scrs1 bash
mongo
rs.initiate()
rs.add('10.100.0.3:27017')
rs.add('10.100.0.4:27017')
use admin
db.createUser({user:"root",pwd:"123456",roles:[{role:"root",db:"admin"}]})
db.createUser({user:"admin",pwd:"123456",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
db.createUser({user:"user",pwd:"123456",roles:[{"role":"readWriteAnyDatabase","db":"admin"}]})

# 設定 shard rs 有幾個sh叢集就做幾次 以sh1為例
docker exec -it sh1rs1 bash
mongo
rs.initiate()
rs.add('10.100.0.8:27017')
rs.addArb('10.100.0.9:27017')
use admin
db.createUser({user:"root",pwd:"123456",roles:[{role:"root",db:"admin"}]})
db.createUser({user:"admin",pwd:"123456",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
db.createUser({user:"user",pwd:"123456",roles:[{"role":"readWriteAnyDatabase","db":"admin"}]})

# 將所有RS跟user設定完後把容器完全關閉再把原本註解的keyfile加入啟動,因為之前的設定有mont到volume所以不用擔心設定不見

# 設定router 挑一台設定即可
docker exec -it mongos1 bash
mongo --host 10.100.0.5 --port 27017
use admin
db.auth("root","123456")
# 加入shard RS "RS名稱/PrimaryHost:27017"
sh.addShard("rs1/10.100.0.7:27017")
sh.addShard("rs2/10.100.0.10:27017")

# 啟動分片
# 根據不同collection分配在不同SH
sh.enableSharding("<DataBase>")
# 將單一collection分配在不同SH做附載平衡,以hash policy為例
sh.shardCollection("<DataBase>.<Collection>", { _id: "hashed"})