MongoDB副本集与与分片

副本集

一.概述

MongoDB中的副本集是一组维护相同数据集的mongod服务。副本集由一个主节点和多个副本节点组成。主节点将数据的改变推送到副本节点上,在一定的延迟之后,每个MongoDB实例维护相同的数据。能够实现数据冗余,读写分离和自动故障转移。

MongoDB副本集可以用于对数据冗余备份,防止某台或某部分机器故障数据丢失,可以使用副本集进行数据恢复。副本集由一个主节点和多个副节点组成,可以实现读写分离,主节点仅负责写工作,副节点负责读工作,可以减轻主节点的压力,同时又有多个副节点提供读服务,实现负载均衡。且任意副节点宕机后也对整个服务不会产生毁灭性的影响。再配合自动故障转移,当主节点宕机后,再从副节点中选举一个新的主节点,实现整个服务的高可用性。

二、副本集角色

副本集有两种类型三种角色

1.两种类型

  • 主节点类型:数据操作的主要连接点,可读写,但一般只进行写操作。
  • 次要节点类型:数据冗余备份,提供读能力。或用于主节点掉线选举。

2.三种角色

  • 主要成员:主要接收所有写操作,即主节点
  • 副本成员:从节点通过复制操作以维护同主节点相同的数据库,只提供读服务。
  • 仲裁成员:不存储数据副本,不提供读写服务,仅用于主要成员掉线后选举新的主要成员。

3.仲裁成员

在副本集中仲裁成员可以用于选举新的主要成员,事实上不使用仲裁成员,其他成员也都拥有重新选举新成员的能力。但也不是说仲裁成员毫无作用,当选举新主要成员是,票数一致若无仲裁成员,整个选举环节可能会卡在投票环节,仲裁成员可以用于解决这种问题。我们也可以不部署仲裁成员部署奇数个其他成员,但保不齐掉线几个变为偶数。最后仲裁成员的性价比很高,它不提供数据备份的功能,因此系统资源占用很少。

三、副本集操作

1.搭建

本地搭建副本集,配置3份配置文件,port分布配置27017(主节点),27018(从节点),27019(仲裁节点)。都给3份配置文件设置上副本集名,如:

然后分别用这3份配置文件启动3个mongodb服务,并使用mongosh指令连接27017端口的mongodb服务。主节点执行如下指令

从节点和仲裁节点执行如下指令

2.副本集读写

主节点写入

从节点读取

四、故障说明

1.从节点故障

不受影响,从节点恢复后同步数据。

2.主节点故障

从节点被选举为主节点,主节点恢复后变为从节点,同步数据。

3.仲裁节点 & 主节点故障

从节点无法选举为主节点,因为网络中不存在大多数节点。仲裁节点和主节点故障恢复后,触发重新选举。

4.仲裁节点 & 从节点故障

主节点降级为从节点,因为主节点无法得知是其他节点掉线了还是自己掉线,万一其他节点没有掉线会重新选举一个主节点,就会出现双主节点的情况,这种情况下若主节点所在网络不存在大多数节点会自动降级为从节点。当从节点和仲裁节点恢复,触发重新选举。

五、主节点选举

下面对选举简单介绍,如需要深入了解,自行查找资料。

1.选举条件

假设X是一个从节点,那么X会定时检测是否需要选举自己成为主节点。其检测内容包括:

  • 是否集群中有其它节点认为自己是主节点?
  • X节点自己是否有资格成为主节点?

只有当X节点是一个能够当主节点的从节点,并且其它节点都不是主节点时,X才会发起选举并选自己为主节点。

