首页
mongodb
Linux
云原生
常用bat文件
Maven教程
设计模式
Oracle常用知识梳理
更多……
申请加入课程
MongDB简介
MongDB及其附属工具介绍和安装
MongoDB 备份(mongodump)与恢复(mongorestore)
MongoDB基础DML和DDL操作
MongoDB 可视化工具
MongoDB 索引
MongoDB 聚合
MongDB 复制与分片集群
MongoDB 监控
MongoDB 查询分析
MongoDB 概念解析
MongoDB GridFS
MongoDB Java
Redis、Memcache和MongoDB的区别
MongoDB的其它关键知识点
MongoDB k8s单节点部署和备份
MongoDB 的配置mongodb.conf
MongoDB k8s下部署 Replica Set
MongoDB 状态查询
MongoDB 数据库的日志解析
MongoDb 常见错误处理方法收集
MongoDB 一次性能测试和问题解决
MongDB 复制与分片集群
星辰
2018-10-13
0
0
151
人
0
人评论
0
人举报
[TOC] # MongoDB的高可用方案 * 主从复制,已经不推荐使用,存在单点故障 * Replica Sets,代替了主从复制集群,支持故障后主节点的自动迁移 * 分片模式,生产环境推荐使用的集群方式,搭建起来稍微复杂些,对机器资源也较多 * 可以有效减少单台机器CPU和RAM的压力 * 提供可用性,可以避免单点故障 * 支持自动分片,可以解决单个磁盘容量不足的问题 * 可以提高QPS,将流量分摊到多个分片上,使集群拥有更大的负载 * 一般分片集群每个片上会进行副本集方式搭建,以提供容灾性,也就是正式生产环境搭建的分片集群基本都是包含副本集集群的 ## 注意 * 生产环境服务器需要是64系统,否则受4G大小的限制 * MongoDB支持BSON文档嵌套的级别不超过100 * Replica Sets每个节点数据支持32T,Replica Sets每个实例建议数据不要超过4T,数据量大备份恢复时间会很长 * 在Mongodb3.0中Replica Sets成员最最多支持50个,也就是说Replica Sets做大支持50个节点 * 我们通常分片会使用默认的chunk大小为64M,如果我们的分片key (片键)values值是512字节,分片节点支持最大32768个也就是最大支持数据量为32768TB * 一个片键大小不能超过512字节 ## MongoDB 分片 分片就是将数据存储到多台机器中,使用分片来使数据横向存储支持大规模的数据集部署和支持负载均衡提高吞吐量。 生产环境下的mongo使用,建议使用分片的方式部署,既支持扩展也支持多副本的备份要求。 **注意**: 当你的服务器资源比较少,比如只有2台时,由于我们每个分片也是需要做副本集来保障数据的安全,所以2个节点时,其实并不能解决容量的问题。分片反而会增加难度。但是分片的方式搭建的集群有个好处就是你后续可以往分片里面添加分片,所以扩展性更好。 **分片背景** 使用分片集群需要满足很多的要求,其部署的代价是比较高的, 什么时候会用到分片集群的部署 * 减少单机的存储空间,提高总存空间。 * 系统活跃工作集将要超过你系统RAM最大容量的时候(希望将大量数据放在内存中提高性能)。 * 减少单机请求数,将单机负载,提高总负载。 ### 分片架构图   ### Auto - Sharding 成员 shards、Config Servers 和 mongos instance(query routers) #### Shard 称为片,上面运行mongod进程来存储数据。每个shard 可以是一台服务器运行单独一个Mongod实例,但是为了提高系统的可靠性实现自动故障恢复,一个Shard应该是一个复制集(官方建议)Shard相当于Hadoop HDFS中的datanode,用来存储数据。每个Shard中存储了一个集合的的部分数据,即集合的子集。 * 使用`sh.status()`方法可以查看整个分片集群的状态 :包括哪个分片是主片,数据块的分布情况 * 在开发测试环境下,一个Shard可以只包含一个mongod实例。但在商业部署的条件下,一个 Shard是一个复制集。 * 只有分片的集合,它的文档才会水平的存储到集群的各个分片上,没有分片的集合的文档会存储到主分片上(primary shard)。主分片用来存储已分片的集合和未分片的集合的数据。 * 使用movePrimary命令可以改变主分片,但是这样会付出很大的代价,因为它会将所有未分片集合的数据拷贝到主分片上,而在拷贝数据的过程中你是不能进行其他操作的。当我们部署分片集群的时候,第一个分片会被默认的作为主分片 #### Config Server (配置服务器) 配置服务器是一个Mongod实例,它负责存储了集群中的`元数据(MetaData),包括每个shard服务器上的块列表以及每个数据块所对应的片键取值范围`,每个配置服务器都有一份包括所有块信息的完全副本,系统使用一个两阶段锁提交协议来保证config server中配置的快速一致性和高可靠性。 Config Server 相当于Hadoop HDFS中的镜像文件和编辑日志 Config Servers有张从数据块到具体分片的映射表, monogs进程通过这张映射表来将客户端的请求路由到指定分片上,在商业部署上一般会放置3个配置服务器。 **注意:**为防止单点故障,进行备份和提高安全,在实际部署时通常是需要部署3个配置服务器。如果只部署一个配置服务器,它出现故障宕机的话,那么整个集群就无法访问。如果它无法从故障恢复的话,这个集群也将不可用。 `配置服务器存储的数据是十分重要的,应该经常对其进行备份` **注意:** * 如果三个中的一个或两个配置服务器变的不可用,那么整个集群的元数据就会变为只读状态,但此时你仍然可以从分片读和写数据,但是在Shard中不会进行数据块的分割和移动,只有三个配置服务器都可以用的情况下才会进行数据块的分割和移动。 * 如果三个配置服务器都变得不可用了,在没有重启mongos进程的情况下,你依然可以读写集群中的数据,但是如果在所有配置服务器变得可用前你重启了mongos进程的话,那就无法进行读写了。也就是说,在没有集群元数据的情况下,整个集群是无法使用的。所以要总是确保配置服务器的可用且功能完整。 * 当有下列情况发生时会写配置服务器:当有数据块进行分裂的时候;在分片间移动数据块的时候; 当有下列情况发生时会读配置服务器:当mongos集群第一次启动的时候,或者一个已经存在的mongos进程进行重启的时候;当一个数据块移动完毕后,mongos进程更新自己缓存的元数据的时候。 #### Mongos Mongos是一个mongos进程,可以将其看作一个路由和协调进程,它是集群与客户端交互的窗口,它使集群中多个组件看起来像一个单一的系统。 当Mongos启动的时候,它会从配置服务器获取同步数据 ,将配置服务器存储的数据全部缓存到内存中,当收到客户端的请求时,mongos通过查找映射表为请求寻找合适的片服务器,并将聚合后的结果传送给客户端。 Mongos的功能类似于Hadoop HDFS中的namenode,协调调度作用。 Mongos 进程并不需要持久状态,它的数据是其刚启动时从配置服务器中获得的,configure serve中发生的任何变化都会传播到每一个mongos进程。monogs进程可以运行在任何服务器上,同时启动的mongos进程数量也没有限制。 **注意:** * 在开发测试环境下可以只用一个mongos进程,为了分担来自客户端的请求,和避免单点故障需要启动多个mongos进程。 * 客户端的程序不能直接访问分服务器,mongons隐藏了分片的细节,对于客户端来说是透明的。 * 在实际部署的集群中,确保你的数据是有备份的,你的系统是高可用的,不存在单点故障点。为了达到上述的目的,一个商业集群必须有一下的组件:3个配置服务器,每一个配置服务器必须在不同的机器上 ,两个或多个复制集 ,一个或多个mongos。 * 在开发测试环境下的分片集群组件:一个配置服务器;至少一个分片 (一个复制集接或者是一个mongod实例);一个mongos实例。 ### Sharding工作过程 为了维护数据的均衡分布,MongoDB使用了两个后台进程:一个是分割器( Splitting ) ,一个是平衡器( Balancer ) #### 分割器(Splitting) `分割器的作用是防止数据块变大, 当一个数据块中的数据“长大”到指定大小时,分割器会将其一分为二。插入和更新操作都有可能触发分割。 分割的对象不是具体的数据,而是元数据,也就是说分割的过程只是修改元数据,可以认为是一种逻辑上的块划分,不会影响到分片上数据的分布,其过程是非常高效的。 **数据块大小的选择** MongoDB将片键的值域划分为不重叠的区间,每一个子区间对应一个数据块。MongoDB在集群间分发数据块。 数据块默认大小是60MB,也可以增大和减小。 如果块设置的太小的话,少量的数据会产生大量的块,很容易使集群进入不平衡的状态,会引起频繁的块移动,影响集群的性能,除此之数据块的个数的增加,也会导致元数据的文件大小的增加,影响查询效率。 如果数据块太大的话,会减少数据块移动的频率,有利于数据的查询,但是一旦需要移动数据块的时候会花费很长的时间,影响集群的整体性能。 **注意:** 数据块的大小是可变的,减小当前数据块大小的时候,系统需要花费时间来将原来大的数据块进行分割;如果增大当前数据块的话,原来小的数据块会继续“长大”直到超出新的设定值。 **平衡器(Balancer)** 平衡器的作用是管理数据数据块的移动, 当一个集合的数据块在集群中分布达到移动阈值(Migration Thresholds)的时候,平衡器就将数目最多的分片上的数据块移动到数目比较少的分片上。比如说,users集合在分片1上有100个数据块,分片2上有50个数据块,平衡器就会将分片1上的数据块移动到分配2上,直至uers集合在两个分片上的数据块个数相同。 **数据移动的过程** * 平衡器向源分片发送moveChunk的命令。 * 源分片收到命令后,会启动自己内部的一个moveChunk命令,如果在数据移动过程中有客户端发来读写请求的话,都会发送到源分片。(因为配置服务器上的元数据还没有改变)。 * 目标片开始向源分片请求将要移动的数据块的文档,准备拷贝文档数据。 * 当目标分片接收到数据块的最后一个文档后,目标分片会启动一个同步进程来检查,是否已经拷贝完全部的文档。 * 当同步完成后,目标分片会连接配置服务器,更新元数据列表中数据块的地址。 * 当目标分片完成元数据更新后,源分片就会删除原来的数据块.如果有新的数据块需要移动的话,可以继续进行移动。 * 配置服务器会通知monogs进程更新自己的映射表。 移动过程中,目标分片会拷贝源分片上将要移动的数据块中的文档,当移动完成后会更新配置服务器上的元数据,并删除源分片上的数据块。如果移动过程中,涉及到正在移动数据块的数据请求都会发送到源数据块上。如果移动过程中,发生错误的话,平衡器就会终止数据的复制,将待移动的数据块还保留在源分片上。 当添加和删除分片的时候都会使集群进去不平衡的状态,导致数据块的移动。 **注意** * 平衡器的工作有两个目标,第一是保持不同分片之间的数据平衡,另外还需要尽量最小化不同分片之间交互的数据块次数。 * 除了使用平衡器自动移动数据块外,也可以手动的方式来移动数据块。 * 默认数据块的大小是64MB,平衡器不能保证每个分片间的数据块时刻是相等的,如果那样的话会频繁的发生数据块的移动,这样会严重影响集群的性能。一般情况下会设定一个(Migration Thresholds)移动阈值,当集群中不平衡数据块超过指定阈值的时候,才会进行数据块的移动。 * 在实际的条件下,你的数据会保持在一个单一分片上,除非你的集群有成千上百个数据块的时候。 ### CentOS7.6下搭建分片集群 CentOS7.6下搭建分片集群,参考一下文章 `https://blog.csdn.net/liver_life/article/details/100562949?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control` ## replication set 复制集 复制集:自带故障转移功能的主从复制 mongodb 不推荐主从复制,推荐建立副本集(Replica Set)来保证1个服务挂了,可以有其他服务顶上,程序正常运行,几个服务的数据都是一样的,后台自动同步。主从复制其实就是一个单副本的应用,没有很好的扩展性饿容错性。然而副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多个副本存在,并且解决了"主节点挂掉后,整个集群内会自动切换"的问题。副本集比传统的Master-Slave主从复制有改进的地方就是它可以进行故障的自动转移,如果我们停掉复制集中的一个成员,那么剩余成员会再自动选举一个成员,作为主库。 Replica Set 使用的是 n 个 mongod 节点,构建具备自动的容错功能(auto-failover),自动恢复的(auto-recovery)的高可用方案。使用 Replica Set 来实现读写分离。通过在连接时指定或者在主库指定 slaveOk,由Secondary 来分担读的压力,Primary 只承担写操作。对于 Replica Set 中的 secondary 节点默认是不可读的 ### 关于副本集的概念 ``` 副本集是一种在多台机器同步数据的进程,副本集体提供了数据冗余,扩展了数据可用性。在多台服务器保存数据可以避免因为一台服务器导致的数据丢失。 也可以从硬件故障或服务中断解脱出来,利用额外的数据副本,可以从一台机器致力于灾难恢复或者备份。 在一些场景,可以使用副本集来扩展读性能,客户端有能力发送读写操作给不同的服务器。也可以在不同的数据中心获取不同的副本来扩展分布式应用的能力。 mongodb副本集是一组拥有相同数据的mongodb实例,主mongodb接受所有的写操作,所有的其他实例可以接受主实例的操作以保持数据同步。 主实例接受客户的写操作,副本集只能有一个主实例,因为为了维持数据一致性,只有一个实例可写,主实例的日志保存在oplog。 Client Application Driver Writes Reads | | Primary |Replication|Replication Secondary Secondary 二级节点复制主节点的oplog然后在自己的数据副本上执行操作,二级节点是主节点数据的反射,如果主节点不可用,会选举一个新的主节点。 默认读操作是在主节点进行的,但是可以指定读取首选项参数来指定读操作到副本节点。 可以添加一个额外的仲裁节点(不拥有被选举权),使副本集节点保持奇数,确保可以选举出票数不同的直接点。仲裁者并不需要专用的硬件设备。 仲裁者节点一直会保存仲裁者身份 ........异步复制........ 副本节点同步直接点操作是异步的,然而会导致副本集无法返回最新的数据给客户端程序。 ........自动故障转移........ 如果主节点10s以上与其他节点失去通信,其他节点将会选举新的节点作为主节点。 拥有大多数选票的副节点会被选举为主节点。 副本集提供了一些选项给应用程序,可以做一个成员位于不同数据中心的副本集。 也可以指定成员不同的优先级来控制选举。 ``` ### 副本集的结构及原理 MongoDB 的副本集不同于以往的主从模式。 在集群Master故障的时候,副本集可以自动投票,选举出新的Master,并引导其余的Slave服务器连接新的Master,而这个过程对于应用是透明的。可以说MongoDB的副本集 是自带故障转移功能的主从复制。 相对于传统主从模式的优势 传统的主从模式,需要手工指定集群中的 Master。如果 Master 发生故障,一般都是人工介入,指定新的 Master。 这个过程对于应用一般不是透明的,往往伴随着应用重 新修改配置文件,重启应用服务器等。而 MongoDB 副本集,集群中的任何节点都可能成为 Master 节点。一旦 Master 节点故障,则会在其余节点中选举出一个新的 Master 节点。 并引导剩余节点连接到新的 Master 节点。这个过程对于应用是透明的。  一个副本集即为服务于同一数据集的多个 MongoDB 实例,其中一个为主节点,其余的都为从节点。主节 点上能够完成读写操作,从节点仅能用于读操作。主节点需要记录所有改变数据库状态的操作,这些记录 保存在 oplog 中,这个文件存储在 local 数据库,各个从节点通过此 oplog 来复制数据并应用于本地,保持 本地的数据与主节点的一致。oplog 具有幂等性,即无论执行几次其结果一致,这个比 mysql 的二进制日 志更好用。 集群中的各节点还会通过传递心跳信息来检测各自的健康状况。当主节点故障时,多个从节点会触发一次 新的选举操作,并选举其中的一个成为新的主节点(通常谁的优先级更高,谁就是新的主节点),心跳信 息默认每 2 秒传递一次。  客户端连接到副本集后,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份。一旦主节点挂掉,副本节点就会选举一个新的主服务器。这一切对于应用服务器不需要关心。 ``` 心跳检测: 整个集群需要保持一定的通信才能知道哪些节点活着哪些节点挂掉。mongodb节点会向副本集中的其他节点每两秒就会发送一次pings包,如果其他节点在10秒钟 之内没有返回就标示为不能访问。每个节点内部都会维护一个状态映射表,表明当前每个节点是什么角色、日志时间戳等关键信息。如果是主节点,除了维护映射表 外还需要检查自己能否和集群中内大部分节点通讯,如果不能则把自己降级为secondary只读节点。 数据同步 副本集同步分为初始化同步和keep复制。初始化同步指全量从主节点同步数据,如果主节点数据量比较大同步时间会比较长。而keep复制指初始化同步过后,节点 之间的实时同步一般是增量同步。初始化同步不只是在第一次才会被处罚,有以下两种情况会触发: 1)secondary第一次加入,这个是肯定的。 2)secondary落后的数据量超过了oplog的大小,这样也会被全量复制。 ``` 副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举出一位新的主服务器。 副本集包括三种节点:主节点、从节点、仲裁节点。 ``` 1)主节点负责处理客户端请求,读、写数据, 记录在其上所有操作的 oplog; 2)从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。默认情况下,从节点不支持外部读取,但可以设置; 副本集的机制在于主节点出现故障的时候,余下的节点会选举出一个新的主节点,从而保证系统可以正常运行。 3)仲裁节点不复制数据,仅参与投票。由于它没有访问的压力,比较空闲,因此不容易出故障。由于副本集出现故障的时候,存活的节点必须大于副本集节点总数的一半, 否则无法选举主节点,或者主节点会自动降级为从节点,整个副本集变为只读。因此,增加一个不容易出故障的仲裁节点,可以增加有效选票,降低整个副本集不可用的 风险。仲裁节点可多于一个。也就是说只参与投票,不接收复制的数据,也不能成为活跃节点。 ``` 官方推荐MongoDB副本节点最少为3台, 建议副本集成员为奇数,最多12个副本节点,最多7个节点参与选举。限制副本节点的数量,主要是因为一个集群中过多的副本节点,增加了复制的成本,反而拖累了集群 的整体性能。 太多的副本节点参与选举,也会增加选举的时间。而官方建议奇数的节点,是为了避免脑裂 的发生。 ### 副本集的工作流程 ``` 在 MongoDB 副本集中,主节点负责处理客户端的读写请求,备份节点则负责映射主节点的 数据。备份节点的工作原理过程可以大致描述为,备份节点定期轮询主节点上的数据操作,然后对 自己的数据副本进行这些操作,从而保证跟主节点的数据同步。至于主节点上的所有 数据库状态改变 的操作,都会存放在一张特定的系统表中。备份节点则是根据这些数据进行自己的数据更新。 oplog 上面提到的数据库状态改变的操作,称为 oplog(operation log,主节点操作记录)。oplog 存储在 local 数据库的"oplog.rs"表中。副本集中备份节点异步的从主节点同步 oplog,然后重新 执行它记录的操作,以此达到了数据同步的作用。 关于 oplog 有几个注意的地方: 1)oplog 只记录改变数据库状态的操作 2)存储在 oplog 中的操作并不是和主节点执行的操作完全一样,例如"$inc"操作就会转化为"$set"操作 3)oplog 存储在固定集合中(capped collection),当 oplog 的数量超过 oplogSize,新的操作就会覆盖旧的操作 数据同步 在副本集中,有两种数据同步方式: 1)initial sync(初始化):这个过程发生在当副本集中创建一个新的数据库或其中某个节点刚从宕机中恢复,或者向副本集中添加新的成员的时候,默认的,副本集中的节点会从离 它最近 的节点复制 oplog 来同步数据,这个最近的节点可以是 primary 也可以是拥有最新 oplog 副本的 secondary 节点。该操作一般会重新初始化备份节点,开销较大。 2)replication(复制):在初始化后这个操作会一直持续的进行着,以保持各个 secondary 节点之间的数据同步。 initial sync 当遇到无法同步的问题时,只能使用以下两种方式进行 initial sync 了 1)第一种方式就是停止该节点,然后删除目录中的文件,重新启动该节点。这样,这个节 点就会执行 initial sync 注意:通过这种方式,sync 的时间是根据数据量大小的,如果数据量过大,sync 时间就会很长同时会有很多网络传输,可能会影响其他节点的工作 2)第二种方式,停止该节点,然后删除目录中的文件,找一个比较新的节点,然后把该节点目录中的文件拷贝到要 sync 的节点目录中 通过上面两种方式中的一种,都可以重新恢复"port=33333"的节点。不在进行截图了。 副本集管理 1)查看oplog的信息 通过"db.printReplicationInfo()"命令可以查看 oplog 的信息 字段说明: configured oplog size: oplog 文件大小 log length start to end: oplog 日志的启用时间段 oplog first event time: 第一个事务日志的产生时间 oplog last event time: 最后一个事务日志的产生时间 now: 现在的时间 2)查看 slave 状态 通过"db.printSlaveReplicationInfo()"可以查看 slave 的同步状态 当插入一条新的数据,然后重新检查 slave 状态时,就会发现 sync 时间更新了 ``` ### 副本集选举的过程和注意点 ``` Mongodb副本集选举采用的是Bully算法,这是一种协调者(主节点)竞选算法,主要思想是集群的每个成员都可以声明它是主节点并通知其他节点。 别的节点可以选择接受这个声称或是拒绝并进入主节点竞争,被其他所有节点接受的节点才能成为主节点。 节点按照一些属性来判断谁应该胜出,这个属性可以是一个静态 ID,也可以是更新的度量像最近一次事务ID(最新的节点会胜出) 副本集的选举过程大致如下: 1)得到每个服务器节点的最后操作时间戳。每个 mongodb 都有 oplog 机制会记录本机的操作,方便和主服 务器进行对比数据是否同步还可以用于错误恢复。 2)如果集群中大部分服务器 down 机了,保留活着的节点都为 secondary 状态并停止,不选举了。 3)如果集群中选举出来的主节点或者所有从节点最后一次同步时间看起来很旧了,停止选举等待人来操作。 4)如果上面都没有问题就选择最后操作时间戳最新(保证数据是最新的)的服务器节点作为主节点。 副本集选举的特点: 选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半(建议副本集成员为奇数。最多12个副本节点,最多7个节点参与选举) 如果已经小于一半了所有节点保持只读状态。集合中的成员一定要有大部分成员(即超过一半数量)是保持正常在线状态,3个成员的副本集,需要至少2个从属节点是正常状态。 如果一个从属节点挂掉,那么当主节点down掉 产生故障切换时,由于副本集中只有一个节点是正常的,少于一半,则选举失败。 4个成员的副本集,则需要3个成员是正常状态(先关闭一个从属节点,然后再关闭主节点,产生故障切换,此时副本集中只有2个节点正常,则无法成功选举出新主节点)。 ``` ### 副本集数据过程 ``` Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点 停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的 oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作 执行多次,与执行一次的效果是一样的。简单的说就是: 当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步: 1)检查自己local库的oplog.rs集合找出最近的时间戳。 2)检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。 3)将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。 副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序 的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%, oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。 注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。 ``` ### MongoDB 同步延迟问题 ``` 当你的用户抱怨修改过的信息不改变,删除掉的数据还在显示,你掐指一算,估计是数据库主从不同步。与其他提供数据同步的数据库一样,MongoDB 也会遇到同步延迟的问题, 在MongoDB的Replica Sets模式中,同步延迟也经常是困扰使用者的一个大问题。 什么是同步延迟? 首先,要出现同步延迟,必然是在有数据同步的场合,在 MongoDB 中,有两种数据冗余方式,一种是Master-Slave 模式,一种是Replica Sets模式。这两个模式本质上都是 在一个节点上执行写操作, 另外的节点将主节点上的写操作同步到自己这边再进行执行。在MongoDB中,所有写操作都会产生 oplog,oplog 是每修改一条数据都会生成一条,如果你采用一个批量 update 命令更新了 N 多条数据, 那么抱歉,oplog 会有很多条,而不是一条。所以同步延迟就是写操作在主节点上执行完后,从节点还没有把 oplog 拿过来再执行一次。而这个写操作的量越大,主节点与从节点的差别也就越大,同步延迟也就越大了。 同步延迟带来的问题 首先,同步操作通常有两个效果,一是读写分离,将读操作放到从节点上来执行,从而减少主节点的 压力。对于大多数场景来说,读多写少是基本特性,所以这一点是很有用的。 另一个作用是数据备份, 同一个写操作除了在主节点执行之外,在从节点上也同样执行,这样我们就有多份同样的数据,一旦 主节点的数据因为各种天灾人祸无法恢复的时候,我们至少还有从节点可以依赖。但是主从延迟问题 可能会对上面两个效果都产生不好的影响。 如果主从延迟过大,主节点上会有很多数据更改没有同步到从节点上。这时候如果主节点故障,就有 两种情况: 1)主节点故障并且无法恢复,如果应用上又无法忍受这部分数据的丢失,我们就得想各种办法将这部 数据更改找回来,再写入到从节点中去。可以想象,即使是有可能,那这也绝对是一件非常恶心的活。 2)主节点能够恢复,但是需要花的时间比较长,这种情况如果应用能忍受,我们可以直接让从节点提 供服务,只是对用户来说,有一段时间的数据丢失了,而如果应用不能接受数据的不一致,那么就只能下线整个业务,等主节点恢复后再提供服务了。 如果你只有一个从节点,当主从延迟过大时,由于主节点只保存最近的一部分 oplog,可能会导致从 节点青黄不接,不得不进行 resync 操作,全量从主节点同步数据。 带来的问题是:当从节点全量同步的时候,实际只有主节点保存了完整的数据,这时候如果主节点故障,很可能全 部数据都丢掉了。 ``` ### docker部署 Replica Set 同一台机器下模拟 ``` # 1创建网络与容器 docker pull mongo docker network create mongo-rs docker run --name mongo1 -p 27027:27027 --net mongo-rs -d mongo mongod --replSet "rs0" --port 27027 docker run --name mongo2 -p 27028:27028 --net mongo-rs -d mongo mongod --replSet "rs0" --port 27028 docker run --name mongo3 -p 27029:27029 --net mongo-rs -d mongo mongod --replSet "rs0" --port 27029 # 2分别进入每个容器执行,这一步也可以不用,不做这一步第三部则写ip docker exec -it mongo1 /bin/bash echo "127.0.0.1 mongo1 mongo2 mongo3" >> /etc/hosts docker exec -it mongo2 /bin/bash echo "127.0.0.1 mongo1 mongo2 mongo3" >> /etc/hosts docker exec -it mongo3 /bin/bash echo "127.0.0.1 mongo1 mongo2 mongo3" >> /etc/hosts # docker restart mongo1 docker restart mongo2 docker restart mongo3 # 3进入一个容器初始化副本集 docker exec -it mongo1 mongo --port 27027 # https://docs.mongodb.com/manual/reference/method/rs.initiate/ rs.initiate( { _id: "rs0", version: 1, members: [ { _id: 0, host : "mongo1:27027" }, { _id: 1, host : "mongo2:27028" }, { _id: 2, host : "mongo3:27029" } ] } ) # 4 Application连接 mongodb://127.0.0.1:27027,127.0.0.1:27028,127.0.0.1:27029/databaseName?slaveOk=true&replicaSet=rs0&write=1&connectTimeoutMS=30000&readPreference=primary mongodb://192.168.0.253:27027,192.168.0.253:27028,192.168.0.253:27029/databaseName?slaveOk=true&replicaSet=rs0&write=1&connectTimeoutMS=30000&readPreference=primary ``` ### Mongodb Replica Set K8s 部署 查看课题下的专题文章。 ## 主从复制 主从复制是MongoDB最常用的复制方式,也是一个简单的数据库同步备份的集群技术,这种方式很灵活.可用于备份,故障恢复,读扩展等。 不推荐使用:因为存在单点故障,现在一般被复制集的方式代替 搭建可以参考 `https://www.cnblogs.com/nulige/p/7613721.html` 其他参考文档: `https://www.cnblogs.com/kevingrace/p/5752382.html`
所有评论列表
点我发表评论