文章标题 原创 翻译 转载 文章内容 # 环境 在windows一台机器上部署3个副本集(replica set),端口分别是:27020, 27021, 27022,在e://mongo//replset下新建三个目录,分别是:27020,27021,27023。 # 创建副本集 打开命令行工具执行: ``` mongod --port 27020 --replSet rs0 --dbpath e://mongo/replset//27020 ``` # 初始化副本集 打开命令行工具,连接到先前的服务:mongo --port 27020 初始化只有一个成员的副本集,后面可以新增(也可以初始化多个)。 ``` rs.initiate({_id: "rs0", members:[{_id: 0, host: "127.0.0.1:27020"}]}) ``` > rs.conf()查看副本集配置, rs.status()查看副本集状态 # 新增副本集 打开新的命令行工具,开启新的服务,这里开启两个(可以开启多个) ``` mongod --port 27021 --replSet rs0 --dbpath e://mongo/replset//27021 mongod --port 27022 --replSet rs0 --dbpath e://mongo/replset//27022 ``` 连接到primary服务,也就是之前的27020端口,执行: ``` rs.add("127.0.0.1:27021") rs.add("127.0.0.1:27022") ``` rs.status()可以看到如下信息: ``` { "set" : "rs0", "date" : ISODate("2017-12-03T05:49:38.949Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "127.0.0.1:27020", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 888, "optime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-03T05:49:33Z"), "electionTime" : Timestamp(1512279507, 1), "electionDate" : ISODate("2017-12-03T05:38:27Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "127.0.0.1:27021", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 178, "optime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-03T05:49:33Z"), "optimeDurableDate" : ISODate("2017-12-03T05:49:33Z"), "lastHeartbeat" : ISODate("2017-12-03T05:49:37.825Z"), "lastHeartbeatRecv" : ISODate("2017-12-03T05:49:38.841Z"), "pingMs" : NumberLong(0), "configVersion" : 3 }, { "_id" : 2, "name" : "127.0.0.1:27022", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 5, "optime" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512280173, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-03T05:49:33Z"), "optimeDurableDate" : ISODate("2017-12-03T05:49:33Z"), "lastHeartbeat" : ISODate("2017-12-03T05:49:37.825Z"), "lastHeartbeatRecv" : ISODate("2017-12-03T05:49:35.213Z"), "pingMs" : NumberLong(0), "configVersion" : 3 } ], "ok" : 1 } ``` 副本集有三个成员,其中_id为0的是primary # nodejs测试 首先安装:npm install mongodb --save 代码如下: ``` var MongoClient = require('mongodb').MongoClient; var DB_CONN_STR = 'mongodb://localhost:27020,localhost:27021,localhost:27022/test?replicaSet=rs0'; var insertData = function(db, callback) { //连接到表 site var collection = db.collection('test'); //插入数据 var data = [{"name":"hello","url":"3inns.cn"}]; collection.insert(data, function(err, result) { if(err) { console.log('Error:'+ err); return; } callback(result); }); } MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("连接成功!"); let i = 0; setInterval(function() { console.log(i++); insertData(db, function(result) { console.log(result); // db.close(); }); }, 5000); }); ``` 注意副本集的url配置:mongodb://localhost:27020,localhost:27021,localhost:27022/test?replicaSet=rs0 每五秒钟向test数据库的test集合插入一条数据。当我关掉primary主服务后(目前是27020端口)nodejs程序写入数据会失败个10几秒钟,过一会就正常了,而且之前写入失败的数据也会自动补上的。 此时再用rs.status()查看发现27022变成了primary,27020not reachable/healthy 如果再关掉27022服务,发现nodejs程序写数据一直是失败的,看来副本集中至少要有两个成员存活才能完成自动切换到primary 启动27022服务,写入就正常了,之前写入失败的操作也会重新补上。 再启动27020就完整了,查看各个服务中数据库的数据是否一致。 # 副本集个数 需要满足“大多数”的概念,有两种方式: * 奇数个,至少要部署3个 * 偶数个,需要再部署一个仲裁者 此个数是配置的个数,并不是运行中的成员个数。所以当某台服务挂了副本集的个数还是不变的。 文章类别 Python Mobile Android Java Shell Life Database Bug Windows IOS Tools Boost Node.js Mac Product Tips C/C++ Golang Javascript React Qt MQ MongoDB Design Web Linux LLM ChatGPT RAG AI 提交