2.选举因素

  • Replication Election Protocol(复制选举协议,选择从3.2开始支持protocolVersion: 1)
  • 优先级(先看优先级,级别越高,优先为主,priority=0:表示不参与选举、不能成为主
  • optime (如果优先级都相同,则有最新的 optime 的成为主)
  • 心跳 (副本级中的每个member默认都是每2秒ping 其他节点,protocolVersion:0如果超过{"heartbeatTimeoutSecs" : 10} 默认是10秒 或者 protocolVersion:1时 electionTimeoutMillis 默认是10秒没有回应,则标记节点不可达s_down,类似Redis sentinel主观下线)

3.选举时机 & 规则

时机

  • 初始化副本集
  • 主节点故障
  • 主节点网络不可达
  • 人工干预,主节点降为从节点(rs.stepDown(600))

规则

当副本集内投票成员数量为N,则大多数为(N/2)+1,当副本集内存活成员数量不足大多数时(网络分裂),整个副本集将无法选举出主节点,副本集将无法提供写服务,处于只读状态。

可以进行选举的副本集,当某个节点没有节点投反对票,且获得赞成票数超过有权投票节点总数的1/2,则能成为主节点。否则进入下一轮选举。

网络分裂

将整个副本集看成一个网络,发生故障副本集被分为一块块相互无法连接的网络即为网络分裂。如果主节点不在大多数的那一块网络中,主节点会变成从节点,多数节点(互相能通信)的那组选举新的主节点。

例外情况:如发生网络分裂,被分裂的一组选举出一个新的Primary,老的Primary还没降级,这就出现了2个Primary,这就是脑裂现象。此时2个Primary都有写入,直到网络恢复后,若老主再次成为Primary,则脑裂过程中选举出的新Primary会回滚脑裂过程新写入的数据;若老主成为Secondary,则回滚老主脑裂过程新写入的数据。

六、oplog

下面对oplog简单介绍,如需要深入了解,自行查找资料。

1.简介

oplog是local库下的一个固定集合,从节点就是通过查看主节点 的oplog这个集合来进行复制的。每个节点都有oplog,记录这从主节点复制过来的信息,这样每个成员都可以作为同步源给其他节点。oplog记录着主节点上面的操作记录。

为了提高效率,从节点可以不从主节点获取oplog信息,也可以从其他从节点获取最新的oplog。

2.副本集数据同步过程

主节点写入数据,从节点通过读取主节点的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。

如果某个操作失败(只有当同步源的数据损坏或者数据与主节点不一致时才可能发生),则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog。

由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。

七、安全认证

若mongodb开启了安全认证,数据库间的连接也是需要安全认证的,执行以下流程

Mongodb分片概括

  • 分片在多台服务器上分布数据的方法, Mongodb使用分片来支持具有非常大的数据集和高吞吐量的操作的部署

  • 具有大数据集和高吞吐量应用程序的数据库系统,可以挑战单台服务器的容量。
    例如,高查询率可以耗尽服务器的cpu容量,工作集大小大于系统的RAM强制磁盘驱动器的I/O容量,

  • 有两种方法来解决系统增长:垂直和水平缩放。

    • 垂直缩放 涉及增加的单个服务器的容量,例如使用更强大的CPU,加入更多的RAM,或增加的存储空间量。可用技术中的限制可能限制单个机器对于给定工作负载足够强大。此外,基于云的提供商具有基于可用硬件配置的硬上限。因此,对于垂直缩放存在实际的最大值。

    • 包括将系统数据和负载在多个服务器,添加额外的服务器,需要增加容量。虽然单个机器的总速度或容量可能不高,但是每个机器处理整个工作负载的子集,潜在地提供比单个高速大容量服务器更好的效率。扩展部署的容量仅需要根据需要添加额外的服务器,这可以是比单个机器的高端硬件低的总体成本。权衡是基础设施的复杂性和部署的维护。

  • Mongodb的支持水平扩展,分片。

1、分片目的

对于单台数据库服务器,庞大的数据量及高吞吐量的应用程序对它而言无疑是个巨大的挑战。频繁的CRUD操作能够耗尽服务器的CPU资源,快速的数据增长也会让硬盘存储无能为力,最终内存无法满足数据需要导致大量的I/O,主机负载严重。为了解决这种问题,对于数据库系统一般有两种方法:垂直扩展分片(水平扩展)。

【垂直扩展】:添加更多的CPU和存储资源来增加系统性能。这种方式缺点是:拥有大量CPU和RAM资源的高端机器比普通PC机器昂贵得太多,而且单点故障会影响整个系统的服务。

【分片】:相反地,分片将大的数据集分配到多台主机上,每个分片是一个独立的数据库,这些分片整体上构成一个完整的逻辑数据库。分片减少了每台服务器上的数据操作量,随着集群的增长,每台分片处理越来越少的数据,结果,增加了系统整体服务能力。另外,分片还减少了每台服务器需要存储的数据量。

2、MongoDB中的分片

MongoDB通过配置分片集群来支持分片,一个分片集群包括以下几个组件:分片,查询路由,配置服务器

  • 分片:用来存储数据,为了提供系统可用性和数据一致性,一个生产环境的分片集群,通常每个分片是一个副本集。
  • 查询路由:指客户端应用访问每个分片的路径。
  • 配置服务器:存储集群的元数据,这些数据包含了集群数据集到各分片的映射关系。查询路由就是通过这些元数据到特定的分片上执行指定的数据操作。(从v3.2开始,配置服务器也可以作为副本集,但是必须使用WiredTiger存储引擎,反对使用3个镜像实例作为配置服务器)
数据划分

MongoDB的数据划分,是以集合级别为标准。分片通过shard key来划分集合数据。

  • shard key:

为了对集合分片,你需要指定一个shard key。shard key既可以是集合的每个文档的索引字段也可以是集合中每个文档都有的组合索引字段。MongoDB将shard keys值按照块(chunks)划分,并且均匀的将这些chunks分配到各个分片上。MongoDB使用基于范围划分基于散列划分来划分chunks的。

  • 基于范围划分

MongoDB通过shard key值将数据集划分到不同的范围就称为基于范围划分。对于数值型的shard key:你可以虚构一条从负无穷到正无穷的直线(理解为x轴),每个shard key 值都落在这条直线的某个点上,然后MongoDB把这条线划分为许多更小的没有重复的范围成为块(chunks),一个chunk就是就某些最小值到最大值的范围。

  • 基于散列划分:

MongoDB计算每个字段的hash值,然后用这些hash值建立chunks。

  • 基于范围和基于散列划分的性能比较:

基于范围划分对于范围查询比较高效。假设在shard key上进行范围查询,查询路由很容易能够知道哪些块与这个范围重叠,然后把相关查询按照这个路线发送到仅仅包含这些chunks的分片。但是基于范围划分很容易导致数据不均匀分布,这样会削弱分片集群的功能。例如当shard key是个成直线上升的字段,如时间。那么,所有在给定时间范围内的请求都会映射到相同的chunk,也就是相同的分片上。这种情况下,小部分的分片将会承受大多数的请求,那么系统整体扩展并不理想。

相反的,基于散列划分是以牺牲高效范围查询为代价,它能够均匀的分布数据,散列值能够保证数据随机分布到各个分片上。

  • 使用标签来自定义数据分布

MongoDB允许DBA们通过标签标记分片的方式直接平衡数据分布策略,DBA可以创建标签并且将它们与shard key值的范围进行关联,然后分配这些标签到各个分片上,最终平衡器转移带有标签标记的数据到对应的分片上,确保集群总是按标签描述的那样进行数据分布。标签是控制平衡器行为及集群中块分布的主要方法

4、维持数据分布平衡

新加入的数据及服务器都会导致集群数据分布不平衡,MongoDB采用两种方式确保数据分布的平衡:

  • 拆分

拆分是一个后台进程,防止块变得太大。当一个块增长到指定块大小的时候,拆分进程就会块一分为二,整个拆分过程是高效的。不会涉及到数据的迁移等操作。

  • 平衡

平衡器是一个后台进程,管理块的迁移。平衡器能够运行在集群任何的mongd实例上。当集群中数据分布不均匀时,平衡器就会将某个分片中比较多的块迁移到拥有块较少的分片中,直到数据分片平衡为止。举个例子:如果集合users有100个块在分片1里,50个块在分片2中,那么平衡器就会将分片1中的块迁移到分片2中,直到维持平衡。

分片采用后台操作的方式管理着源分片和目标分片之间块的迁移。在迁移的过程中,源分片中的块会将所有文档发送到目标分片中,然后目标分片会获取并应用这些变化。最后,更新配置服务器上关于块位置元数据。

  • 从集群中增加和删除分片

添加新分片到集群中会产生数据不平衡,因为新分片中没有块,当MongoDB开始迁移数据到新分片中时,等到数据分片平衡恐怕需要点时间。

当删除一个分片时,平衡器将会把分片中所有块迁移到另一个分片中,在完成这些迁移并更新元数据后,你就可以安全的删除分片了。

分片集群

片键

  • 一个mongodb分片集群由以下几部分组成

  • 每个shard包含分片数据的子集,每个shard可以部署一个副本集
    一台机器的一个数据表 Collection1 存储了 1T 数据,压力太大了!在分给4个机器后,每个机器都是256G,则分摊了集中在一台机器的压力。也许有人问一台机器硬盘加大一点不就可以了,为什么要分给四台机器呢?不要光想到存储空间,实际运行的数据库还有硬盘的读写、网络的IO、CPU和内存的瓶颈。在mongodb集群只要设置好了分片规则,通过mongos操作数据库就能自动把对应的数据操作请求转发到对应的分片机器上。在生产环境中分片的片键可要好好设置,这个影响到了怎么把数据均匀分到多个分片机器上,不要出现其中一台机器分了1T,其他机器没有分到的情况,这样还不如不分片!
  • 13.jpg

  • mongos MongoS充当一个查询的路由器,提供客户端应用程序和所述分片簇之间的接口,mongos作为数据库集群请求的入口,所有的请求都是通过mongos来进行协调的,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求转发到对应的shard服务器上,在生产环境中通常有多个monogs作为请求的入口,防止其中一个挂掉所有mongos请求都没有办法操作
  • config servers 为集群配置的服务器存储元数据和配置设置,从Mongodb3.4开始,配置服务器必须部署为复制集,mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存当中,配置服务器则实际存储这些数据,mongos第一次启动或者关掉重启会从configserver中加载配置信息,以后如果配置信息有变化会通过所有的mongos更新自己的状态,这样mongs就能继续准确路由,在生产环境中通常有多个config server配置服务器,因为它存储了分片路由的元数据,如果就一个如果挂掉一个,整个mongodb基础就会挂掉。
  • 片键
    1、在分发集合中文件时,mongodb的分区使用的收集片键关键,在片键由存在目标集合中的每个文档中的一个不可变或多个字段
    2、在分割集合的时候选择片键,<font color=red size=4>分片键完成之后是不能更改的</font>,分片集合只能有1个片键,到片键的非空集合,集合必须有一个索引,与片键启动,对于空空集合,如果集合尚未具有指定分片键的相关索引,则Mongodb会创建索引
    3、分片键的选择会影响分片集群的性能和效率以及可伸缩性,具有最佳可能的硬件可以通过分片达到瓶颈,片键和其支持指数的选择也可以影响数据的拆分,但集群可以使用
    4、片键决定了集群中一个集合的文件咋不同的片键中的分布,片键字段必须被索引,且在集合中的每条记录都不能为空,可以是单个字段或者是复合字段
    5、Mongodb使用片键的范围是吧数据分布在分片中,每个范围,又称为数据块,定义了一个不重叠的片键范围Mongodb把数据块与他们存储的文档分布到集群中的不同分布中,当一个数据块的大小超过数据块最大大小的时候,Mongodb会宜聚片键的范围将数据块分裂为更小的数据块

     

    14.png

  • 片键的使用语法
    1、在分片集合,必须制定目标集合和片键的

2、哈希片键使用单字段的哈希索引进行数据在分片之间的平均分发,除数取余一致性哈希
3、被选为片键的字段必须有足够大的基数,或者有足够多的不同的值,对于单调的递增的字段如果ObjectID或是时间戳,哈希索引效果更好
4、如果在一个空集合创建哈希片键,Mongodb会自动创建并迁移数据块,以保证每个分片上都有两个数据块,也可以执行shardCollection指定numInitialChunks参数以控制初始化时Mongodb创建数据块数目,或者手动调用split命令在分片上分裂数据块
5、对使用了哈希片键分片的集合进行请求时,Mongodb会自动计算哈希值,应用不需要解析哈希值

shard集群部署
  • 部署ip规划
    172.17.237.33:30001 config1
    172.17.237.34:30002 config2
    172.17.237.36:30003 config3
    172.17.237.37:40000 mongos
    172.17.237.38:50000 shard1
    172.17.237.39:50001 shard2
    172.17.237.40:50002 shard3
    172.17.237.41:60000 sha1
    172.17.237.42:60001 sha2
    172.17.237.43:60002 sha3
配置config server 副本集

  • 配置confi1配置文件
  • 配置confi2配置文件
  • 配置confi3配置文件
  • 启动config server
  • 配置config副本集
  • 配置mongos
  • 添加配置mongos配置文件
  • 启动mongos
  • shard2副本集集群部署
  • 配置sha配置文件
  • 启动shard
  • 配置shard2副本集集群
  • 分片配置
  • 分片集合中是否有数据
    默认第一个添加的shard就是主shard,存放没有被分割的shard就是主shard
    在创建分片的时,必须在索引中创建的,如果这个集合中有数据,则首先自己先创建索引,然后进行分片,如果是分片集合中没有数据的话,则就不需要创建索引,就可以分片

  • 登陆mongos配置分片,向分区集群中添加shard服务器和副本集

  • 添加shard副本集

  • 指定那个数据库使用分片,创建片键

  • 查看sh.status()信息

  • 测试批量插入数据验证

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值