mongoDB的操作总结

1、mongodb副本集数据同步

从mongodb2.0开始支持链式复制,并且默认是开启的,是根据second节点之间的ping time和网络距离进行选择那个second作为数据的同步节点,链式复制的优点:可以减少master的资源消耗,减少负载。缺点:节点之间同步数据本来就不可避免会有数据的延迟,执行链式复制的过程会使这个时间增大,该second节点的数据就会比其他的更落后于master,所以在读取数据的时候就会有一些问题,比如读取数据读不到,后端服务就会抛错,导致用户能感知到,非常不好,当然可以通过降低数据延迟来缓解,保证节点见的网络带宽流畅、io等。

方案

了解了副本集之间的复制方式,接下来就开始着手解决这个数据延迟的问题,从官网来看有两种方式:使用rs.syncFrom()设置同步源、禁用掉链式复制

1、rs.syncFrom

官网对于这个命令的介绍:

Provides a wrapper around the replSetSyncFrom, which allows administrators to temporarily override the default sync target for the current member. Specify the name of the member you want to replicate from in the form of [hostname]:[port].

Changed in version 3.2: MongoDB 3.2 replica set members with vote cannot sync from members with 0votes

>rs.syncFrom("myHost:27017");

2、禁用掉链式复制

Disable Chained Replication

To disable chained replication, set the settings.chainingAllowed field in Replica Set Configuration to false.

