preface

Are you still upset about the system outage caused by the unexpected database outage? Are you still worried that the database is under too much pressure and the system is running at a snail’s pace? Use DDB(Distributed Database). DDB really smells good! Without further discussion, this article mainly introduces the MongoDB DDB feature of the replica set function, hope to have a need for partners can help!

The body of the

According to its storage characteristics, databases can be divided into RDB(relational database) and NOSQL(non-relational database). Common RDB such as Oracle, mysql, SQL Server, and common NOSQL such as mongodb, Redis, memoryCache, etc. See DB-Engines for the full ranking. As can be seen from the ranking, Oracle and mysql rank higher in RDB and have similar users, while mongodb ranks highest in NOSQL and has the largest number of users. As a result, mysql and mongodb have become essential skills for new code farmers.

1 Preparations

  • Operating system: WIN10
  • Mongodb is the latest official mongodb version, which is automatically installed as a Windows service after installation. Configure the bin directory in the path environment variable
  • WIN+R Enter services. MSC to find the MongoDB Server (MongoDB) service, set the startup mode to manual, and disable the service
  • Create the mongodb folder on disk D, create 3 directories 1, 2, and 3, and create the data and log directories and key_file file (without suffix) in each directory.
  • Use OpenSSL to generate the key and paste it into each key_file file, or you can use an encrypted string, however you want

2 Start the mongodb replica set

To facilitate startup, Windows batch scripts are written in this article.

2.1 Write the Mongod startup configuration file

For the options of the startup configuration file, refer to the official configuration file description. The purpose of the configuration file is to avoid writing a long startup script for easy modification. The configuration of the datA1 node is provided first

# data1.cfg

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: D:\mongodb\1\data
  journal:
    enabled: true
#  engine:
#  wiredTiger:

# where to write logging data.
# systemLog:
#   destination: file
#   logAppend: true
#   path:  D:\mongodb\1\log\mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0

# repl set
replication:
  replSetName: rs0

# auth
# security:
#  keyFile: D:\mongodb\1\key_file
#  authorization: enabled
Copy the code

Note the comment auth, temporarily turning off login authorization authentication to create a new user

2.2 Write a batch script and start it
: : start.bat start cmd /k mongod -f "./data1.cfg" start cmd /k mongod -f "./data2.cfg" start cmd /k mongod -f "./data3.cfg"Copy the code

CMD go to the start.bat directory and execute the script. Three Window command prompt Windows are displayed and logs are displayed

2.3 Adding a replica set member to the primary node

WIN+R Open a command prompt window and enter mongo –port 27017 to enter the Mongo client. Run the following command:

> // Initiate () {" infO2 ":" No configuration specified. Using a default configuration for the set", "me" : "Hostname :27017"," OK ": 1} rs0:SECONDARY> rs.add("hostname:27018") // Add a copy object {" OK" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1631944851, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1631944851, 1)} rs0:PRIMARY> rs.add("hostname:27019") { "clusterTime" : Timestamp(1631944854, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1631944854, 1)} rs0:PRIMARY> rs.conf() {"_id" : "rs0", "version" : 3, "term" : 1, "members" : {"_id" : 0, "host" : "hostname:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "hostname:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "hostname:27019", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 } ], ... } rs0:PRIMARY> rs.status() // check mongodb status {... {"_id" : 0, "name" : "hostname:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 514, "optime" : { "ts" : Timestamp(1631945197, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-09-18T06:06:37Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1631944796, 2), "electionDate" : ISODate("2021-09-18T05:59:56Z"), "configVersion" : 5, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "hostname:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 351, "optime" : { "ts" : Timestamp(1631945197, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1631945197, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-09-18T06:06:37Z"), "optimeDurableDate" : ISODate("2021-09-18T06:06:37Z"), "lastHeartbeat" : ISODate(" 2021-09-18T06:06:43.242z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T06:06:41.296z "), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "luoshenzhou:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 5, "configTerm" : 1 }, { "_id" : 2, "name" : "hostname:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 348, "optime" : { "ts" : Timestamp(1631945197, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1631945197, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-09-18T06:06:37Z"), "optimeDurableDate" : ISODate("2021-09-18T06:06:37Z"), "lastHeartbeat" : ISODate(" 2021-09-18T06:06:43.242z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T06:06:41.817z "), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "luoshenzhou:27018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 5, "configTerm" : 1 } ], ... }Copy the code
2.4 Adding databases and users
Rs0 :PRIMARY> show DBS // Display all databases admin 0.000GB config 0.000GB local 0.000GB rs0:PRIMARY> use admin // Switch to the admin database switched  to db admin rs0:PRIMARY> db.createUser({ user: "Su ", PWD :"123", roles:["root"]}) { "user" : "su", "roles" : [ "root" ] } rs0:PRIMARY> use test switched to db test rs0:PRIMARY> Db.createuser ({user:"uu", PWD :"123",roles:["dbOwner"]}) // Add a user named uU to the test database. { "user" : "uu", "roles" : [ "dbOwner" ] } rs0:PRIMARY> show users { "_id" : "test.uu", "userId" : UUID("47a7751d-d27b-4537-909f-85e806ce0df1"), "user" : "uu", "db" : "test", "roles" : [ { "role" : "dbOwner", "db" : "test" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] }Copy the code
2.5 Changing the Priority of the Primary Node

This step is for testing purposes, in case the master node changes after the restart

