docker搭建mongodb集群

参考资料

  • 基于 Docker 的 MongoDB 主从集群

http://www.imooc.com/article/details/id/258885

  • mongodb: docker-compose一主两从一仲裁副本集模式

https://blog.csdn.net/weixin_34117522/article/details/94609770

  • Mongodb集群搭建与介绍

https://blog.csdn.net/wangshuang1631/article/details/53857319

前序–聊聊数据库升级方案

  • 一主一从
  • 一主两从
  • 一主一从一仲裁 (当前搭建使用
  • 集群shard分片(暂不讨论)

1.使用docker搭建相应的单节点的mongodb服务

#主节点master
docker run --name mongo-master --restart=always -d --net="bridge" -p 27017:27017 \
-v /root/fct/mongocluster/master/data/db:/data/db \
-v /root/fct/mongocluster/master/logs/mongodb:/var/log/mongodb \
mongo:3.4 \
/bin/sh -c 'mongod --dbpath /data/db --replSet annosys'
#从节点slave1
docker run --name mongo-slave1 --restart=always -d --net="bridge" -p 27027:27017  \
-v /root/fct/mongocluster/slave1/data/db:/data/db \
-v /root/fct/mongocluster/slave1/logs/mongodb:/var/log/mongodb \
mongo:3.4 \
/bin/sh -c 'mongod --dbpath /data/db --replSet annosys'
#仲裁节点arbiter
docker run --name mongo-arbiter -d  --net="bridge" -p 27037:27017 \
mongo:3.4 \
/bin/sh -c 'mongod --dbpath /data/db --replSet annosys --smallfiles'

将各个单个的mongdb通过配置构建成给一个mongodb集群

参考:https://blog.csdn.net/wangshuang1631/article/details/53857319

2 初始化配置副本集

2.1在三台机器上任意一台机器登陆mongodb

进入任意一mongodb的容器中,然后

mongo

切换到admin 库

use admin

定义副本集配置变量,这里的 _id:” annosys” 和上面配置文件中replSet=annosys要保持一样。

config={ _id:"annosys", members:[
{_id:0,host:'172.19.32.142:27017',priority:5},
{_id:1,host:'172.19.32.142:27027',priority:3},
{_id:2,host:'172.19.32.142:27037',arbiterOnly:true}]
}

初始化副本集配置

rs.initiate(config)

查看集群节点的状态
rs.status()

annosys:SECONDARY> rs.status()
{"set" : "annosys","date" : ISODate("2019-10-23T09:43:42.784Z"),"myState" : 2,"term" : NumberLong(1),"syncingTo" : "172.19.32.142:27017","syncSourceHost" : "172.19.32.142:27017","syncSourceId" : 0,"heartbeatIntervalMillis" : NumberLong(2000),"optimes" : {"lastCommittedOpTime" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)},"appliedOpTime" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)},"durableOpTime" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)}},"members" : [{"_id" : 0,"name" : "172.19.32.142:27017","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 3032,"optime" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)},"optimeDurable" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2019-10-23T09:43:40Z"),"optimeDurableDate" : ISODate("2019-10-23T09:43:40Z"),"lastHeartbeat" : ISODate("2019-10-23T09:43:42.362Z"),"lastHeartbeatRecv" : ISODate("2019-10-23T09:43:42.036Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncingTo" : "","syncSourceHost" : "","syncSourceId" : -1,"infoMessage" : "","electionTime" : Timestamp(1571820799, 1),"electionDate" : ISODate("2019-10-23T08:53:19Z"),"configVersion" : 1},{"_id" : 1,"name" : "172.19.32.142:27027","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 4498,"optime" : {"ts" : Timestamp(1571823820, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2019-10-23T09:43:40Z"),"syncingTo" : "172.19.32.142:27017","syncSourceHost" : "172.19.32.142:27017","syncSourceId" : 0,"infoMessage" : "","configVersion" : 1,"self" : true,"lastHeartbeatMessage" : ""},{"_id" : 2,"name" : "172.19.32.142:27037","health" : 1,"state" : 7,"stateStr" : "ARBITER","uptime" : 3032,"lastHeartbeat" : ISODate("2019-10-23T09:43:42.362Z"),"lastHeartbeatRecv" : ISODate("2019-10-23T09:43:40.850Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncingTo" : "","syncSourceHost" : "","syncSourceId" : -1,"infoMessage" : "","configVersion" : 1}],"ok" : 1
}