If chained replication is disabled, you still can use replSetSyncFrom to specify that a secondary replicates from another secondary. But that configuration will last only until the secondary recalculates which member to sync from.(禁用了链式复制以后,还是可以通过replSetSyncFrom指定复制源为second,但是必须要有投票权

You can use the following sequence of commands to set settings.chainingAllowed to false:

cfg = rs.config()

cfg.settings.chainingAllowed = false
rs.reconfig(cfg)

Re-enable Chained Replication

To re-enable chained replication, set settings.chainingAllowed to true. You can use the following sequence of commands:

cfg = rs.config()
cfg.settings.chainingAllowed = true
rs.reconfig(cfg)

3、常用监控方法

rs.printSlaveReplicationInfo()  打印数据同步延迟信息

rs.printReplicationInfo()  打印oplog信息

具体遇到数据同步延迟的,需要具体分析当时的情况,不能盲目的修改。首先考虑节点服务器的负载情况和当时的网络环境是否正常,有的时候可能是网络环境导致的,排除这些原因后,再去考虑修改同步源。这样要做好读写分离,否则master的压力会非常大。如果master的压力太大就要做一些处理,比如切换一下msater升级资源或使用replSetSyncFrom切换同步源到second上。

4. 更改节点优先级

修改节点的优先级可以触发重新选举,这样可以人工指定主节点。
使用如下命令,在主节点登录,将192.168.1.3提升为Master。

rs.conf();
cfg=rs.conf();
cfg.members[0].priority=1
cfg.members[1].priority=1
cfg.members[2].priority=10
rs.reconfig(cfg);

需要注意的是,修改节点优先级需要登录Master节点运行。否则报错。

再次查看集群状态,可以看到192.168.1.3已经作为Master运行

5 .节点类型

MongoDB的节点类型有主节点(Master),副本节点(Slave或者称为Secondary),仲裁节点,Secondary-Only节点,Hidden节点,Delayed节点和Non-Voting节点。

仲裁节点不存储数据,只是负责故障转移的群体投票,这样就少了数据复制的压力。

Secondary-Only:不能成为primary节点,只能作为secondary副本节点,防止一些性能不高的节点成为主节点。

Hidden:这类节点是不能够被客户端制定IP引用,也不能被设置为主节点,但是可以投票,一般用于备份数据。

Delayed:可以指定一个时间延迟从primary节点同步数据。主要用于备份数据,如果实时同步,误删除数据马上同步到从节点。所以延迟复制主要用于避免用户错误。

Non-Voting:没有选举权的secondary节点,纯粹的备份数据节点。

6 .设置隐藏节点(Hidden)
隐藏节点可以在选举中投票,但是不能被客户端引用,也不能成为主节点。也就是说这个节点不能用于读写分离的场景。
将192.168.1.3设置为隐藏节点。
注意,只有优先级为0的成员才能设置为隐藏节点。
如果设置优先级不为0的节点为隐藏节点,则报错如下

使用如下命令设置隐藏节点

cfg=rs.conf();
cfg.members[0].priority=10
cfg.members[1].priority=1
cfg.members[2].priority=0
cfg.members[2].hidden=1
rs.reconfig(cfg);

设置完成之后,使用rs.status()查看该节点还是SECONDARY状态。
但是通过rs.isMaster()和rs.conf()可以看到这个节点的变化。
rs.isMaster()的hosts中192.168.1.3节点已经不可见

并且rs.conf()显示该节点状态为hidden

 

7 .设置仲裁节点
仲裁节点不存储数据,只是用于投票。所以仲裁节点对于服务器负载很低。
节点一旦以仲裁者的身份加入集群,他就只能是仲裁者,无法将仲裁者配置为非仲裁者,反之也是一样。
另外一个集群最多只能使用一个仲裁者,额外的仲裁者拖累选举新Master节点的速度,同时也不能提供更好的数据安全性。
初始化集群时,设置仲裁者的配置如下

config = { _id:"mvbox", members:[
{_id:0,host:"192.168.1.1:27017"},
{_id:1,host:"192.168.1.2:27017",arbiterOnly:true},
{_id:2,host:"192.168.1.3:27017"}]
}

使用仲裁者主要是因为MongoDB副本集需要奇数成员,而又没有足够服务器的情况。在服务器充足的情况下,不应该使用仲裁者节点

 

8 .设置延迟复制节点(延迟节点)

MongoDB官方没有增量备份方案,只有一个导出的工具mongodump。
他不能像数据库一样,通过binlog或者归档日志将数据推到事故发生的前一刻。
假设每天凌晨2点使用mongodump备份,而下午5点发生事故,数据库损毁,则凌晨2点到下午5点的数据全部都会丢失。
虽然副本集可以一定程度避免这个问题,但是默认情况下不能避免人为的失误。
比如没有指定筛选条件删除了全部的数据。副本节点会应用这个命令,删除所有副本节点的数据。
在这个场景下,可以使用延迟节点,它会延迟应用复制。
如果主节点发生了人为的失误,而这个操作因为延迟的原因,还没有应用在延迟节点。
这个时候,修改延迟节点的优先级为最高级,使他成为新的Master服务器。

延迟节点的优先级必须为0.这个和hidden节点是一样的。
设置192.168.1.2为延迟节点

cfg=rs.conf();
cfg.members[1].priority=0
cfg.members[1].slaveDelay=3600
rs.reconfig(cfg);

slaveDelay的单位是秒
在192.168.1.1主节点删除一个集合所有数据,模拟人为失误。

db.users.remove({});

在192.168.1.3查看,发现数据已经全部丢失。

db.users.find();

而在192.168.1.2延迟节点,可以看到因为延迟复制的缘故,数据还在。

这个时候千万不要提升延迟节点的优先级。因为这样他会立即应用原主节点的所有操作,并成为新的主节点。这样误操作就同步到了延迟节点。
首先,关闭副本集中其他的成员,除了延迟节点。
删除其他成员数据目录中的所有数据。确保每个其他成员的数据目录都是空的(除了延迟节点)
重启其他成员,他们会自动从延迟节点中恢复数据(且并不改变之前的节点配置)。

9 .设置Secondary-Only节点

Priority为0的节点永远不能成为主节点,所以设置Secondary-only节点只需要将其priority设置为0.

10 .设置Non-Voting节点

假设设置192.168.1.1不能投票,则使用如下命令

cfg=rs.conf();
cfg.members[0].votes=0;
rs.reconfig(cfg);


11 .副本集成员状态

副本集成员状态指的是rs.status()的stateStr字段

复制代码
STARTUP:刚加入到复制集中,配置还未加载

STARTUP2:配置已加载完,初始化状态

RECOVERING:正在恢复,不适用读

ARBITER: 仲裁者

DOWN:节点不可到达

UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂

REMOVED:移除复制集

ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态

FATAL:出错。查看日志grep “replSet FATAL”找出错原因,重新做同步

PRIMARY:主节点

SECONDARY:备份节点
复制代码

 

12. 读写分离

如果Master节点读写压力过大,可以考虑读写分离的方案。


不过需要考虑一种场景,就是主服务器的写入压力非常的大,所以副本节点复制的写入压力同样很大。

这时副本节点如果读取压力也很大的话,根据MongoDB库级别读写锁的机制,
很可能复制写入程序拿不到写锁,从而导致副本节点与主节点有较大延迟。

如果进行读写分离,首先需要在副本节点声明其为slave,

db.getMongo().setSlaveOk();


其中的ReadRreference有几种设置:

primary:默认参数,只从主节点上进行读取操作;

primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。

secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。

secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据;

nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。

 

MongoDB客户端配置,可以提出来做成spring注入,设置最大连接数什么的。

MongoClientOptions options = MongoClientOptions.builder().maxWaitTime(1000 * 60 * 2) .connectionsPerHost(500).build(); mongoClient = new MongoClient(Arrays.asList(new ServerAddress("10.205.68.57", 8700),
new ServerAddress("10.205.68.15", 8700), 
new ServerAddress("10.205.69.13", 8700)), options); 
mongoClient.setReadPreference(ReadPreference.secondaryPreferred());

 13.mongodb慢查询的设置

开启慢日志
1.查看mongodb慢日志是否开起
 
use BJ_Rack;
 
db.getProfilingStatus();
 
发现没有开户慢日志
 
2.开启慢日志,设置超过200毫秒的操作为慢操作
 
db.setProfilingLevel(1);
db.setProfilingLevel(1,200); 超过200ms的才记录
0 不开启
1 记录慢查询
2 记录所有查询
db.getProfilingStatus()
 
 
 
3.查看慢日志内容
 
得到50个比较慢的操作日志.
db.system.profile.find().sort({$natural:-1})
 
 
#### 查看查询时间超过某个时间的
use local
db.system.profile.find({millis:{$gte:500}}).sort({"ts":-1}).limit(3)
 
 
#### 查询最慢的查询
db.system.profile.find().sort({"millis":-1}).limit(3)
 
 
通过配置文件开启:
operationProfiling:
   mode: slowOp
   slowOpThresholdMs: 100
 
 
查看当前操作
db.currentOp(true);
查看当前节点的连接情况
db.serverStatus().connections

 

 

 

  

posted on 2014-02-24 15:14  duanxz  阅读(961)  评论(0编辑  收藏  举报