复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并保证数据的安全性。

主从复制集群

主从复制只有 1 个主节点,至少有 1 个从节点,可以有多个从节点。它们的身份是在启 MongoDB数据库服务时就需要指定的。所有的从节点都会自动地去主节点获取最新数据,做到主从节点数据保持一致。注意主节点是不会去从节点上读取数据的,只会输出数据到从节点。理论上 1 个集群中可以有无数个从节点,但是这么多的从节点对主节点进行访问,主节点会受不了。《MongoDB 权威指南》中有说不超过 12 个从节点的集群就可以运作良好。
在这里插入图片描述
使用主从复制集群有一个比较明显的缺陷:当主节点出现故障,比如停电或者死机等情况发生时,整个 MongoDB 服务集群就不能正常运作了。需要人工地去处理这种情况,修复主节点之后再重启所有服务。当主节点一时难以修复时,我们也可以把其中 1 个从节点启动为主节点,在这个过程中就需要人工操作处理,而且需要停机操作,我们对外的服务会有一段空白时间,给网站和其他应用的用户造成影响,所以说主从复制集群的容灾并不算太好。

复制集集群

为了解决主从复制集群的容灾性的问题,复制集应运而生。复制集是具有自动故障恢复功能的主从集群。复制集是对主从复制的一种完善。它跟主从集群最明显的区别就是复制集没有固定的主节点,也就是主节点的身份不需要我们去指明,而是整个集群自己会选举出 1 个主节点,这个主节点不能正常工作时,又会另外选举出其他的节点作为主节点。复制集中总会有 1 个活跃节点(Primary)和 1 个或者多个备份节点 (Secondary)。这样就大大提 MongoDB 服务集群的容灾性。在足够多的节点情况下,即使一两个节点不工作了, MongoDB 服务集群仍能正常提供数据服务。
在这里插入图片描述
客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。复制集的整个流程都是自动化的,我们只需要为复制集指定有哪些服务器作为节点,驱动程序就会自动去连接服务器,在当前活跃节点出故障后,自动提升备份节点为活跃节点。如果停电死机或者故障的节点来电或者启动之后,只要服务器地址没改变,复制集会自动连接它作为备份节点。
在这里插入图片描述
Mongodb 3.0版本之后一个复制集集群中可设置50个成员,但最多只有7个投票成员(包括 primary)(建议选择奇数个节点),其余为非投票成员(Non-Voting Member)。 非投票成员是复制集中数据的备份副本,不参与投票,但可以被投票或转成为主节点。此时,主从复制集群不推荐使用。

工作原理

复制集中主要有三个角色:主节点(primary)、从节点(secondary)、仲裁者(非必需)。要组建复制集集群至少需要两个节点,主节点和从节点都是必需的,主节点负责接受客户端的请求写入数据等操作,从节点则负责复制主节点上的数据,也可以提供给客户端读取数据的服务。仲裁者则是辅助投票修复集群。
复制集要完成数据复制以及修复集群依赖于两个基础的机制: oplog (operation log,操作日志)和心跳 (heartbeat)。oplog 让数据的复制成为可能,而“心跳”则监控节点的健康情况并触发故障转移。

oplog操作日志

