MongoDB 分片集群技术
温馨提示:这篇文章已超过620天没有更新,请注意相关的内容是否还可用!
C/C++Linux服务器开发/后台架构师知识体系整理
1. MongoDB复制集简介
一组 Mongodb 复制集,就是一组 mongod 进程,这些进程维护同一个数据集合。复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础。
1.1 复制集的目的
保证数据在生产部署时的冗余和可靠性,通过在不同的机器上保存副本来保证数据的不会因为单点损坏而丢失。能够随时应对数据丢失、机器损坏带来的风险。
换一句话来说,还能提高读取能力,用户的读取服务器和写入服务器在不同的地方,而且,由不同的服务器为不同的用户提供服务,提高整个系统的负载。
1.2 简单介绍
一组复制集就是一组 mongod 实例掌管同一个数据集,实例可以在不同的机器上面。实例中包含一个主导,接受客户端所有的写入操作,其他都是副本实例,从主服务器上获得数据并保持同步。.
主服务器很重要,包含了所有的改变操作(写)的日志。但是副本服务器集群包含有所有的主服务器数据,因此当主服务器挂掉了,就会在副本服务器上重新选取一个成为主服务器。
每个复制集还有一个仲裁者,仲裁者不存储数据,只是负责通过心跳包来确认集群中集合的数量,并在主服务器选举的时候作为仲裁决定结果。
2. 复制的基本架构
基本的架构由3台服务器组成,一个三成员的复制集,由三个有数据,或者两个有数据,一个作为仲裁者。
2.1 三个存储数据的复制集
具有三个存储数据的成员的复制集有:
一个主库;
两个从库组成,主库宕机时,这两个从库都可以被选为主库。
当主库宕机后,两个从库都会进行竞选,其中一个变为主库,当原主库恢复后,作为从库加入当前的复制集群即可。
2.2 当存在 arbiter 节点
在三个成员的复制集中,有两个正常的主从,及一台 arbiter 节点:
一个主库
一个从库,可以在选举中成为主库
一个 aribiter 节点,在选举中,只进行投票,不能成为主库
说明:
由于 arbiter 节点没有复制数据,因此这个架构中仅提供一个完整的数据副本。arbiter 节点只需要更少的资源,代价是更有限的冗余和容错。
当主库宕机时集群存储技术,将会选择从库成为主,主库修复后,将其加入到现有的复制集群中即可。
2.3 Primary 选举
复制集通过 replSetInitiate 命令(或 mongo shell 的 rs.initiate())进行初始化集群存储技术,初始化后各个成员间开始发送心跳消息,并发起 Priamry 选举操作,获得『大多数』成员投票支持的节点,会成为 Primary,其余节点成为 Secondary 。
『大多数』的定义
假设复制集内投票成员(后续介绍)数量为N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
通常建议将复制集成员数量设置为奇数,从上表可以看出3个节点和4个节点的复制集都只能容忍1个节点失效,从『服务可用性』的角度看,其效果是一样的。(但无疑4个节点能提供更可靠的数据存储)
3. 复制集中成员说明 3.1 所有成员说明
3.2 Priority 0节点
作为一个辅助可以作为一个备用。在一些复制集中,可能无法在合理的时间内添加新成员的时候。备用成员保持数据的当前最新数据能够替换不可用的成员。
3.3 Hidden 节点(隐藏节点)
客户端将不会把读请求分发到隐藏节点上,即使我们设定了 复制集读选项 。
这些隐藏节点将不会收到来自应用程序的请求。我们可以将隐藏节点专用于报表节点或是备份节点。 延时节点也应该是一个隐藏节点。
3.4 Delayed 节点(延时节点)
延时节点的数据集是延时的,因此它可以帮助我们在人为误操作或是其他意外情况下恢复数据。
举个例子,当应用升级失败,或是误操作删除了表和数据库时,我们可以通过延时节点进行数据恢复。
4. 配置MongoDB复制集 4.1 环境说明
系统环境说明:
[root@MongoDB ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
[root@MongoDB ~]# uname -r
2.6.32-696.el6.x86_64
[root@MongoDB ~]# /etc/init.d/iptables status
iptables: Firewall is not running.
[root@MongoDB ~]# getenforce
Disabled
[root@MongoDB ~]# hostname -I
10.0.0.152 172.16.1.152
软件版本说明
本次使用的mongodb版本为:mongodb-linux-x86_64-3.2.8.tgz
4.2 前期准备,在root用户下操作
本次复制集复制采用Mongodb多实例进行
所有的操作都基于安装完成的mongodb服务,详情参照:#_label3
#创建mongod用户
useradd -u800 mongod
echo 123456|passwd --stdin mongod
# 安装mongodb
mkdir -p /mongodb/bin
cd /mongodb
wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.8.tgz
tar xf mongodb-linux-x86_64-3.2.8.tgz
cd mongodb-linux-x86_64-3.2.8/bin/ &&\
cp * /mongodb/bin
chown -R mongod.mongod /mongodb
# 切换到mongod用户进行后续操作
su - mongod
4.3 创建所需目录
for i in 28017 28018 28019 28020
do
mkdir -p /mongodb/$i/conf
mkdir -p /mongodb/$i/data
mkdir -p /mongodb/$i/log
done
4.4 配置多实例环境
编辑第一个实例配置文件
cat >>/mongodb/28017/conf/mongod.conf<<'EOF'
systemLog:
destination: file
path: /mongodb/28017/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/28017/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
# cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
port: 28017
replication:
oplogSizeMB: 2048
replSetName: my_repl
EOF
复制配置文件
for i in 28018 28019 28020
do
\cp /mongodb/28017/conf/mongod.conf /mongodb/$i/conf/
done
修改配置文件
for i in 28018 28019 28020
do
sed -i "s#28017#$i#g" /mongodb/$i/conf/mongod.conf
done
启动服务
for i in 28017 28018 28019 28020
do
mongod -f /mongodb/$i/conf/mongod.conf
done
#关闭服务的方法
for i in 28017 28018 28019 28020
do
mongod --shutdown -f /mongodb/$i/conf/mongod.conf
done
4.5 配置复制集
登陆数据库,配置mongodb复制
shell> mongo --port 28017
config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.152:28017'},
{_id: 1, host: '10.0.0.152:28018'},
{_id: 2, host: '10.0.0.152:28019'}]
}
初始化这个配置
> rs.initiate(config)
到此复制集配置完成
4.6 测试主从复制
在主节点插入数据
my_repl:PRIMARY> db.movies.insert([ { "title" : "Jaws", "year" : 1975, "imdb_rating" : 8.1 },
{ "title" : "Batman", "year" : 1989, "imdb_rating" : 7.6 },
] );
在主节点查看数据
my_repl:PRIMARY> db.movies.find().pretty()
{
"_id" : ObjectId("5a4d9ec184b9b2076686b0ac"),
"title" : "Jaws",
"year" : 1975,
"imdb_rating" : 8.1
}
{
"_id" : ObjectId("5a4d9ec184b9b2076686b0ad"),
"title" : "Batman",
"year" : 1989,
"imdb_rating" : 7.6
}
注:在mongodb复制集当中,默认从库不允许读写。
在从库打开配置(危险)
注意:严禁在从库做任何修改操作
my_repl:SECONDARY> rs.slaveOk()
my_repl:SECONDARY> show tables;
movies
my_repl:SECONDARY> db.movies.find().pretty()
{
"_id" : ObjectId("5a4d9ec184b9b2076686b0ac"),
"title" : "Jaws",
"year" : 1975,
"imdb_rating" : 8.1
}
{
"_id" : ObjectId("5a4d9ec184b9b2076686b0ad"),
"title" : "Batman",
"year" : 1989,
"imdb_rating" : 7.6
}
在从库查看完成在登陆到主库
4.7 复制集管理操作
(1)查看复制集状态:
rs.status(); # 查看整体复制集状态
rs.isMaster(); # 查看当前是否是主节点
(2)添加删除节点
rs.add("ip:port"); # 新增从节点
rs.addArb("ip:port"); # 新增仲裁节点
rs.remove("ip:port"); # 删除一个节点
注:
添加特殊节点时,
1>可以在搭建过程中设置特殊节点
2>可以通过修改配置的方式将普通从节点设置为特殊节点
/找到需要改为延迟性同步的数组号/;
(3)配置延时节点(一般延时节点也配置成hidden)
cfg=rs.conf()
cfg.members[2].priority=0
cfg.members[2].slaveDelay=120
cfg.members[2].hidden=true
注:这里的2是rs.conf()显示的顺序(除主库之外),非ID
重写复制集配置
rs.reconfig(cfg)
也可将延时节点配置为arbiter节点
cfg.members[2].arbiterOnly=true
配置成功后,通过以下命令查询配置后的属性
rs.conf();
4.8 副本集其他操作命令
查看副本集的配置信息
my_repl:PRIMARY> rs.config()
查看副本集各成员的状态
my_repl:PRIMARY> rs.status()
4.8.1 副本集角色切换(不要人为随便操作)
rs.stepDown()
rs.freeze(300) # 锁定从,使其不会转变成主库,freeze()和stepDown单位都是秒。
rs.slaveOk() # 设置副本节点可读:在副本节点执行
插入数据
> use app
switched to db app
app> db.createCollection('a')
{ "ok" : 0, "errmsg" : "not master", "code" : 10107 }
查看副本节点
> rs.printSlaveReplicationInfo()
source: 192.168.1.22:27017
syncedTo: Thu May 26 2016 10:28:56 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
C/C++Linux服务器开发/高级架构师系统性学习课程
Linux服务器开发/架构师面试题、学习资料、教学视频和学习路线图(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享有需要的可以自行添加学习交流群960994558