一、搭建
主从复制和副本集区别:
主从集群和副本集最大的区别就是副本集没有固定的主节点;整个集群会选出一个主节点,当其挂掉后,又在剩下的从节点中选中其他节点为主节点,副本集总有一个主节点和一个或多个备份节点。
docker-compose 配置复制集只要注意几点:
- command 执行命令时需要指定 --keyFile 和 --replSet 两个属性。keyFile 是为了添加复制集时的验证处理,拥有同样的 keyFile 文件的节点才可以被添加到复制集中。
- docker-compose 配置复制集需要指定 –replSet 属性值,否则直接配置直接失败。
副本集的集合名 replSetName 必须是相同的
1.拉取镜像
docker pull mongo:5.0.6
2.使用 openssl 生成 keyFile 文件
生成 keyFile 文件:
openssl rand -base64 756 > key.file
修改 keyFile 文件权限:
chmod 400 key.file
chown 999 key.file
若不修改 keyFile 文件权限,会出现 permissions on /etc/key.file are too open,这是因为 mongo key 文件权限过大造成的。
3.docker compose 启动容器
docker-compose.yml 文件:
version: '3'
services:
mongo_1:
image: mongo:5.0.6
container_name: mongo_1
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
volumes:
- ./replica_set_1/data/db:/data/db
- ./key.file:/etc/key.file
command: --keyFile /etc/key.file --replSet rs0
networks:
mongo:
ipv4_address: 172.18.1.11
mongo_2:
image: mongo:5.0.6
container_name: mongo_2
restart: always
ports:
- 27027:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
volumes:
- ./replica_set_2/data/db:/data/db
- ./key.file:/etc/key.file
command: --keyFile /etc/key.file --replSet rs0
networks:
mongo:
ipv4_address: 172.18.1.12
mongo_3:
image: mongo:5.0.6
container_name: mongo_3
restart: always
ports:
- 27037:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
volumes:
- ./replica_set_3/data/db:/data/db
- ./key.file:/etc/key.file
command: --keyFile /etc/key.file --replSet rs0
networks:
mongo:
ipv4_address: 172.18.1.13
networks:
mongo:
driver: bridge
ipam:
config:
- subnet: 172.18.1.0/24
使用 docker compose 启动容器
docker compose -f docker-compose.yml up -d
进入容器,可以看到实际启动命令,如下:
root@3b9e1efd4bab:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
mongodb 1 0 1 16:20 ? 00:00:11 mongod --keyFile /etc/key.file --replSet rs0 --auth --bind_ip_all
注意,此时副本集还没有初始化,还不能使用 mongodb
4. 副本集初始化
使用 rs.initiate,进行初始化副本集
rs.initiate({
"_id" : "rs0",
"members" : [
{
"_id" : 0,
"host" : "mongo_1:27017"
},
{
"_id" : 1,
"host" : "mongo_2:27017"
},
{
"_id" : 2,
"host" : "mongo_3:27017"
}
]
}
)
或
rs.initiate({
"_id" : "rs0",
"members" : [
{
"_id" : 0,
"host" : "172.18.1.11:27017"
},
{
"_id" : 1,
"host" : "172.18.1.12:27017"
},
{
"_id" : 2,
"host" : "172.18.1.13:27017"
}
]
}
)
示例:
root@3b9e1efd4bab:/# mongo
> use admin
> db.auth("root","123456")
> rs.initiate({
... "_id" : "rs0",
... "members" : [
... {
... "_id" : 0,
... "host" : "mongo_1:27017"
... },
... {
... "_id" : 1,
... "host" : "mongo_2:27017"
... },
... {
... "_id" : 2,
... "host" : "mongo_3:27017"
... }
... ]
... }
... )
{ "ok" : 1 }
rs0:SECONDARY>
5.测试
找到主节点,进入 mongodb:
root@3b9e1efd4bab:/# mongo
rs0:PRIMARY> use admin
switched to db admin
rs0:PRIMARY> db.auth("root","123456")
1
rs0:PRIMARY> show databases
admin 0.000GB
config 0.000GB
local 0.000GB
rs0:PRIMARY> db.person.insert({'name': 'zhang1', 'age': '21'})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.person.find()
{ "_id" : ObjectId("664e1d6f569f986f9ce44428"), "name" : "zhang1", "age" : "21" }
副本集管理命令:
命令 | 解释 |
---|---|
rs.initiate() | 使用默认配置初始化副本集 |
rs.initiate(cfg) | 使用配置文件cfg初始化副本集 |
rs.reconfig(cfg) | 修改副本集配置信息 |
rs.status() | 查看副本集状态 |
rs.conf() | 查看副本集配置 |
rs.add(hostportstr) 或 rs.add(membercfgobj) | 添加新的节点 |
rs.addArb(hostportstr) | 添加投票节点 |
rs.remove(hostportstr) | 删除节点 |
rs.slaveOk() | 允许从库只读,默认从库不允许读写 |
rs.isMaster() | 查看哪个节点为主节点 |
rs.stepDown([stepdownSecs, catchUpSecs]) | 手动主从切换 |
二、jdcb 操作
pom 依赖:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
测试连接:
@Test
public void testConnectionWithRep() {
// 方式一,验证连接
String database = "admin";
String user = "root";
char[] password = "123456".toCharArray();
MongoCredential credential = MongoCredential.createCredential(user, database, password);
MongoClientOptions options = MongoClientOptions.builder().sslEnabled(false).build();
MongoClient mongoClient = new MongoClient(Arrays.asList(new ServerAddress("127.0.0.1", 27017),
new ServerAddress("127.0.0.1", 27027), new ServerAddress("127.0.0.1", 27037)),
credential, options);
// 方式二,使用 url,验证连接
// MongoClient mongoClient = new MongoClient(
// new MongoClientURI( "mongodb://root:123456@127.0.0.1:27017,127.0.0.1:27027,127.0.0.1:27037/?authSource=admin&ssl=false&replicaSet=rs0"));
MongoCursor<String> cursor = mongoClient.listDatabaseNames().cursor();
while (cursor.hasNext()) {
String next = cursor.next();
System.out.println(next);
}
}