复制集中只有主节点会接受客户端的写入操作,也就是说从节点只要监控主节点的写入操作,并且能够模仿主节点的写入操作就能完成一样的数据新增和更新,这样就实现了主节点到从节点的数据的复制,而不需要经常去完整地遍历对比主节点的数据。那从节点是如何能够获取主节点做了哪些操作呢?就是通过主节点的 oplog。oplog 是 MongoDB 复制的关键。 oplog 是一个固定集合,位于每个复制节点的 local 数据库里,记录了所有对数据的变更操作。 与mysql中的binlog类似,oplog 只记录改变了数据的操作,例如更新数据或者插入数据,读取查询这些操作是不会存在 oplog 中的。新操作会自动替换旧的操作,类似循环队列,以保证 oplog 不会超过预设的大小, oplog 中的每个文档都代表主节点上执行的一个操作。默认的 oplog 大小会随着安装 MongoDB 服务的环境变化。在 64 位系统上, oplog 默认大小是空余磁盘空间的 5% oplog 的大小,这个值可以通过启动 MongoDB 服务时的参数来设置。oplog 集合的大小应根据 DB 规模及应用写入需求合理配置,配置得太大,会造成存储空间的浪费;配置得太小,可能造成 Secondary 的 init sync 一直无法成功。
因 oplog 的数据会不断增加,local.oplog.rs 被设置成为一个 capped 集合,当容量达到配置上限时,会将最旧的数据删除掉。另外考虑到 oplog 在 Secondary 上可能重复应用,oplog 必须具有幂等性,即重复应用也会得到相同的结果。
在复制集中,每次客户端向主节点写入数据,就会自动向主节点的 oplog 里添加一个文档,其中包含了足够的信息来重现这次写操作。一旦写操作文档被复制到某个从节点上,从节点就会执行重现这个写操作,然后从节点 oplog 也会保存一条关于写入的操作记录。主节点有哪些数据变动的操作,从节点也同步做出这样的操作,从而保证了数据同步的一致性。 每个 oplog 都有时间戳,所有从节点都使用这个时间戳来追踪它们最后执行的写入操作记录。

{
    "ts" : Timestamp(1446011584, 2),
    "h" : NumberLong("1687359108795812092"), 
    "v" : 2, 
    "op" : "i", 
    "ns" : "test.nosql", 
    "o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" :"100" } 
}

从节点是定时更新自己的,当某个从节点准备更新自己时,它会做三件事:

  • 首先,查看自己 oplog 里最后一条的时间戳;
  • 其次,查询主节点 oplog 里所有大于此时间戳的文档;
  • 最后,把那些文档应用到自己库里,并添加写操作文档到自己的 oplog 里。

从节点第一次启动时,会对主节点的数据进行一次完整的同步。同步时从节点会复制主节点上的每个库和文档(除了 local 数据库)。 同步完成之后,从节点就会开始查询主节点的 log 并执行里面记录的操作。
具体来说,Secondary 初次同步数据时,会先进行 init sync,从 Primary(或其他数据更新的 Secondary)同步全量数据,然后不断通过 tailable cursor 从 Primary 的 local.oplog.rs 集合里查询最新的 oplog并应用到自身。其中,init sync 过程包含如下步骤:
1、T1 时间,从 Primary 同步所有数据库的数据(local 除外),通过 listDatabases + listCollections + cloneCollection 命令组合完成,假设 T2 时完成所有操作。
2、从 Primary 应用[T1-T2]时间段内的所有 oplog,可能部分操作已经包含在步骤 1,由于 oplog的幂等性,可重复应用。
3、根据 Primary 各集合的 index 设置,在 Secondary 上为相应集合创建 index。(每个集合_id 的index 已在步骤 1 中完成)。
除了 oplog 操作记录之外,主从节点还会存放复制状态。记录下主从节点交互连接的状态,记录同步参数时间戳和选举情况等。主从节点都会检查这些复制状态,以确保从节点能跟上主节点的数据更新。
复制状态的文档记录在本地数据库 local 中。 主节点的 local 数据库的内容是不会被从节点复制的。如果有不想被从节点复制的文档,可以将它放在本地数据库 local 中。

阻塞复制

从节点复制主节点的 oplog 并且执行它,对主节点来说是异步的,也就是主节点不需要等到从节点执行完同样的操作就可以继续下一个写入操作了。然而,当写入操作太快时,从节点的更新状态就有可能跟不上。如果从节点的操作己经被主节点落下很远, oplog 日志在从节点还没执行完, oplog 可能已经轮滚一圈了,从节点跟不上同步,复制就会停下,从节点需要新做完整的同步。为了避免此种情况,尽量保证主节点的 oplog 足够大,能够存放相当长时间的操作记录。
还有一种方法就是暂时阻塞主节点的操作,以确保从节点能够跟上主节点的数据更新,
这种方式叫阻塞复制。阻塞复制是在主节点使用 getLastError 命令加参数"w"来确保
数据的同步性。比如我们把"w"参数设置为 10,运行 getLastError 命令后,主节点
会进入阻塞状态,直到 N-1 个从节点复制了最新的写入操作为止。阻塞复制会导致写操作明显变慢,尤其是"w"的值比较大时。实际上,对于重要操作,将其值为 2 或者 3 就能做到效率和安全兼备了。

