Windows下Mongo分片及集群
这里简单介绍一下windows下mongodb的分片设置和集群搭建,希望能够为迷茫的新手起到一点点作用。其实windows下与linux下思路是一致的,只是绑定时的ip,与端口号不同,linux下可以开三台虚拟机分别设置ip,然后通过端口号设置分片,集群;windows下是通过黑窗口来运行的,当然只有一个本机ip:127.0.0.1,然后通过端口号的不同进行绑定。
分片涉及到相关内容:首先要知道的是几个名称,路由服务器:分配管理数据,应答客户或者称为mongos;分片服务器:用于存储数据;配置服务器:用于存储路由服务器的信息;分片服务器与配置服务器的信息均存储在内存中。
实现描述:首先是要明确是先设置复制集还是分片,根据本人实验结果是先搭建复制集然后将复制集作为分片的分片服务器添加进去,再进行分片的设置。这样就既可以快速读取数据,又可以防止数据丢失。在黑窗口运行时,要保证所要求的不同磁盘下的文件夹存在。
复制集:
Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持复制集内所有成员存储相同的数据集,提供数据的高可用。
分片:
分片集群(sharded cluster)是一种水平扩展数据库系统性能的方法,能够将数据集分布式存储在不同的分片(shard)上,每个分片只保存数据集的一部分,MongoDB保证各个分片之间不会有重复的数据,所有分片保存的数据之和就是完整的数据集。分片集群将数据集分布式存储,能够将负载分摊到多个分片上,每个分片只负责读写一部分数据,充分利用了各个shard的系统资源,提高数据库系统的吞吐量。
集群的三种方式:
①Replica Set(副本集/复制集)
集群中包含多份数据,当主节点故障,备用节点能继续提供服务。
- 高可用(主要目标):当一个结点故障时自动切换到其他结点;
- 数据冗余(主要目标):数据复制到n个结点上,增加数据安全性,同时为高可用提供基础;
- 功能隔离(次要目标):使用不同的结点隔离某些有特殊需求的功能,比如使用一个结点进行OLAP运算(大规模资源占用),使用一个结点在远程做灾备(性能要求不如本地高),读写分离等等;
副本集有三种角色,分别为主节点、副本节点和仲裁节点(可选)。
主节点具有完全的读写操作,并且只有主节点可以进行写操作。
副本节点同步主节点的oplog,保持数据一致。
仲裁节点不保存数据副本,只在选举主节点的投票中有投票权。
②Sharded Cluster(分片集):
分片集主要优势在于:
- 水平扩展:当一台服务器满足不了需求的时候,我们可以选择垂直扩展(增加服务器硬件),它虽然简单,但很容易达到极限,并且面临成本高等明显缺点。成本更低的方式是使用n台服务器组成集群来满足系统需求。这就是分片集的主要设计目标;
- 缩短响应时间:因为可以把数据分散到多台服务器上,自然每台服务器的处理压力减小,处理时间就会缩短;
这里会出现一个问题:假设每台服务器出故障的机率是x%
,那么n
台服务器有一台出现故障的机率就是x% * n
,如果不做高可用设计,集群出现故障的概率就会随机器数量成正比增长,这在工程上是不能接受的。幸运的是我们已经有了解决高可用的方案,也就是复制集。所以MongoDB的分片集群要求每一个片都是复制集(当然测试环境也可以使用单结点,生产环境不推荐)。
分片群集由三部分构成:
1.shard,存储了分片数据,可部署成一个副本集。
2.mongos,路由器,连接客户端和分片群集,使分片操作对客户端透明。可部署成一个副本集。
3.config server,配置服务器,存储元数据和配置数据。3.4以后必须部署成副本集。
③Master-Slaver(官方不推荐):
主备节点方式,只能从Master复制数据到Slave,并不提供高可用,一旦Master结点出故障就比较难处理。
教程:
https://blog.csdn.net/bfdnmy/article/details/51842217
集群环境测试,因服务器有限,使用一台服务器进行分片集群(每一个片都是复制集);
Mongdb 安装这里不在赘述。直接开始布置集群环境。
首先,建立服务器文件地址:
这里我们分为2片,复制集三个节点。
IP地址:192.168.168.185(片及复制集均可分服务器存放,最多存在6个ip,测试时采用一台服务器进行环境搭建)
片1:
集群(复制集)名称:replcopy1
集群IP:192.168.168.185(服务器1-1)、192.168.168.185(服务器1-2)、192.168.168.185(服务器1-3)
服务器1-1数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared1-1\data 端口号:1111
服务器1-2数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared1-2\data 端口号:1112
服务器1-3数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared1-3\data 端口号:1113
片2:
集群(复制集)名称:replcopy2
集群IP:192.168.168.185(服务器2-1)、192.168.168.185(服务器2-2)、192.168.168.185(服务器2-3)
服务器2-1数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared=2-1\data 端口号:2221
服务器2-2数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared2-2\data 端口号:2222
服务器2-3数据存放地址:C:\WindaTest\mongodb-3.6.4\mongodb\shared2-3\data 端口号:2223
1、分别启动服务器,以分片1为例:
mongod --port 1111 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared1-1\data --replSet=replcopy1
mongod --port 1112 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared1-2\data --replSet=replcopy1
mongod --port 1113 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared1-3\data --replSet=replcopy1
开三个cmd窗口分别执行:
2、初始化
任意进入一台复制集
mongo 192.168.168.185:1111
(任意选择客户端进入)
设置配置:
config = {
_id:"replcopy1",
members:[{
_id:1,host:"192.168.168.185:1111"
},{
_id:2,
host:"192.168.168.185:1112"
},{
_id:3,
host:"192.168.168.185:1113"
}]
}
rs.initiate(config)
#初始化
rs.conf()
#查看配置
rs.status()
#查看状态
rs.isMaster()
#查看是否是主节点
同理,将片2一样启动:
mongod --port 2221 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared2-1\data --replSet=replcopy2
mongod --port 2222 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared2-2\data --replSet=replcopy2
mongod --port 2223 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared2-3\data --replSet=replcopy2
mongo 192.168.168.185:2221
config = {
_id:"replcopy2",
members:[{
_id:1,
host:"192.168.168.185:2221"
},{
_id:2,
host:"192.168.168.185:2222"
},{
_id:3,
host:"192.168.168.185:2223"
}]
}
rs.initiate(config)
#初始化
rs.conf()
#查看配置
rs.status()
#查看状态
rs.isMaster()
#查看是否是主节点
以片2为例:
在主节点2221端口服务器,插入数据:
show dbs
show collections
db.student.insert({name:"zhangsan"})
show collections
设置从节点读写分离:
登录某从节点,设置该节点为从节点。
rs.slaveOk()
db.getMongo().setSlaveOk()
不设置的话,无法查询主节点上的数据。这里以端口号为2222的服务器为例:
当未进行设置时,无权对数据进行操作
设置完之后:
注意:从节点只有读的权限。
查看当前服务器状态:
用下面命令查看
rs.status()
#查看状态
rs.isMaster()
#查看是否是主节点
rs.conf()
#查看配置
可以看到当前节点不是主节点。
故障转移测试:
依旧以片2服务器复制集为例,我们断掉主节点,ctr+c停止端口为2221的mongo运行(注意不是关闭cmd窗口)
关掉之后我们再来查看端口为2222的服务器状态:
看到主节点变成2223了,故障转移是成功的,数据保存在了2223中。
片集建立好之后,开始建立分片系统;
1、服务器信息
配置服务器:
端口号:3333
IP:192.168.168.185
路径:C:\WindaTest\mongodb-3.6.4\config_server
路由服务器:
端口号:4444
IP:192.168.168.185
分片服务器1:
端口号为: 1111
IP:192.168.168.185
分片服务器2:
端口号为: 2222
IP: 192.168.168.185
2、开启配置服务器(这一步高版本有问题,往后翻;低于3.4版本可正常)
mongod --dbpath C:\WindaTest\mongodb-3.6.4\config_server\data --logpath C:\WindaTest\mongodb-3.6.4\config_server\3333.log --port 3333 --bind_ip=192.168.168.185 –journal
开启之后页面无任何变化,可以查看日志,服务器已经开启成功。
3、开启路由服务器
mongos --port 4444 --bind_ip=192.168.168.185 --configdb 192.168.168.185:3333
出错:
此时这里报错,查到资料
高版本的mongo要求config server必须是集群模式,不能单点,包括配置和访问都会涉及这点,与旧版不同。
既然如此,重新配置配置服务器,第二步重新配置:
mongod --port 3331 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\config_server\share1\data --configsvr --replSet=conf
mongod --port 3332 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\config_server\share2\data --configsvr --replSet=conf
mongod --port 3333 --bind_ip=192.168.168.185 --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\config_server\share3\data --configsvr --replSet=conf
mongo 192.168.168.185:3331
config = {_id:"conf", members:[
{_id:0, host:"192.168.168.185:3331"},
{_id:1, host:"192.168.168.185:3332"},
{_id:2, host:"192.168.168.185:3333"}
]
};
rs.initiate(config);
以上不会操作的话,参照片1配置开启即可。
现在开始重新开启路由服务器:
mongos --port 4444 --bind_ip 192.168.168.185 --shardsvr --logpath C:\WindaTest\mongodb-3.6.4\mongos\mongos.log --configdb --replSet/conf/192.168.168.185:3331,192.168.168.185:3332,192.168.168.185:3333
这里需要注意的点就是高版本必须增加参数--configdb --replSet/conf/,即必须指定复制集。
同样,路由服务器开启之后仍然没有任何反应,可通过日志判断,路由服务开启成功。
服务器配置,添加分片集,client直接跟mongos打交道,也就说明我们要连接mongos服务器,然后将1111,2222的mongod交给mongos,添加分片也就是addshard()
1、首先保证分片集已经全部启动。
2、mongo 192.168.168.185:4444/admin
必须是在admin下执行此操作
添加分片集:
db.runCommand({addshard:"replcopy1/192.168.168.185:1111",allowLocal:true})
db.runCommand({addshard:"replcopy2/192.168.168.185:2221",allowLocal:true})
3、查看整个集群分片机制
在路由服务器中执行
show dbs
use config
show collections
db.shards.find()
4、设置片键
片已经集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步
①.开数据分片功能,为数据库test打开分片功能
use admin
db.runCommand({"enablesharding":"test"})
②对集合进行分片(片键即key决定了你的分片服务器的数据分配,一般以_id为片键,1表示升序)
db.runCommand({"shardcollection":"test.goods","key":{"_id":1}})
5、测试,观察效果
mongo 192.168.168.185:4444
use test
①插入50W行数据
for(var i=0;i<500000;i++){
db.goods.insert({id:i,name:"goods"+i})
}
插入数据时,有可能会报错:
出问题的状况可能有很多种,检查一遍之后发现,片2的192.168.168.185:2221不是主节点,将2221端口mongo更改为主节点之后,插入成功(设置主节点没有找到有效方法,将其他两个节点关闭再重新开启,2221会自动变为主节点)
后来发现设置主节点了也没有用,将所有的分片重新启动,启动的时候加上参数-shardsvr即可:
mongod --shardsvr --dbpath C:\WindaTest\mongodb-3.6.4\mongodb\shared1-1\data --port 1111 --bind_ip=192.168.168.185 --replSet=replcopy1
(删除数据库:(先切换到要删除的数据库 use dbname)
db.dropDatabase()
)
db.goods.find()
②分别在不同的库中,观察分片的集合的内容
mongo 192.168.168.185:1111 mongo 192.168.168.185:2222(链接主节点) use test db.goods.find().count() db.goods.stats()
③
查看配置库对于分片服务器的配置存储
在路由服务器中执行
db.printShardingStatus()
将Mongo封为windows服务启动:
片集1:
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared1-1\mongo.config --install --serviceName "Shared11"
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared1-2\mongo.config --install --serviceName "Mongo_Shared1_2"
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared1-3\mongo.config --install --serviceName "Mongo_Shared1_3"
片集2:
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared2-1\mongo.config --install --serviceName "Mongo_Shared2_1"
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared2-2\mongo.config --install --serviceName "Mongo_Shared2_2"
mongod --config C:\WindaTest\mongodb-3.6.4\mongodb\shared2-3\mongo.config --install --serviceName "Mongo_Shared2_3"
配置服务器集群:
mongod --config C:\WindaTest\mongodb-3.6.4\config_server\share1\mongo.config --install --serviceName "Mongo_Shared3_1"
mongod --config C:\WindaTest\mongodb-3.6.4\config_server\share2\mongo.config --install --serviceName "Mongo_Shared3_2"
mongod --config C:\WindaTest\mongodb-3.6.4\config_server\share3\mongo.config --install --serviceName "Mongo_Shared3_3"