本文转载于运维生存时间http://www.ttlsa.com/html/1096.html
mongodb集群:复制,复制集和分片。 强烈建议在生产环境中使用mongodb的复制功能。复制具有故障切换,读扩展,热备份和离线批处理操作。
默认情况下,主节点负责客户端所有的读写请求,从节点不可读不可写。
一. 工作原理
1. mongodb的复制至少需要两个实例。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
2. 主节点的操作记录称为oplog(operation log),存储在local数据库中(local数据库不会被复制,用来存放复制状态信息的)。oplog中的每个文档代表着主节点上执行的操作。oplog只作为从节点与主节点保持数据同步的机制。
3. oplog.rs是一个固定长度的capped collection。默认情况下,64位的实例将使用oplog 5%的可用空间,这个空间将在local数据库中分配,并在服务器启动时预先分配。
4. 如果从节点落后主节点很远了,oplog日志从节点还没执行完,oplog可能已经轮滚一圈了,那么从节点将会追赶不上主节点了,复制将会停止。从节点需要重新做完整的同步,可以用{resync:1}命令来手动执行重新同步或在启动从节点时指定–autoresync选项让其自动重新同步。重新同步的代价昂贵,应尽量避免,避免的方法就是配置足够大的oplog。
查看oplog信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
> db.oplog.rs.stats()
{
"ns"
:
"local.oplog.rs"
,
"count"
:
7276573
,
"size"
:
1980730564
,
"avgObjSize"
:
272.20651314842854
,
"storageSize"
:
2097156096
,
"numExtents"
:
1
,
"nindexes"
:
0
,
"lastExtentSize"
:
2097156096
,
"paddingFactor"
:
1
,
"systemFlags"
:
0
,
"userFlags"
:
0
,
"totalIndexSize"
:
0
,
"indexSizes"
: {
},
"capped"
:
true
,
"max"
:
2147483647
,
"ok"
:
1
}
|
查看oplog.rs内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
> db.oplog.rs.find().limit(
1
).toArray()
[
{
"ts"
: Timestamp(
1357529944000
,
1
),
"h"
: NumberLong(
"-3237467944396345731"
),
"v"
:
2
,
"op"
:
"i"
,
"ns"
:
"ttlsa_event.ttlsa_events"
,
"o"
: {
"_id"
: ObjectId(
"50ea43599ca66a2d7e000000"
),
"aid"
:
110000
,
"kid"
:
10007
,
"tag"
:
"Mobile"
,
"uid"
:
368514901
,
"stmp"
:
1357529945
,
"born"
:
1357529945
,
"total"
:
1
,
"val"
: [
{
"nickname"
:
"m44332148"
,
"productid"
:
109350
,
"product"
:
"三国时代OL"
,
"stmp"
:
1357529945
}
]
}
}
]
|
字段说明:
ts:操作的时间戳,用于跟踪操作执行的时间。
op:操作类型,i代表插入,u代表更新,d代表delete
ns:执行操作的集合名
o: 文档内容
二. 复制
mongodb支持传统的master-slave架构。没有自动故障转移功能,需要指定master和slave端。强烈推荐使用复制集架构,复制集架构比复制架构更好维护,功能更强。
master-slave架构一般使用于下面两种情况:
1. slave超过11个
2. 需要复制单一的数据库
master-salve架构配置:
// master server启动master,只需指定master参数
1
|
# mongod --master
|
// slave server启动slave,需要指定slave参数和master的IP和端口
1
|
# mongod --slave --source master_server:
27017
|
主从复制的选项有:
1. –only 在slave节点上指定只复制的数据库
2. –slavedelay 指定slave节点延时多少秒同步master
3. –fastsync 以master节点的数据快照为基础启动slave节点
4. –autoresync 如果slave节点不同步了,则主动重新同步
5. –oplogSize master节点oplog大小
三. 复制集
复制集最少需要三台服务器或两台服务器+仲裁一台。
复制集的配置参见:http://www.ttlsa.com/html/1093.html
查看master 的oplog元数据信息:
1
2
3
4
5
6
|
> db.printReplicationInfo()
configured oplog size: 2000MB
log length start to end: 16685504secs (
4634
.86hrs)
oplog first event time: Mon Jan
07
2013
11
:
42
:
50
GMT+
0800
(CST)
oplog last event time: Fri Jul
19
2013
14
:
34
:
34
GMT+
0800
(CST)
now: Fri Jul
19
2013
14
:
34
:
38
GMT+
0800
(CST)
|
字段说明:
configured oplog size: oplog文件大小
log length start to end: oplog日志的启用时间段
oplog first event time: 第一个事务日志的产生时间
oplog last event time: 最后一个事务日志的产生时间
now: 现在的时间
查看slave的同步状态:
1
2
3
4
5
6
|
> db.printSlaveReplicationInfo()
source:
10.1
.
11.157
:
27017
no replication info, yet. State: ARBITER
source:
10.1
.
11.156
:
27017
syncedTo: Fri Jul
19
2013
14
:
34
:
42
GMT+
0800
(CST)
=
2
secs ago (0hrs)
|
字段说明:
source:从库的IP以及端口
syncedTo:当前的同步情况
增加节点:
1
|
ttlsa:PRIMARY> rs.add(
"10.1.11.111:27017"
)
|
减少节点:
1
|
ttlsa:PRIMARY> rs.remove(
"10.1.11.111:27017"
)
|
允许从库读操作:
1
|
ttlsa:SECONDARY> db.getMongo().setSlaveOK()
|
手动转移primary:
1
2
|
ttlsa:SECONDARY> rs.freeze([secs])
//make a node ineligible to become primary for the time specified
ttlsa:PRIMARY> rs.stepDown([secs])
//step down as primary (momentarily) (disconnects)
|
复制集状态:
1. STARTUP:刚加入到复制集中,配置还未加载
2. STARTUP2:配置已加载完,初始化状态
3. RECOVERING:正在恢复,不适用读
4. ARBITER: 仲裁者
5. DOWN:节点不可到达
6. UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂
7. REMOVED:移除复制集
8. ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
9. FATAL:出错。查看日志grep “replSet FATAL”找出错原因,重新做同步
10. PRIMARY:主节点
11. SECONDARY:备份节点
四. 复制认证
如果启用了认证,需要在主节点和从节点上的local数据库下,建个相同的用户名和密码的用户,可读写。 从节点连接主节点时,会用存储在local.system.users中的用户进行认证,最先尝试用repl用户,若没有,则用local.system.users中的第一个可用用户。
1
2
|
>
use
local
> db.addUser(
"repl"
,
"password"
)
|
五. 分片
分片下一节说。