MongoDB-复制、分片

MongoDB

  • 复制集Replication
    • 复制集主节点
    • 复制集从节点
      • 节点优先级为0的成员
      • 隐藏节点
      • 延迟节点
    • 仲裁节点
    • 部署复制集
  • 分片
    • 向集群中添加一个分片

复制集Replication

MongoDB中的副本集是一组维护相同数据集的mongod进程。 副本集提供冗余和高可用性,是所有生产部署的基础。 MongoDB复制是将数据同步在多个服务器的过程。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。复制还允许您从硬件故障和服务中断中恢复数据。
副本集包含多个数据承载节点和可选的一个仲裁节点。 在承载数据的节点中,一个且仅一个成员被视为节点,而其他节点被视为次要节点。
主节点接收所有写操作。 一个副本集只能有一个主要节点,其具有{ w: "majority" }write concern ; 虽然在某些情况下,另一个mongod实例可能会暂时认为自己也是主要的。主节点记录在其上的所有操作,即oplog。
复制结构图:MongoDB-复制、分片_第1张图片

复制集主节点

在复制集中,主节点是唯一能够接收写请求的节点。MongoDB在 主节点 上进行写操作,并会将这些操作记录到主节点的 oplog 中。 从节点 会将oplog复制到其本机并将这些操作应用到其自己的数据集上。
客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。复制集中任何成员都可以接收读请求。但是默认情况下,应用程序会直接连接到在主节点上进行读操作。
MongoDB-复制、分片_第2张图片
次要节点复制主节点的oplog并将操作应用于其数据集,以使次要节点的数据集反映主节点的数据集。如果主要节点不可用,则符合条件的次要节点会选出新的主节点。如果主节点未与该节点的其他成员通信超过配置的electionTimeoutMillis期间(默认为10秒),则符合条件的次要节点要求选举将自己指定为新主节点。 群集尝试完成新主节点的选举并恢复正常操作。
MongoDB-复制、分片_第3张图片

复制集从节点

节点优先级为0的成员

一旦将优先级设置为0,那么该从节点将不能升级为主节点 。 优先级为0 的成员不会触发选举 。除此之外该节点与其他从节点没有区别,优先级为0 的从节点拥有与主节点一致的数据集,能接受读请求,同时也能参与投票。通过将从节点的 优先级设置为0 来防止其升职为主节点可以在分布式数据中心的结构中起到很好的作用。
MongoDB-复制、分片_第4张图片
在很多情况下,我们可能不需要准备一个 优先级为0 的备用节点。然而在一些硬件环境或是架构的 地理分布 较为多变的情境中,一个 优先级为0 的备用节点可以很好的保证符合条件的成员升职为主节点。
一个拥有特殊硬件配置或是系统优化配置的 优先级为0 的备用节点也可以有效的为特殊需求提供服务。比如可以将 优先级设置为0 来让其不能升职为主节点。我们也可以考虑将该节点设置为 隐藏节点 。
如果我们的复制集中已经有了七个参与投票的节点,那么请将其他节点设置为 不参与投票

隐藏节点

隐藏成员维护了一个主数据集的副本,但对客户端应用程序不可见。隐藏成员适用于具有与副本集中其他成员不同的使用模式的工作负载。隐藏成员必须始终保持优先级为0,因此不能成为主要成员。db.isMaster()方法不显示隐藏的成员,然而隐藏的成员可以会在选举中投票
在下述这样拥有五个节点的复制集中,四个从节点都拥有与主节点一致的数据集,但其中的一个从节点是隐藏节点。

读操作:
客户端将不会把读请求分发到隐藏节点上,即使我们设定了 复制集读选项 。这些隐藏节点将不会收到来自应用程序的请求。我们可以将隐藏节点专用于报表节点或是备份节点。 延时节点 也应该是一个隐藏节点。在分片集群中, mongos 将不与隐藏节点进行交流。
投票:
在复制集的选举中,隐藏节点是会参加投票的。当关闭一个隐藏节点的时候,请确认复制集中的可用节点个数足够进行选举,以防主节点降职导致复制集对外不可用

延迟节点

延时节点也将从复制集中主节点复制数据,然而延时节点中的数据集将会比复制集中主节点的数据延后。举个例子,现在是09:52,如果延时节点延后了1小时,那么延时节点的数据集中将不会有08:52之后的操作。

由于延时节点的数据集是延时的,因此它可以帮助我们在人为误操作或是其他意外情况下恢复数据。举个例子,当应用升级失败,或是误操作删除了表和数据库时,我们可以通过延时节点进行数据恢复。
要求:

  • 延迟节点的优先级也必须为0,不能成为主节点;
  • 需要为隐藏节点,设置为应用程序不可见,也无法被其查询;
  • 也可以进行投票选举主节点,只要member[n].votes为1;

