常见的 MongoDB 集群有三种,分别是主从复制、副本集和分片,这篇文章将会对副本集进行简单的介绍
开始先说一下,这篇文章用到的所有代码都是经过本地测试的,博主用于测试的操作系统为 CentOS 7
好,下面正式开始!
之前讲到,主从复制集群利用从节点对主节点的数据进行备份,在主节点发生故障后可以手动恢复数据
但是这里有一个问题,那就是每次当主节点发生故障后,都需要暂停服务并且手动转移数据
不仅十分麻烦,而且暂停服务所带来的损失更是无法估量的,副本集就是为了解决这个问题而出现了
在一个副本集(Replica Set)中,包含多个数据承载节点(Data Bearing)和仲裁节点(Arbiter)
数据承载节点又可以细分为主节点(Primary)和从节点(Secondary),它们各自的描述如下:
主节点:有且仅有一个,默认情况下对客户端提供所有增删改查的服务从节点:备份主节点数据,可提供查询服务,在主节点挂掉后要选一个从节点作为主节点继续提供服务仲裁节点:不储存数据,在主节点挂掉后决定哪一个从节点被选为主节点副本集的特征如下:
写操作仅在主节点上,并同步到从节点以保证数据的一致性读操作既可以在主节点上,也可以在从节点上,在一定程度上可以减轻主节点的负担当主节点挂掉后,会选举一个从节点作为主节点继续提供服务,因此无需进行停机维护下面是一个简单的模拟,一个主节点,一个从节点,一个仲裁节点
(1)下载 MongoDB
> su > cd /root > mkdir mongodb-replica-set-cluster > cd mongodb-replica-set-cluster > mkdir mongodb > cd mongodb > wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.7.tgz > tar -zxvf mongodb-linux-x86_64-3.2.7.tgz > cd ..(2)创建三个文件夹,分别模拟主节点、从节点和仲裁节点
> mkdir primary # 主节点 > touch ./primary/mongodb.conf > mkdir ./primary/log > mkdir -p ./primary/data/db > mkdir secondary # 从节点 > touch ./secondary/mongodb.conf > mkdir ./secondary/log > mkdir -p ./secondary/data/db > mkdir arbiter # 仲裁节点 > touch ./arbiter/mongodb.conf > mkdir ./arbiter/log > mkdir -p ./arbiter/data/db创建完成之后,目录结构如下
+ mongodb-replica-set-cluster + mongodb + mongodb-linux-x86_64-3.2.7.tgz + mongodb-linux-x86_64-3.2.7 + primary + log + data + db + mongodb.conf + secondary + log + data + db + mongodb.conf + arbiter + log + data + db + mongodb.conf(3)写配置文件
# primary/mongodb.conf 文件内容 # 数据文件的存放位置 dbpath = /root/mongodb-replica-set-cluster/primary/data/db # 日志文件的存放位置 logpath = /root/mongodb-replica-set-cluster/primary/log/mongodb.log # 监听的端口,默认为 27017 port = 27001 # 以守护进程的方式运行 MongoDB fork = true # 设置 replSet 名称 replSet = repl # secondary/mongodb.conf 文件内容 # 数据文件的存放位置 dbpath = /root/mongodb-replica-set-cluster/secondary/data/db # 日志文件的存放位置 logpath = /root/mongodb-replica-set-cluster/secondary/log/mongodb.log # 监听的端口,默认为 27017 port = 27002 # 以守护进程的方式运行 MongoDB fork = true # 设置 replSet 名称 replSet = repl # arbiter/mongodb.conf 文件内容 # 数据文件的存放位置 dbpath = /root/mongodb-replica-set-cluster/arbiter/data/db # 日志文件的存放位置 logpath = /root/mongodb-replica-set-cluster/arbiter/log/mongodb.log # 监听的端口,默认为 27017 port = 27003 # 以守护进程的方式运行 MongoDB fork = true # 设置 replSet 名称 replSet = repl(4)分别开启三个数据库
> cd /root/mongodb-replica-set-cluster/mongodb/mongodb-linux-x86_64-3.2.7/bin/ > ./mongod -f /root/mongodb-replica-set-cluster/primary/mongodb.conf > ./mongod -f /root/mongodb-replica-set-cluster/secondary/mongodb.conf > ./mongod -f /root/mongodb-replica-set-cluster/arbiter/mongodb.conf之后,应该可以看到有三个 MongoDB 进程正在运行
> ps aux | grep mongo(5)连接到任意一个节点,初始化节点之间的关系
> cd /root/mongodb-replica-set-cluster/mongodb/mongodb-linux-x86_64-3.2.7/bin/ > ./mongo mongodb://127.0.0.1:27001/admin > rs.initiate({ "_id": "repl", "members": [ // 添加数据承载节点 { "_id": 1, "host": "127.0.0.1:27001" }, { "_id": 2, "host": "127.0.0.1:27002" } ] }) // { "ok" : 1 } repl:OTHER> rs.addArb("127.0.0.1:27003") // 添加仲裁节点 // { "ok" : 1 } repl:PRIMARY> rs.status() // 在设置成功后,应该可以看到具体的配置信息打开新的终端,连接到主数据库,插入一条数据(可写),之后对其进行查询(可读)
> cd /root/mongodb-replica-set-cluster/mongodb/mongodb-linux-x86_64-3.2.7/bin/ > ./mongo mongodb://127.0.0.1:27001/admin PRIMARY> db.user.insert({'username': 'Alice', 'password': '123456'}) // 插入数据(可写) // WriteResult({ "nInserted" : 1 }) PRIMARY> db.user.find() // 查询数据(可读) // { "username" : "Alice", "password" : "123456" }打开另外一个终端,连接到从节点,查询在主数据库插入的数据(可读),之后尝试插入一条新的数据(不可写)
> cd /root/mongodb-replica-set-cluster/mongodb/mongodb-linux-x86_64-3.2.7/bin/ > ./mongo mongodb://127.0.0.1:27002/admin SECONDARY> rs.slaveOk() // 在查询之前需要先设置从节点状态 SECONDARY> db.user.find() // 查询数据(可读) // { "username" : "Alice", "password" : "123456" } SECONDARY> db.user.insert({'username': 'Bob', 'password': 'abc'}) // 插入数据(不可写) // WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })好,接下来新开一个终端,手动关闭主节点,模拟主节点挂掉的情况
> cd /root/mongodb-replica-set-cluster/mongodb/mongodb-linux-x86_64-3.2.7/bin/ > ./mongod --shutdown --dbpath /root/mongodb-replica-set-cluster/primary/data/db然后在连接着 127.0.0.1:27002 的终端里查看当前副本集的状态
SECONDARY> rs.status()并且可以看到该节点已经成为主节点(注意此时命令行头已经发生改变),可以在里面插入和查询数据
PRIMARY> db.user.insert({'username': 'Bob', 'password': 'abc'}) // 插入数据(可写) // WriteResult({ "nInserted" : 1 }) PRIMARY> db.user.find() // 查询数据(可读) // { "username" : "Alice", "password" : "123456" } // {'username': 'Bob', 'password': 'abc'}【 阅读更多 MongoDB 系列文章,请看 MongoDB学习笔记 】
转载于:https://www.cnblogs.com/wsmrzx/p/11599039.html
相关资源:JAVA上百实例源码以及开源项目