各个节点的健康状态正常。

3 节点数据同步检查测试、读写分离测试、故障测试模拟

3.1数据同步测试

如果在检查的过程中出现如下错误:not master and slaveOk=false

annosys:SECONDARY> use test;
switched to db test
annosys:SECONDARY> show tables;
2019-10-23T09:44:28.838+0000 E QUERY    [thread1] Error: listCollections failed: {"ok" : 0,"errmsg" : "not master and slaveOk=false","code" : 13435,"codeName" : "NotMasterNoSlaveOk"
}:
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:807:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:819:19
DB.prototype.getCollectionNames@src/mongo/shell/db.js:830:16
shellHelper.show@src/mongo/shell/utils.js:807:9
shellHelper@src/mongo/shell/utils.js:704:15

此时需要执行rs.slaveOk()命令即可

annosys:SECONDARY> rs.slaveOk()
annosys:SECONDARY> use test
switched to db test
annosys:SECONDARY> db.testdb.find()
{ "_id" : ObjectId("5db01956f6d1094b8e5c0a16"), "test1" : "testval1" }
{ "_id" : ObjectId("5db01f167be4feac94c9f596"), "name" : "fct----1" }
{ "_id" : ObjectId("5db01f167be4feac94c9f597"), "name" : "fct----2" }
{ "_id" : ObjectId("5db01f167be4feac94c9f599"), "name" : "fct----4" }
{ "_id" : ObjectId("5db01f167be4feac94c9f598"), "name" : "fct----3" }

如果发现数据同步,证明设置正常

3.2读写分离检查

当前的集群是,只能在master中写数据,然后在salve中读数据,

如果在slave中执行写数据,则报如下错误

annosys:SECONDARY> db.testdb.insert({msg: 'this is from primary change yyy', ts: new Date()})
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })

在master节点则没问题

annosys:PRIMARY> db.testdb.insert({msg: 'this is from primary change xxx', ts: new Date()})
WriteResult({ "nInserted" : 1 })

说明节点做了读写分离。

3.3 故障测试模拟

尝试docker停止master主节点服务时候,值slave节点容器中执行插入动作时候,

annosys:SECONDARY> db.testdb.insert({msg: 'this is from primary change yyy', ts: new Date()})
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })
annosys:SECONDARY> db.testdb.insert({msg: 'this is from primary change yyy', ts: new Date()})
WriteResult({ "nInserted" : 1 })
annosys:PRIMARY> db.testdb.insert({msg: 'this is from primary change yyy', ts: new Date()})
WriteResult({ "nInserted" : 1 })

结果表明

①此时原来只能从节点slave1只能读的节点,也可以写数据了;

②注意查看原来的annosys:SECONDARY的从节点升级为annosys:PRIMARY主节点了。

说明成功完成了故障转移。

至此,测试mongodb集群搭建和高可用性测试完成!

(后期如果需要添加从节点,可以直接修改配置文件后,更新配置即可!用时候需要测试)

4 java连接测试与客户端可视化界面

4.1如果需要使用客户端,建议使用Robot 3T连接mongodb集群。

4.2 java连接mongodb集群测试

