Currently we use docker-compose to deploy mongodb replica sets. Of course, it is best to use kubernetes to deploy mongodb replica sets.
Environmental preparation
1. Install docker, docker-compose
Generate keyFile
- MongoDB uses keyFile authentication, and each MongoDB instance in the replica set uses the content as a shared secret to authenticate other members. A mongodb instance can only join a replica set if it has the correct keyfile .
- The content of keyFile must be 6 to 1024 characters in length, and the content of keyFile must be the same for all members of the replica set. This is the officially recommended keyFile generation method from MongoDB:
openssl rand -base64 756 > mongodb.key
chown 999:999 mongodb.key
docker-compose.yaml
This is a sample docker-compose.yaml. The corresponding directory needs to be created on the node in advance /data/mongo/data/mongo(i)
; docker-compose.yaml needs to be in the same directory as the mongodb.key file.
version: '3.3'
services:
mongodb1:
image: mongo:4.4.8
volumes:
- /data/mongo/data/mongo1:/data/db
- ./mongodb.key:/data/mongodb.key
user: root
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=admin
container_name: mongodb1
ports:
- 37017:27017
command: mongod --replSet mongos --keyFile /data/mongodb.key
restart: always
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongodb.key
chown 999:999 /data/mongodb.key
exec docker-entrypoint.sh $$@
mongodb2:
image: mongo:4.4.8
volumes:
- /data/mongo/data/mongo2:/data/db
- ./mongodb.key:/data/mongodb.key
user: root
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=admin
container_name: mongodb2
ports:
- 37018:27017
command: mongod --replSet mongos --keyFile /data/mongodb.key
restart: always
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongodb.key
chown 999:999 /data/mongodb.key
exec docker-entrypoint.sh $$@
mongodb3:
image: mongo:4.4.8
volumes:
- /data/mongo/data/mongo3:/data/db
- ./mongodb.key:/data/mongodb.key
user: root
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=admin
container_name: mongodb3
ports:
- 37019:27017
command: mongod --replSet mongos --keyFile /data/mongodb.key
restart: always
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongodb.key
chown 999:999 /data/mongodb.key
exec docker-entrypoint.sh $$@
Create a mongo cluster
Switch to the directory where the docker-compose.yaml file is located and execute the following startup command:
docker-compose up -d
expected outcome:
[root@test01 mongo]# docker ps | grep mongo
97af9e11c66d mongo:4.4.8 "bash -c 'chmod 400 …" About an hour ago Up About an hour 0.0.0.0:37019->27017/tcp, :::37019->27017/tcp mongodb3
63ee9801d66f mongo:4.4.8 "bash -c 'chmod 400 …" About an hour ago Up About an hour 0.0.0.0:37017->27017/tcp, :::37017->27017/tcp mongodb1
9c15ed7476ba mongo:4.4.8 "bash -c 'chmod 400 …" About an hour ago Up About an hour 0.0.0.0:37018->27017/tcp, :::37018->27017/tcp mongodb2
At this point, three mongo instances are already running. Next, we need to configure these three mongo instances as a cluster.
mongo cluster initialization
Connect to the cluster
Enter the container through commands docker exec -it mongodb1 /bin/bash
to configure
After entering the cluster, execute mongo -u root -p admin
Connect to the cluster. After the connection is successful, the following is shown:
root@63ee9801d66f:/# mongo -u root -p admin
MongoDB shell version v4.4.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session {
"id" : UUID("c69a9e0b-e52e-4224-bc81-3f2d09060434") }
MongoDB server version: 4.4.8
---
The server generated these startup warnings when booting:
2022-03-08T07:13:51.708+00:00: You are running on a NUMA machine. We suggest launching mongod like this to avoid performance problems: numactl --interleave=all mongod [other options]
2022-03-08T07:13:51.708+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
---
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
Initialize replica set
In a cluster that has not initialized a replica set, executing rs.status();
the command will yield the following results:
> rs.status()
{
"ok" : 0,
"errmsg" : "command replSetGetStatus requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
Initialize the cluster according to the address of the mongo service:
> rs.initiate({
_id: "mongos", members: [
{
_id : 0, host : "10.81.138.205:37017" },
{
_id : 1, host : "10.81.138.205:37018" },
{
_id : 2, host : "10.81.138.205:37019" },
]});
Among them “mongos”
is the replica set name specified in the docker-compose.yaml file, which can be modified according to the actual situation.
host
What follows is the address (hostIP + port) of the three mongos just deployed. The port number is the port number mapped in docker-compose.yaml, which can be adjusted according to the port usage on the server.
expected outcome:
{
"ok" : 1 }
Execute after initialization is completed. rs.status();
At this time, the following text will be output in the command line:
mongos:SECONDARY> rs.status();
{
"set" : "mongos",
"date" : ISODate("2022-03-08T06:37:31.168Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncSourceHost" : "",
"syncSourceId" : -1,
... ...
"members" : [
{
"_id" : 0,
"name" : "10.81.138.205:37017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 32,
"optime" : {
"ts" : Timestamp(1646721451, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-03-08T06:37:31Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "Could not find member to sync from",
"electionTime" : Timestamp(1646721450, 1),
"electionDate" : ISODate("2022-03-08T06:37:30Z"),
"configVersion" : 1,
"configTerm" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
... ...
At this point the cluster deployment is complete.
Connect to the cluster
What you need to know
The primary node in a MongoDB replica set is not fixed. When encountering replica set rotation upgrades, primary downtime, network partitions, etc., the replica set may elect a new primary, and the original primary will be downgraded to secondary. That is, an active/standby switchover occurs.
All in all, the Primary node in the MongoDB replica set is not fixed, not fixed, not fixed, important things are said three times.
When connecting to a replica set, if you directly specify Primary
the address to connect, you may be able to read and write data correctly at that time. However, once the replica set switches between primary and secondary, the Primary you are connected to will be downgraded to Secondary, and you will not be able to continue to perform write operations. Will seriously affect your online services.
Therefore, the production environment must not be directly connected to the Primary. Never be directly connected to the Primary. Never be directly connected to the Primary .
Correct connection method
To correctly connect to a replica set, you need to first understand MongoDB's Connection String URI. All official drivers support connecting to MongoDB using Connection String.
The following is the main content contained in Connection String
mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
- mongodb:// prefix means this is a Connection String
- username:password If authentication is enabled, you need to specify the user password
- hostX:portX ip:port information of replication set members, multiple members are separated by commas
- /database When authenticating, the database to which the user account belongs
- ?options specifies additional connection options
Taking the mongo replica set on 205 as an example, the correct connection method is as follows:
mongodb://root:[email protected]:37017,10.81.138.205:37018,10.81.138.205:37019/?replicaSet=mongos&readPreference=primary