心跳机制

复制集的心跳检测有助于发现故障进行自动选举和故障转移。默认情况下,每个复制集成员之间都会有心跳检测机制,每隔 2s发一次心跳包, ping 一次其他所有成员。这样一来,系统可以弄清自己的健康状况。如果10s(5 次心跳时间)未收到某个节点的心跳,则认为该节点已宕机。如果宕机的节点为Primary,Secondary(前提是可被选为 Primary)会发起新的 Primary 选举。
在这里插入图片描述
只要每个节点都保持健康且有应答,说明复制集就很正常,没有故障发生。如果哪个点失去了响应,复制集就会采取相应的措施了。这时候复制集会去判断失去响应的是主节点还是从节点。

  • 如果是多个从节点中的某一个从节点,则复制集不做任何处理,只是等待从节点重新上线。
  • 如果是主节点挂掉了,则复制集就会开始进行选举了,选出新的主节点。

还有一种场景是复制集集群的主节点突然失去了其他大多数节点的心跳,主节点会把自己降级为从节点。这是为了防止网络原因让主节点和其他从节点断开时,其他的从节点中推举出了一个新的主节点,而原来的主节点又没降级的话,当网络恢复之后,复制集就出来了两个主节点。如果客户端继续运行,就会对两个主节点都进行读写操作,肯定复制集就混乱了。所以,当主节点失去多数节点的心跳时(自己不够半数),必须降级为从节点。
假设复制集内投票成员数量为 N,则大多数定义为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出 Primary,复制集将无法提供写服务,处于只读状态。

选举机制

如果主节点故障了,其余的节点就会选出一个新的主节点。选举可以由任意非主节点发起,然后根据优先级和 Bully 算法(核心就是评判谁的数据更新)选举出主节点。在选举出主节点之前,整个集群服务是只读的,不能执行写入操作。
非仲裁节点都有个优先级的配置,范围为 0~100 ,越大的值越优先成为主节点。默认情况下 1,如果是0,则不能成为主节点。选举机制会尽最大的努力让优先级最高的节点成为主节点 ,即使复制集中已经选举出了比较稳定的、但优先级比较低的主节点。优先级比较低的节点会短暂地作为主节点运行一段时间,但不能一直作为主节点。也就是说,如果优先级比较高的节点在 Bully 算法投票中没有胜出,复制集运行一段时间后会继续发起选举,直到优先级最高的节点成为主节点为止。由此可见,优先级的配置参数在选举机制中是很重要的,要么不设置,保持大家都是优先级 1 的公平状态,要么把可以把性能比较好的几台服务器设置的优先级高一些。这个可以根据实际的业务场景需求。

数据回滚

不论哪一个从节点升级为主节点,新的主节点的数据都认定为 MongoDB 服务复制集
的最新数据,对其他节点(特别是原来的主节点)的操作都会回滚,即使之前故障的主节点恢复工作作为从节点加入集群之后。为了完成回滚,所有节点连接新的主节点后要重新同步。这些节点会查看自己的 oplog,找出其中新主节点中没有执行过的操作,然后向新主节点请求这些操作影响的文档的数据样本,替换掉自己的异常样本。正在执行重新同步的、之前故障的主节点被视为恢复中,在完成这个过程之前不能作为主节点的候选者。

特殊节点

除了主从节点外,mongodb还有一些特殊作用的节点。

仲裁节点Arbiter

Arbiter 节点只参与投票,不能被选为 Primary,并且不从 Primary 同步数据。 比如你部署了一个 2 个节点的复制集,1 个 Primary,1 个 Secondary,任意节点宕机,复制集将不能提供服务了(无法选出 Primary),这时可以给复制集添加一个 Arbiter 节点,即使有节点宕机,仍能选出 Primary。
Arbiter 本身不存储数据,是非常轻量级的服务,当复制集成员为偶数时,最好加入一
个 Arbiter 节点,以提升复制集可用性(提高投票的选举效率)。