行为:
延迟成员在延迟时间后从源oplog复制和应用操作。 在选择延迟量时,请考虑延迟量:

  • 必须等于或大于预期的维护窗口持续时间;
  • 必须小于oplog的容量;

在分片集群中,当平衡器打开的时候延时节点效果有限。因为延时节点延时的复制数据段,而若在延时的时间段内进行过数据段迁移的话,复制集中的延时节点就无法为还原分片集群提供有效的帮助了。
配置实例:
members[n].slaveDelay 就是需要设置的延迟时间

{
   "_id" : ,
   "host" : ,
   "priority" : 0,
   "slaveDelay" : ,
   "hidden" : true
}

仲裁节点

可以将额外的mongod实例添加到副本集作为仲裁器。仲裁者不维护数据集。仲裁者的目的是通过响应其他副本集成员的心跳和选举请求来维护副本集中的仲裁。 因为它们不存储数据集,所以仲裁器是一个提供副本集仲裁功能的好方法,其资源成本比带有数据集的全功能副本集成员更低。如果您的副本集具有偶数个成员,请添加仲裁者以获得主要选举中的大多数投票。 仲裁者不需要专用硬件。
MongoDB-复制、分片_第5张图片
仲裁者将始终是仲裁者,而主节点可能会退出并成为次节点,而次节点可能被选举为主节点。

总结,副本集的特征:

  • N 个节点的集群
  • 任何节点可作为主节点
  • 所有写入操作都在主节点上
  • 自动故障转移
  • 自动恢复

部署复制集

在同一台机器上,

使用
mongod --replSet "replica"" 命令启动MongoDB

ulysses@ulysses:~$ mongod -f /etc/mongodb.conf --replSet 'rs0'
2018-12-05T09:32:36.879+0800 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
about to fork child process, waiting until server is ready for connections.
forked process: 11230
child process started successfully, parent exiting

打开MongoDB客户端使用rs.initiate()来启动一个新的副本集。

> rs.initiate()
{
	"info2" : "no configuration specified. Using a default configuration for the set",
	"me" : "localhost:27017",
	"ok" : 1,
	"operationTime" : Timestamp(1543889383, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1543889383, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
rs0:SECONDARY> 

使用rs.conf()来查看副本集的配置

{
	"_id" : "rs0",
	"version" : 1,
	"protocolVersion" : NumberLong(1),
	"writeConcernMajorityJournalDefault" : true,
	"members" : [
		{
			"_id" : 0,
			"host" : "localhost:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},

查看副本集状态使用 rs.status() 命令:

{
	"set" : "rs0",
	"date" : ISODate("2018-12-05T01:39:17.462Z"),
	"myState" : 1,
	"term" : NumberLong(2),
	"syncingTo" : "",
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {

使用rs.add() 方法添加其余成员,例如:

rs.add("mongodb1.example.net")
rs.add("mongodb2.example.net")

其他具体的复制集操作,看Replica Set Deployment Tutorials

分片

在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
具有大型数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量,解决系统增长的方法有两种:垂直和水平缩放。
垂直扩展涉及增加单个服务器的容量,例如使用更强大的CPU,添加更多RAM或增加存储空间量。
水平扩展涉及划分系统数据集并加载多个服务器,添加其他服务器以根据需要增加容量。MongoDB支持通过分片进行水平扩展。
MongoDB中使用分片集群结构分布:
MongoDB-复制、分片_第6张图片

  • Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障

  • Config Server: mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。

  • Query Routers: 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

向集群中添加一个分片

连接到一个 mongos 之后对集群进行操作:

使用mongo连接到一个mongos,比如,如果一个 mongos 运行在 mongos0.example.net 的 27017端口,使用以下命令进行连接:

mongo --host mongos0.example.net --port 27017

使用 sh.addShard() 方法向集群中添加分片. sh.addShard() 每次添加一个分片,如果要添加的分片是一个复制集,需要指定复制集的名字与至少一个成员.在生产环境中,所有分片都应该是复制集.
有一个运行在 mongodb0.example.net 的 27017 的mongod,它是名字为 rs1 的复制集的一个成员,要添加一个这样的分片,需要:

sh.addShard( "rs1/mongodb0.example.net:27017" )

要添加运行在 mongodb0.example.net 的 27017 端口的单机 mongod ,使用以下命令:

sh.addShard( "mongodb0.example.net:27017" )

你可能感兴趣的:(学习笔记)