MongoDB集群之复制集,分片

2022-11-10  本文已影响0人  上善若泪

1 集群

1.1 简介

MongoDB 有三种集群部署模式,分别为主从复制(Master-Slaver)、副本集(Replica Set)和分⽚(Sharding)模式。

1.2 复制集

1.2.1 简介

副本集是一组保持着相同数据集合的mongod实例,其中1个mongod为primary,接收全部写操作其余secodary只负责读操作
primary instance打开oplogsecendary读取oplog,并产生相同的数据集
replicattion set多台服务器维护相同的数据副本,提高服务器的可用性

image.png

副本集中仲裁关系


image.png

1.2.2 复制集设置

1.2.2.1 创建目录并启动

mkdir -p /data/r0 /data/r1 /data/r2

注意:在启动3个实例时,必须要声明 实例属于某复制集

./bin/mongod --port 27017 --dbpath /data/r0  --replSet rsa --fork --logpath /var/log/mongo17.log
./bin/mongod --port 27018 --dbpath /data/r1  --replSet rsa --fork --logpath /var/log/mongo18.log
./bin/mongod --port 27019 --dbpath /data/r2  --replSet rsa --fork --logpath /var/log/mongo19.log

注意:

1.2.2.2 配置及初始化

先随便连上一台服务器,然后切换到admin数据库

var rsconf = {
    _id:'rsa', //复制集名字
    members: //成员集合
    [
        {_id:0,
        host:'192.168.1.201:27017'
        },
        {_id:1,
        host:'192.168.1.201:27018'
        },
        {_id:2,
        host:'192.168.1.201:27019'
        }
      
    ]
}

节点和初始化高级参数:

members:[{
"_id":1,
"host":"127.0.0.1:1111“,
arbiterOnly : true
}]

根据配置做初始化

rs.initiate(rsconf);

查看复制集信息:

查看配置
rs.conf();
查看状态
rs.status();
查看帮助信息
rs.help();

1.2.2.3 操作节点

添加节点

rs.add('192.168.1.201:27018');
rs.add('192.168.1.201:27019');

删除节点

rs.remove('192.168.1.201:27019');

主节点插入数据

>use test
>db.user.insert({uid:1,name:'lily'});

连接secondary查询同步情况

./bin/mongo --port 27019
>use test
>show tables

rsa:SECONDARY> show tables;
Sat Aug 17 16:03:55.786 JavaScript execution failed: error: { "$err" : "not master and slaveOk=false", "code" : 13435 } 

出现上述错误,是因为slave默认不许读写

>rs.slaveOk();
>show tables

1.2.2.4 不正常关闭服务

mongodb不正常关闭形成的mongodb被锁定,这算是一个Mongod启动的一个常见错误,非法关闭的时候,lock 文件没有remove,第二次启动的时候检查到有lock 文件的时候,就报这个错误了

1.3 分片

1.3.1 简介

分片是指把数据分布存储在多台机器上,从而达到存储超大数据,及提高数据吞吐量的目的,分片就要使用命令mongos命令来请求路由

注意:在replication中,每台机器存储的内容是一致的,而sharding中,每台机器存储数据的一部分

image.png

1.3.2 结构

分片要有如下要素:

image.png

mongos查询某条数据时,要先找config server,询问得到该数据在哪个shard分片上

  1. mongs,请求路由
  2. config server,存储元数据--即某台数据存储于某个sharding
    它不存储真的数据,存储meta信息,即某条数据在哪个片上的信息
  3. shard--mongod实例或repla set

1.3.3 配置分片

1.3.3.1 创建分片服务

./bin/mongod --port 27017 --dbpath share/data01 --logpath logs/mongod01.log --fork --replSet share --shardsvr

./bin/mongod --port 27018 --dbpath share/data02 --logpath logs/mongod02.log --fork --replSet share --shardsvr

./bin/mongod --port 27019 --dbpath share/data03 --logpath logs/mongod03.log --fork --replSet share --shardsvr

1.3.3.2 创建配置服务

创建配置服务,这里我们完全可以像启动普通mongodb服务一样启动

./bin/mongod --port 28017 --dbpath replSet/data01 --logpath logs/mongod01.log --fork --replSet config --configsvr

./bin/mongod --port 28018 --dbpath replSet/data02 --logpath logs/mongod02.log --fork --replSet config --configsvr

./bin/mongod --port 28019 --dbpath replSet/data03 --logpath logs/mongod03.log --fork --replSet config --configsvr

1.3.3.3 配置连接路由

配置mongos,通过 configdb 来说明是为哪个服务服务的

./bin/mongos --port 30000 --logpath /var/log/mongo30.log\
 --configdb 127.0.0.1:27020 --fork

报错:

BadValue: configdb supports only replica set connection string

如上, 出现这个问题, 是因为使用的MongoDB 5.0.6版,这个版本在之前的版本上有做调整,要求configs服务器是副本集模式。3.2和3.2以下都不做强制要求的。
解决办法:

  1. configs服务器配置成副本集模式
    比如:./bin/mongos --port 30000 --configdb rsa/127.0.0.1:28017 --logpath logs/router.log --fork
  2. 把MongoDB换成3.4以下版本

连接路由器,通过mongos的端口连接

./bin/mongo --port 30000

1.3.3.4 添加分片

sh.addShard('share/127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019');

分片相关的状态

sh.status();

查看帮助信息

sh.help();

1.3.3.5 对库表进行分片

添加待分片的库

sh.enableSharding(databaseName);

添加待分片的文档

>sh.shardCollection('dbName.collection',{field:1});

fieldcollection的一个字段,系统将会利用filed的值,来计算应该分到哪一个片上.这个filed片键(shard key)

1.3.3.6 分片相关问题

mongodb不是从单篇文档的级别,绝对平均的散落在各个片上,而是N篇文档,形成一个块chunk,优先放在某个片上,当这片上的chunk,比另一个片的chunk,区别比较大时, (>=3) ,会把本片上的chunk,移到另一个片上,以chunk为单位,维护片之间的数据均衡

问: 为什么插入了10万条数据,才2个chunk?
答: 说明chunk比较大(默认是64M),在config数据库中,修改chunksize的值
查看chunk大小:db.settings.find()
修改命令:db.settings.save({_id:'chunksize,value:1});

问: 既然优先往某个片上插入,当chunk失衡时(一个片34chunk,另一个36chunk),会自动移动chunk,自然随着数据的增多,shard的实例之间有chunk来回移动的现象,这将带来什么问题?
答: 服务器之间IO的增加,

问: 能否自定义一个规则,某N条数据形成1个块,预告分配M个chunk,M个chunk预告分配在不同片上,以后的数据直接入各自预分配好的chunk,不再来回移动?
答: 能,手动预先分片

1.3.4 手动预先分片

以shop.user表为例

  1. 配置分片的表
    user表用userid做shard key
    sh.shardCollection('shop.user',{userid:1});
  2. 使用sh.splitAt分片
    预先在1K 2K...40K这样的界限切好chunk(虽然chunk是空的), 这些chunk将会均匀移动到各片上.
    for(var i=1;i<=40;i++) { sh.splitAt('shop.user',{userid:i*1000}) }
  3. 通过mongos添加user数据
    数据会添加到预先分配好的chunk上,chunk就不会来回移动了.

1.3.5 复制集和分片相结合

配置复制集参考上面步骤
配置分片参考上面步骤,向分片中添加复制集分片时不同
sh.addShard('复制集名字'/ip:port);

sh.addShard('rsa/127.0.0.1:27017');
sh.addShard('rsa/127.0.0.1:27018');
上一篇 下一篇

猜你喜欢

热点阅读