Priority0节点

将节点的优先级Priority设为0,代表不会被选举为 Primary。
比如跨机房 A、B 部署了一个复制集,并且想指定 Primary 必须在 A 机房,这时可以将 B 机房的复制集成员 Priority 设置为 0,这样 Primary 就一定会是 A 机房的成员。(注意:如果这样部署,最好将大多数节点部署在 A 机房,否则网络分区时可能无法选出 Primary)

Vote0 节点

在Mongodb 3.0 里,复制集成员最多 50 个,参与 Primary 选举投票的成员最多 7 个,其他成员的 vote 属性必须设置为 0,即不参与投票。

Hidden节点

Hidden 节点不能被选为主(Priority 为 0),并且对 Driver 不可见。 因 Hidden 节点不会接受 Driver 的请求,可使用 Hidden 节点做一些数据备份、离线计算的任务,不会影响复制集的服务。

Delayed 节点

Delayed 节点必须是 Hidden 节点,并且其数据落后与 Primary 一段时间(可配置,比如1 个小时)。 因 Delayed 节点的数据比 Primary 落后一段时间,当错误或者无效的数据写入 Primary 时,可通过 Delayed 节点的数据来恢复到之前的时间点。

搭建操作

准备工作

1、相应实例的配置
和之前单机配置一样,需要配置数据目录、配置文件等。注意如果是在单机上配置集群,需要配置不同的端口、dbpath和logpath。

systemLog:
    destination: file
    path: /home/lqf/data/db1/mongod.log # log path 
    logAppend: true
storage:
    dbPath: /home/lqf/data/db1 # data directory 
net:
    bindIp: 0.0.0.0 
    port: 28017 # port
replication: 
    replSetName: rs0
processManagement: 
    fork: true

这里如果启动时报错

error parsing YAML config file: yaml-cpp: error at line 2, column 13: illegal map value

说明.conf文件对齐出了问题,要用空格进行对齐,不是使用 table进行缩进。
2、配置复制集
有两个方法