package mongotest;import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import java.util.ArrayList;
import java.util.List;/*** 描述: java连接mongdb集群;测试高可用性* @author: fangchangtan* @version 创建时间:2018年11月26日 下午7:45:29*/
public class TestMongoDBReplSet {public static void main(String[] args) {ArrayList<ServerAddress> arrayList = new ArrayList<>();try {//mongpdb的java连接配置为一个集群模式List<ServerAddress> addresses = new ArrayList<ServerAddress>();ServerAddress address1 = new ServerAddress("172.19.32.142" , 27017);ServerAddress address2 = new ServerAddress("172.19.32.142" , 27027);ServerAddress address3 = new ServerAddress("172.19.32.142" , 27037);addresses.add(address1);addresses.add(address2);addresses.add(address3);MongoClient mongoClient = new MongoClient(addresses);MongoDatabase database = mongoClient.getDatabase("test");MongoCollection<Document> collection = database.getCollection("testdb");for (int i = 0; i < 1000; i++) {System.out.println("==========================");Thread.sleep(2000);//向集群中插入文档数据collection.insertOne(new Document("name","dog"+i));//查询集群中的数据记录FindIterable<Document> find = collection.find();for(Document doc : find){System.out.println(doc);}}} catch (Exception e) {e.printStackTrace();}}
}

mongodb集群可以正常的插入和删除数据;

但是当集群发生slave与master节点切换的时候,会发生异常

2019-10-23 20:21:05,972 WARN [org.mongodb.driver.connection] - Got socket exception on connection [connectionId{localValue:4, serverValue:15}] to 172.19.32.142:27017. All connections to 172.19.32.142:27017 will be closed.
com.mongodb.MongoSocketReadException: Prematurely reached end of streamat com.mongodb.connection.SocketStream.read(SocketStream.java:88)at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:494)at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:224)at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:96)at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:440)at com.mongodb.connection.WriteCommandProtocol.receiveMessage(WriteCommandProtocol.java:262)at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:104)at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:67)at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:37)at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:168)at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:289)at com.mongodb.connection.DefaultServerConnection.insertCommand(DefaultServerConnection.java:118)at com.mongodb.operation.MixedBulkWriteOperation$Run$2.executeWriteCommandProtocol(MixedBulkWriteOperation.java:465)at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:656)at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:411)at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:177)at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:426)at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:417)at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:168)at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:74)at com.mongodb.Mongo.execute(Mongo.java:845)at com.mongodb.Mongo$2.execute(Mongo.java:828)at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:550)at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:317)at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:307)at mongotest.TestMongoDBReplSet.main(TestMongoDBReplSet.java:39)

报错:com.mongodb.MongoSocketReadException: Prematurely reached end of stream

这时候要使用try-catch{}捕获异常,并重连mongodb集群即可。(具体代码不再给出,参照redis集群自己体会!)


5.搭建mongodb集群,常见问题总结

1.常见警告WARNING提示,可以忽略

搭建完成之后,进入任意mongo容器之中执行mongo

root@a10c7a769a4a:/# mongo
MongoDB shell version v3.4.23
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.23
Server has startup warnings:
2019-10-23T08:25:41.590+0000 I CONTROL  [initandlisten]
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten]
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten]
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten]
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-10-23T08:25:41.591+0000 I CONTROL  [initandlisten] 

可以看到4个WARNING信息,基于安全的警告,对使用mongo基本没啥影响。

2.出现No host described in new configuration 1 for replica set annosys maps to this node

> use admin
switched to db admin
> config={ _id:"annosys", members:[
... {_id:0,host:'mongo-master:27017',priority:5},
... {_id:1,host:'mongo-slave1:27017',priority:3},
... {_id:3,host:'mongo-arbiter:27017',arbiterOnly:true}]
... }
{"_id" : "annosys","members" : [{"_id" : 0,"host" : "mongo-master:27017","priority" : 5},{"_id" : 1,"host" : "mongo-slave1:27017","priority" : 3},{"_id" : 3,"host" : "mongo-arbiter:27017","arbiterOnly" : true}]
}
> rs.initiate(config)
{"ok" : 0,"errmsg" : "No host described in new configuration 1 for replica set annosys maps to this node","code" : 93,"codeName" : "InvalidReplicaSetConfig"
}

初始化集群失败,集群状态为失败。此时提示是配置项中host无法找到,副本集服务映射到该节点

需要将mongo-master名称修改为真实的ip:172.19.32.142。

config={ _id:"annosys", members:[
{_id:0,host:'172.19.32.142:27017',priority:5},
{_id:1,host:'172.19.32.142:27027',priority:3},
{_id:2,host:'172.19.32.142:27037',arbiterOnly:true}]
}
> rs.initiate(config)
{ "ok" : 1 }