Rs0: PRIMARY > config = rs. Conf () / / get a configuration object {" _id ":" rs0 ", "version" : 5, "the term" : 1, the "members" : [{" _id ": 0, "host" : "hostname:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "hostname:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "hostname:27019", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "secondaryDelaySecs" : NumberLong(0), "votes" : 1 } ], ... } rs0:PRIMARY> config.members[0]. Priority = 5 rs0:PRIMARY> rs.reconfig(config) {"ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1631946559, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1631946559, 1) }Copy the code

3 Test the replica set

Replica set testing can be done using visual tools, or using nodeJs-based MVC architecture to explore the Express part of the case in this article. This article uses the back-end code in the above article for testing. First shut down all mongod services (that is, close the command prompt window that is running), turn on the Auth option in Step 2.1, restart the batch script, and start the back-end code to get a feel for the replica set DDB feature.

3.1 Adding Data
# api.rest
# 批量新增
POST http://localhost:3030/test/addUsers HTTP/1.1
content-type: application/json

 {
     "name": "liming",
     "hobby": "football",
     "num": 10
 }

/*切换到27017节点*/
rs0:PRIMARY> use test
switched to db test
rs0:PRIMARY> db.auth("uu","123")
1
rs0:PRIMARY> db.users.count()
10

/*切换到27018节点,同样新增了10条数据*/
rs0:SECONDARY> rs.secondaryOk()
rs0:SECONDARY> db.users.count()
10
rs0:SECONDARY>

Copy the code
3.2 Disabling the Active Node

Close the 27017Mongod service window and observe the replica set status

Admin rs0:PRIMARY> use admin switched to db admin rs0:PRIMARY> db.auth("su","123") 1 rs0:PRIMARY> rs.status() { . {"_id" : 0, "name" : "hostname:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate(" 2021-09-18T07:55:49.722z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T07:54:53.952z "), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Error connecting to hostname:27017 (10.1.13.91:27017) :: Caused by :: xxxxx", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 6, "configTerm" : 7 }, { "_id" : 1, "name" : "hostname:27018", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 3664, "optime" : { "ts" : Timestamp(1631951740, 1), "t" : NumberLong(7) }, "optimeDate" : ISODate("2021-09-18T07:55:40Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1631951690, 1), "electionDate" : ISODate("2021-09-18T07:54:50Z"), "configVersion" : 6, "configTerm" : 7, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "hostname:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 3659, "optime" : { "ts" : Timestamp(1631951740, 1), "t" : NumberLong(7) }, "optimeDurable" : { "ts" : Timestamp(1631951740, 1), "t" : NumberLong(7) }, "optimeDate" : ISODate("2021-09-18T07:55:40Z"), "optimeDurableDate" : ISODate("2021-09-18T07:55:40Z"), "lastHeartbeat" : ISODate(" 2021-09-18T07:55:48.617z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T07:55:49.658z "), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "hostname:27018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 6, "configTerm" : 7 } ], ... } rs0:PRIMARY>Copy the code
3.3 Add 10 Items of Data and Restore the Active Node

Add 10 new pieces of data using step (1) configuration, re-enable the 27017mongod service window, and then observe the replica set status

Admin rs0:PRIMARY> use admin switched to db admin rs0:PRIMARY> db.auth("su","123") 1 rs0:PRIMARY> rs.status() { . {"_id" : 0, "name" : "hostname:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 41, "optime" : { "ts" : Timestamp(1631952101, 1), "t" : NumberLong(8) }, "optimeDate" : ISODate("2021-09-18T08:01:41Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1631952081, 1), "electionDate" : ISODate("2021-09-18T08:01:21Z"), "configVersion" : 6, "configTerm" : 8, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "hostname:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 37, "optime" : { "ts" : Timestamp(1631952101, 1), "t" : NumberLong(8) }, "optimeDurable" : { "ts" : Timestamp(1631952101, 1), "t" : NumberLong(8) }, "optimeDate" : ISODate("2021-09-18T08:01:41Z"), "optimeDurableDate" : ISODate("2021-09-18T08:01:41Z"), "lastHeartbeat" : ISODate(" 2021-09-18T08:01:45.484z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T08:01:46.701z "), "pingMs" : NumberLong(1), "lastHeartbeatMessage" : "", "syncSourceHost" : "hostname:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 6, "configTerm" : 8 }, { "_id" : 2, "name" : "hostname:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 37, "optime" : { "ts" : Timestamp(1631952101, 1), "t" : NumberLong(8) }, "optimeDurable" : { "ts" : Timestamp(1631952101, 1), "t" : NumberLong(8) }, "optimeDate" : ISODate("2021-09-18T08:01:41Z"), "optimeDurableDate" : ISODate("2021-09-18T08:01:41Z"), "lastHeartbeat" : ISODate(" 2021-09-18T08:01:45.483z "), "lastHeartbeatRecv" : ISODate(" 2021-09-18T08:01:45.684z "), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "hostname:27018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 6, "configTerm" : 8 } ], ... } rs0:PRIMARY> show DBS admin 0.000GB config 0.000GB local 0.000GB test 0.000GB rs0:PRIMARY> use test switched to db 20 /* Switch to 27019 */ rs0:SECONDARY> show DBS rs0:SECONDARY> use test switched to db test rs0:SECONDARY> db.auth("uu","123") 1 rs0:SECONDARY> rs.secondaryOk() rs0:SECONDARY> show tables users rs0:SECONDARY> db.users.count() 20 rs0:SECONDARY>Copy the code

4 Visualization tool recommendations

The third step can also be done with visual tools, and DBeaver Enterprise is recommended because it can connect to almost all RDB and NOSQL on the market without switching frequent management tools! Warm reminder: DBeaver Enterprise edition needs to be used after pojie, tutorial by baidu

5 International Practice

Welcome to the original link