# 在命令行中
mongo --port 28017
> rs.initiate()
> rs.add(“HOSTNAME:28018")
> rs.add(“HOSTNAME:28019")

注意:此方式 hostname 需要能被解析,使用 hostname -f 命令查看实际的 HOSTNAME。
此方式只是适合单机模拟复制集。
第二个方法

# 在命令行中
mongo --port 28017
> rs.initiate({
# ...表示命令还没写完,mongodb还在等待继续输入
... _id: "rs0", 
... members: [{
... _id: 0,
... host: "localhost:28017"
... },{
... _id: 1,
... host: "localhost:28018"
... },{
... _id: 2,
... host: "localhost:28019"
... }]})
# 返回的结果
{ "ok" : 1 }
# 出现下面的字样说明进入复制集模式了
rs0:SECONDARY>

进入复制集模式,可以使用rs.status()查看集群的状态。
3、对复制集进行操作
所有节点使用 test 数据库,测试的时候都先用 use test切换数据库。
mongodb默认是从主节点读写数据的,从节点上不允许读。设置读写分离需要先在从节点 SECONDARY 设置rs.secondaryOk()rs.slaveOk()

复制集常用命令

1、查看复制情况
从库都有哪些,以及每台从库与主库的同步时间差

db.printSecondaryReplicationInfo()

2、查看复制集状态
刚才有过介绍,功能是查看复制集拓扑、及运行情况

rs.status()

3、查看复制集配置
查看各节点的详细配置情况

rs.config()
# 或
rs.conf()

4、增加节点

rs.add(HOST_NAME:PORT)

在MongoDB 中你只能通过主节点将 Mongo 服务添加到复制集中, 判断当前运行的 Mongo 服务是否为主节点可以使用命令db.isMaster()
5、删除节点

rs.remove("10.1.8.69:27018")

6、主节点退位

rs.stepDown()

退位后让出主节点,该节点变为从节点。
7、节点不建立索引
不建立索引的节点不能成为主节点(所以 priority 必须为 0)。适用范围:性能较低服务器或者只用于备份或离线任务处理的机器可以配置。

rs.add({"host":"10.1.8.69:27018","priority":0,"buildIndexes":false})

修改节点的集群配置

某些配置生效后需要更改则必须先移除该节点、删除所有数据、再重新加入才可以。并且不建立索引的节点不能成为主节点(所以 priority 必须为 0)。操作步骤:
1、rs.remove(“10.1.8.69:27018”)
2、登录被移除的节点上
3、关闭该节点

use admin
db.shutdownServer()

4、移除该节点数据目录下的所有数据

rm MONGODB_DATA_DIR/*

5、重新启动该节点
6、重新向集群中添加该节点

rs.add({"host":"HOSTNAME:PORT"})

配置隐藏节点或者备份节点

配置隐藏节点或者备份节点:对 driver 不可见,适用范围:性能较低的机器或者仅用于备份及批量处理的机器。一般这样的机器不适合做主节点(会配置其优先级为 0)。需要在主节点配置

cfg=rs.conf()
cfg.members[1].hidden=true
cfg.members[1].priority=0
rs.reconfig(cfg)
rs.conf()

或者也可以用添加的方式进行配置备份节点或者隐藏节点

rs.add({"_id":2,"host":"192.168.199.1:27019","priority":0,"hidden":true})

配置优先级

一般在主节点进行配置(优先级配置范围 0-100),优先级较高并且数据是最新的节点会变成主节点。对于优先级都为 0 的复制集不可以执行 reconfig

cfg=rs.conf()
cfg.members[1].priority=3
rs.reconfig(cfg)
rs.conf() ##查看配置是否生效

更改成员 host

更改成员 host,更换了 IP 的,或者用于替换某个成员。被添加的成员要启动时指定 replSet 选项,或者在配置文件中配置。

cfg=rs.conf()
cfg.members[2].host="10.1.8.69:27018"
rs.reconfig(cfg)
rs.conf() ##查看配置是否生效

某台机器暂时退出

登录主节点并移除要维护的节点

rs.remove("10.1.8.69:27019")

该节点重新启动后自动加入复制集。可以用于该节点的维护或修改端口等操作。

阻止选举

需要对主节点进行维护时,又不希望其它节点进行选举,可以在所有其他节点执行下方命令,将会阻止该节点选举成为主节点。

rs.freeze(10000)  # 禁止 10000 秒该节点进行主节点选举
rs.freeze(0)  # 恢复其它节点的被选举权利,或者让退位的主节点恢复

分片集群

在 Mongodb 里面存在另一种集群,就是分片技术,可以满足 MongoDB 数据量大量增长的需求。这类似于mysql中的分库分表。当 MongoDB 存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
分片集群可以有效解决性能瓶颈及系统扩容问题,但是分片额外消耗较多,管理复杂,能不分片尽量不要分。

基本组成

在这里插入图片描述
上图中主要有如下所述三个主要组件:
1、Shard:用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组成,防止主机单点故障,可以理解为,一个分片就是一个复制集集群。
2、Config Server:mongod 实例,存储了整个 ClusterMetadata,其中包括 chunk 信息。
3、mongos:Query Routers前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

分片方式

MongoDB原生支持了自动分片。分片是 MongoDB 数据库的核心内容,数据分流是实现分片的很重要的部分,MongoDB 内置了几种数据分流存放的策略,目前有:哈希分片、区间分片和标签分片三种策略。

区间分片

范围分片是根据片键的值的区域来把数据划分成数据块的,这也是早期 MongoDB 分片的策略。因为在 MongoDB 中数据类型之间是有严格的次序的,所以 MongoDB 能够对片键的值进行一个排序。
类型的先后次序如下:null<数字<字符串<对象<数组<二进制数据<objectld<布尔值<日期<正则表达式。
同类型也可以进行排序,而且同类型的排序与我们熟悉和期望的排序可能相同,比如:数字类型 5<6 ,或者字符串类型“a”<“b”。
在排序的基础上, MongoDB 就能获取到片键的最大值和最小值了,然后 MongoDB 会根据目前己有的片键和目前有多少台服务器参与分片来进行数据分配。
比如:
在这里插入图片描述
区间分片的优点:片键范围查询性能好,优化了读操作。
缺点:数据分布可能不均匀,容易有热点 (比如自增 ID)。

哈希分片

哈希分片仍然是基于区间分片,只是将提供的片键散列成一个非常大的长整型作为最终的片键。当我们选定片键之后, MongoDB 会自动将片键进行散列计算之后再进行区间的划分。普通的区间分片可以支持复合片键,但是哈希分片只支持单个字段作为片键。
哈希分片最大的好处就是保证数据在各个节点分布基本均匀。 我们来对比一下基于区间分片和哈希分片有什么不同。区间分片方式提供了更高效的范围查询,给定一个片键的范围,分发路由可以很简单地确定哪个数据块存储了请求需要的数据,并将请求转发到相应的分片中,不需要请求所有的分片服务器。不过,区间分片会导致数据在不同分片上的不均衡,有时候,带来的消极作用会大于查询性能的积极作用。比如,如果片键所在的字段是线性增长的,例如数字型自增 id 或者时间戳, 一定时间内的所有请求都会落到某个固定的数据块中,最终导致分布在同一个分片中。在这种情况下,小部分分片服务器承载了集群大部分的数据,系统并不能很好地进行扩展。
哈希分片方式则是以查询性能的损失为代价,保证了集群中数据的均衡。哈希值的随机性使数据随机分布在每个数据块中,因此也随机分布在不同分片中。但是也正由于随机性,一个范围查询很难确定应该请求哪些分片,通常为了返回需要的结果,需要请求所有的分片服务器。 哈希分片如图所示。
在这里插入图片描述
需要注意的是 MongoDB 的哈希片键散列化计算会将浮点数截断为 64 位整数,比如 2.3 2.2 2.9,散列化计算后会得到相同的值,为了避免这一点产生,不要在哈希索引中使用不能可靠地转化为 64 位整数的浮点数。MongoDB 的哈希分片片键不支持大于 253 的浮点数。

标签分片

MongoDB 可以手工设置数据保存在哪个分片节点服务器上,这非常有用,主要就是通过标签分片策略来实现的。此特性支持人为控制数据的分片方式,从而使数据存储到合适的分片节点上。具体的做法是通过对分片节点打 tag 标识,再将片键按范围对应到这些标识上。
例子如下:我们有三个分片节点,定义了两个 tag 标识, A 的 tag 标识表示片键 x 的区间 1~10, B 的 tag 标识表示片键 x 的区间是 11~20 。然后把节点 Alpha 和Beta 都打上 A 标签,节点 Beta 打上 B 标签。最后有数据要写入 MongoDB 数据库时,我们可以看到片键 1~10 范围内的文档数据只会分配到带有 A 标签的节点,也就是 Alpha 或者 Beta ;片键 10~20 范围内的文档数据只会分配到带有 B 标签的节点上,也就是 Beta ,而如果 x 片键的值没有被包含在已有的 tag 的范围内,那么它就可能任意分配到任意分片节点中 。标签分片如下所示。
在这里插入图片描述

搭建实例

先给出要搭建实例的结构分布,方便有一个整体的印象。

Shard Server 0:27020
Shard Server 1:27021
Shard Server 2:27022
Shard Server 3:27023
Config Server :27100
Route Process:40000

1、启动各分片
注意先创建各个实例的数据目录和日志目录。

mkdir -p /www/mongoDB/shard/s0
mkdir -p /www/mongoDB/shard/s1
mkdir -p /www/mongoDB/shard/s2
mkdir -p /www/mongoDB/shard/s3
mkdir -p /www/mongoDB/shard/log

启动各个实例

/usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27021 --dbpath=/www/mongoDB/shard/s1 --logpath=/www/mongoDB/shard/log/s1.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27022 --dbpath=/www/mongoDB/shard/s2 --logpath=/www/mongoDB/shard/log/s2.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27023 --dbpath=/www/mongoDB/shard/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork

也可以用配置文件的方式。

2、启动 Config Server

mkdir -p /www/mongoDB/shard/config
/usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork

注意:这里我们完全可以像启动普通 mongodb 服务一样启动,不需要添加—shardsvr 和 configsvr 参数。因为这两个参数的作用就是改变启动端口的,所以我们自行指定了端口就可以。
3、启动 Route Process

/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500

mongos 启动参数中,chunkSize 这一项是用来指定 chunk 的大小的,单位是 MB,默认大小为 200MB。
4、配置 Sharding
接下来,我们使用 MongoDB Shell 登录到 mongos,添加 Shard 节点

/usr/local/mongoDB/bin/mongo admin --port 40000
mongos> db.runCommand({ addshard:"localhost:27020" })
# 返回结果
{ "shardAdded" : "shard0000", "ok" : 1 }
# 以此类推
......
mongos> db.runCommand({ addshard:"localhost:27023" })
{ "shardAdded" : "shard0003", "ok" : 1 }

mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库
{ "ok" : 1 }
mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
{ "collectionsharded" : "test.log", "ok" : 1 }

mongodb备份与恢复

mongodb中有多种方式进行数据的备份与恢复,这里介绍mongodump的方式。

数据备份

在 Mongodb 中我们使用 mongodump 命令来备份 MongoDB 数据。该命令可以导出所有数据到指定目录中。mongodump 命令可以通过参数指定导出的数据量级转存的服务器。
注意mongodump需要另外下载,现在的版本已不包含在mongodb中。还是注意要选择和自己系统对应的版本,与下载mongodb步骤类似,这里不再过多介绍。

wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2004-x86_64-100.5.3.tgz

mongodump 命令脚本语法如下:

mongodump -h dbhost -d dbname -o dbdirectory

解释一下各个参数
-h:MongDB 所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:需要备份的数据库实例,例如:test
-o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump 目录下建立一个 test 目录,这个目录里面存放该数据库实例的备份数据。
–collection COLLECTION --db DB_NAME:备份指定数据库的指定集合。
可以缺省参数,直接使用mongodump命令,这表示在本地使用 27017 端口启动mongod b,并备份所有数据到 bin/dump/ 目录中。

数据恢复

mongodb 使用 mongorestore 命令来恢复备份的数据。mongorestore 命令脚本语法如下:

mongorestore -h <hostname><:port> -d dbname <path>

解释参数
–host <:port>, -h <:port>:MongoDB 所在服务器地址,默认为: localhost:27017
–db , -d :需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如 test2
–drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用!
:mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。你不能同时指定 和 --dir 选项,–dir 也可以设置备份目录。
–dir:指定备份的目录

MongoDB 监控

在已经安装部署并允许 MongoDB 服务后,需要了解 MongoDB 的运行情况并查看 MongoDB的性能。这样在大流量得情况下可以很好的应对并保证 MongoDB 正常运作。MongoDB 中提供了mongostat 和 mongotop 两个命令来监控 MongoDB 的运行情况。

mongostat命令

mongostat 是 mongodb 自带的状态检测工具,在shell命令行下使用。它会间隔固定时间获取 mongodb 的当前运行状态并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用 mongostat 来查看 mongo 的状态。
启动 Mongod 服务,进入到安装的 MongoDB 目录下的 bin 目录, 然后输入 mongostat 命令,就可以得到返回的相应结果。

mongotop命令

mongotop 也是 mongodb 下的一个内置工具,mongotop 提供了一个方法,用来跟踪一个 MongoDB的实例,查看哪些大量的时间花费在读取和写入数据。mongotop 提供每个集合的水平的统计数据。默认情况下,mongotop 返回值的每一秒。
启动Mongod 服务,进入到安装的 MongoDB 目录下的 bin 目录, 然后输入 mongotop 命令,就可以得到返回的相应结果。

mongotop <sleeptime>

sleeptime参数可以不使用,这是等待的时间长度,以秒为单位,mongotop 等待调用时
间。默认 mongotop 每秒返回一次结果。还可以加上–lock参数,报告每个数据库的锁的使用情况。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