docker搭建mongodb高可用集群相关推荐

  1. docker搭建redis高可用集群

    目标:docker搭建redis高可用集群 1.架构:六个redis容器,三主三从,主从复制,主机宕机从机自动替代 2.网络架构设计:设计一个专属redis的docker网络 docker netwo ...

  2. Nginx配置——搭建 Nginx 高可用集群(双机热备)

    Nginx配置--搭建 Nginx 高可用集群(双机热备) https://blog.csdn.net/zxd1435513775/article/details/102508573?utm_medi ...

  3. 搭建Nginx高可用集群(keepalived+双机热备)

    一.Nginx高可用 首先了解一下什么是高可用,高可用是分布式系统架构中必须考虑的因素. 我们都知道,使用nginx的反向代理和负载均衡可以解决tomcat等web容器的单点故障以及高并发等问题. 反 ...

  4. Windows环境下安装HBase(Hadoop3.1.3、HBase2.2.5)与Linux环境下搭建HBase高可用集群

    Windows环境下安装HBase 下载HBase 官网: https://hbase.apache.org/downloads.html 不同版本集合:https://archive.apache. ...

  5. 容器编排——Kubeadm在线或离线搭建kubernetes高可用集群

    目录 1.架构简介: 2.集群架构图: 3.集群服务器: 4.修改主机名称: 5.修改hosts配置文件: 6.关闭selinux: 7.关闭防火墙: 8.关闭swap: 9.设置iptables网桥 ...

  6. 零基础带你一步步搭建Nacos高可用集群(史上最详细,赛过教科书!)为此我准备了三台云服务器+云数据库

    容我先说一句:节日快乐!永远九岁的我们当然不能错过,奥里给!{容我先说一句:节日快乐!永远九岁的我们当然不能错过,奥里给!}容我先说一句:节日快乐!永远九岁的我们当然不能错过,奥里给! 如果你不懂jd ...

  7. 搭建Eureka高可用集群

    做的快哭了已经 文章目录 Eureka可用高集群的搭建 一.Eureka的工作原理 二.Eureka中服务提供者与服务消费者的关系 三.搭建Eureka-Server和Eureka-Client 四. ...

  8. 二进制方式搭建Kubernetes高可用集群(超丰富的组件概念理论总结)

    二进制方式部署Kubernetes高可用集群 文章目录 二进制方式部署Kubernetes高可用集群 1.环境准备 1.1.Kubernetes高可用集群部署方式 1.2.Kubernetes集群弃用 ...

  9. 基于 Docker 的 Redis 高可用集群搭建(redis-sentinel)

    前言   之前介绍了用docker来搭建redis主从环境,但这只是对数据添加了从库备份(主从复制),当主库down掉的时候,从库是不会自动升级为主库的,也就是说,该redis主从集群并非是高可用的. ...

最新文章

  1. QQ超时不能刷新好友接收发送信息
  2. 通过google app engine 在google cloud 部署支持quic的Java web 应用(多种方式)
  3. 7.18 collection random os sys等模块
  4. curl 增加header_libcurl增加HTTP header 和 POST之后获取返回数据
  5. vue中引入外部文件js、css、img的方法
  6. Matlab 生成vhdl,matlab - 使用HDL Workflow Advisor将Matlab代码转换为vhdl - 堆栈内存溢出...
  7. [转载] Python程序输入一个字符串并查找总数的大写和小写字母
  8. 【Ubantu】Ubantu 20.04设置root账户密码,查看共享文件夹
  9. 产品读书《游戏改变世界:游戏化如何让现实变得更美好》
  10. 国内外有哪些比较好的电子技术的网站类似github?
  11. 倍福---原点断电保持的方法
  12. STL 常用容器的底层数据结构实现
  13. Linux详细到爆炸的一篇文章
  14. mysql 怎样解锁表_mysql一键解锁表
  15. JQuery对象与JavaScript对象的区别与转换
  16. HTB打靶(Active Directory 101 Mantis)
  17. Dataguru(炼数成金)培训优惠码分享
  18. 衰老研究的大问题:百岁老人的长寿秘密是什么?
  19. postgresql之List
  20. JAVA开发地图编辑器_用Java写一个地图编辑器

热门文章

  1. Web 动画帧率(FPS)计算
  2. win10monkey安装教程_详解win10下pytorch-gpu安装以及CUDA详细安装过程
  3. 如何给SCI收录的文章分区?
  4. Linux文件目录颜色的含义
  5. 计算机用通讯电压多少,电脑ATX电源改13.8V通信用电源!
  6. LESS与SASS的伯与仲
  7. 腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面
  8. 未来云计算虚拟化技术的发展趋势
  9. html判断手机浏览器,JS判断浏览器iOS(iPhone)、Android手机移动端
  10. SpannableString字体大小自适应