大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?

让我们一起,一探究竟,继续学习MongoDB高可用和片键策略,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。

一、复制

在MongoDB中,创建副本集后就可以使用复制功能了,副本集是一组服务器,其中一个用于处理写操作的主节点primary,还有多个用于保存主节点数据副本的从节点secondary。如果主节点崩溃了,则从节点会选取出一个新的主节点。

如果使用复制功能时有一台服务器停止运行了,那么仍然可以从副本集中的其它服务器访问数据。如果服务器上的数据已损坏或无法访问,则可以从副本集中的其它成员中创建一个新的数据副本。

副本集中的每个成员都必须能够连接到其它成员,如果收到有关成员无法访问到其它成员,则可能需要更改网络配置以允许它们之间的连接。

二、如何进行选举

当一个从节点无法与主节点连通时,它就会联系并请求其它的副本集成员将自己选举为主节点。

其它成员会做几项健全性检查:

  1. 它们能否连接到主节点,而这个主节点是发起选举的节点无法连接到的?
  2. 这个发起选举的从节点是否有最新数据?
  3. 有没有其它更高优先级的成员可以被选举为主节点?

MongoDB在3.2版本中引入了第1版复制协议。这是一个类PAFT的协议,并且包含了一些特定于MongoDB的副本集概念,比如仲裁节点、优先级、非选举成员、写入关注点等。还提出了很多新概念,比如更短的故障转移时间,大大减少了检测主节点失效的时间,它还通过使用term ID来防止重复投票。

RAFT是一种共识算法,它被分解成了相对独立的子问题。共识是指多台服务器或进程在一些值上达成一致的过程。RAFT确保了一致性,使得同一序列的命令产生相同序列的结果,并在所部署的各个成员中达到相同序列的状态。

副本集成员相互间每隔两秒发送一次心跳。如果某个成员在10秒内没有反馈心跳,则其它成员会将不良成员标记为无法访问。选举算法将尽最大努力尝试让具有最高优先权的从节点发起选举。成员优先权会影响选举的时机和结果。优先级高的从节点要比优先级低的从节点更快发起选举,而且也更有可能成为主节点。然而,低优先级的从节点也是有可能被短暂的选举为主节点的,副本集成员会继续发起选举直到可用的最高优先级成员被选举为主节点。被选举为主节点的从节点必须拥有最新的复制数据。

三、优先级

优先级用于表示一个成员称为主节点的优先程度,取值范围是0 ~ 100。数值越大,优先级越高。默认为1,如果将priority设置为0,表示此节点永远无法成为主节点,这样的成员还有一个名字~被动成员。

四、选举仲裁者

大多数小型项目,MongoDB只有两个副本集,为了参与选举,MongoDB支持一种特殊类型的成员,称为仲裁者,其唯一作用就是参与仲裁。仲裁者不参与存储数据,也不会为程序提供服务,它只是为了帮助只有两个副本集的集群选举主节点(为了满足大多数),需要注意的是,只能有一个仲裁者。

仲裁者的缺点:

假设有一个主节点,两个从节点,一个仲裁者。如果一个从节点停止运行了,那么就需要一个新的从节点,并且将主节点的数据复制到新的从节点,复制数据会父服务器造成很大的压力,降低程序运行速度。所以,尽可能使用奇数的从节点,而不是使用仲裁者。

五、同步

MongoDB通过保存操作日志oplog使多台服务器间保持相同的数据,oplog中保存着主节点执行的每一次写操作。oplog存在于主节点local数据库中的一个固定集合中,从节点通过查询此集合以获取需要复制的操作。

每个从节点同样维护着自己的oplog,用来记录它从主节点复制的每个操作。这使得每个成员都可以被用作其他成员的同步源。如果应用某个操作失败,则从节点会停止从当前数据源复制数据。

如果一个从节点由于某种原因停止工作了,它重新启动后,会从oplog中的最后一个操作开始同步。由于这些操作是先应用到数据上然后再写入oplog,因此从节点可能会重复已经应用到数据上的操作。MongoDB在设计时考虑了这点,oplog中的操作执行一次和多次,效果都是一样的,oplog中的每个操作都是幂等的。

六、处理过时数据

如果某个从节点的数据远远落后于同步源当前的操作,那么这个从节点就是过时的。过时的从节点无法赶上同步源,如果继续同步,从节点就需要跳过一些操作。此时,需要从其它节点进行复制,看看其它成员是否有更长的oplog以继续同步。如果都没有,该节点当前的复制操作将停止,需要进行完全同步或从最近的备份中恢复。

为了避免出现不同步的节点,让主节点拥有比较大的oplog以保存足够多的操作日志。

七、哈希片键

为了尽可能快地加载数据,哈希片键是最好的选择。哈希片键可以使任何字段随机分发。如果打算在大量查询中使用升序键,但又想在写操作时随机分发,哈希片键是不错的选择,不过需要注意的是,哈希片键无法执行指定目标的范围查询。

创建哈希片键:

db.users.createIndex({"name":"hashed"})

有一点需要注意,哈希片键的字段,不能是数组。

Error: hashed indexes do not currently support array values.

八、多热点

单独的mongod服务器在执行升序写操作时效率最高,这与分片相冲突,当写操作分发在集群中时分片效率最高。每个分片上都有几个热点,便于写操作在集群中均匀分发。

可以使用复合片键实现均匀分发,复合片键的第一个值可以是一个基数较小的值,片键的第二部分是一个升序值,这意味着在块的内部,值总是在增加的。

九、分片规则

1、分片的限制

比如上图的异常,片键不能是数组,大多数特殊类型的索引不能用作片键。特别是,不能在地理空间索引上进行分片。

2、片键的基数

片键与索引类似,在基数高的字段上进行分片,性能会更好。如果有一个status键,只有“正常”、"异常"、“错误”几个值,MongoDB是无法将数据拆分成3个以上的块(因为目前只有三个值),如果想将一个取值较小的键作为片键,那么可以将其与另一个拥有多值的键组成复合片键,比如createTime字段。这样复合片键就拥有了较高的基数。

十、控制数据分发

1、自动分片

MongoDB将集合均匀分发在集群中的每个分片上,如果存储的是同构数据,那么这种方式非常高效。如果有一个日志集合,价值不是很大,你可能不希望它存储在性能最好的服务器上,性能最好的服务器一般会存储重要的实时数据,而不允许其它集合使用它。

可以通过sh.addShardToZone("shard0","hign")sh.addShardToZone("shard1","low")sh.addShardToZone("shard2","low")实现它。

可以将不同的集合分配给不同的分片,比如,对及其重要的实时集合执行:

sh.updateZoneKeyRange("super.important",{"<shardKey>":MinKey},...{"<shardKey>":MaxKey},"high")

这条命令指的是:

对于这个集合super.important,将片键从负无穷到正无穷的数据保存在标记为“high”的分片上。这不会影响其它集合的均匀分发。

同样可以通过low,将不重要的日志集合存放在性能较差的服务器上。

sh.updateZoneKeyRange("super.logs",{"<shardKey>":MinKey},...{"<shardKey>":MaxKey},"low")

此时,日志集合就会均匀的分发到shard1和shard2上。

同样,可以通过removeShardFromZone()从区域中删除分片。

sh.removeShardFromZone("super.logs",{"<shardKey>":MinKey},...{"<shardKey>":MaxKey})

2、手动分发

可以通过关闭均衡器 sh.stopBalancer()启动手动分发。

如果当前正在进行迁移,则此设置在迁移完成之前不会生效。一旦正在运行的迁移完成,均衡器就会停止移动数据。

除非遇到特殊情况,否则,MongoDB应该使用自动分片,而不是手动分片。

自从学习了MongoDB高可用,慢慢的喜欢上了它,之前确实冷落了的更多相关文章

  1. MongoDB 高可用集群副本集+分片搭建

    MongoDB 高可用集群搭建 一.架构概况 192.168.150.129192.168.150.130192.168.150.131 参考文档:https://www.cnblogs.com/va ...

  2. MogoDB(6)--mongoDB高可用和4.0特性

    5.1.MongoDB 用户管理 1.用户管理1.1.添加用户为 testdb 添加 tom 用户 use testdb db.createUser({user:"tom",pwd ...

  3. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)

    绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...

  4. MongoDB高可用集群搭建(主从、分片、路由、安全验证)

    目录 一.环境准备 1.部署图 2.模块介绍 3.服务器准备 二.环境变量 1.准备三台集群 2.安装解压 3.配置环境变量 三.集群搭建 1.新建配置目录 2.修改配置文件 3.分发其他节点 4.批 ...

  5. MongoDB 高可用集群架构简介

    在大数据的时代,传统的关系型数据库要能更高的服务必须要解决高并发读写.海量数据高效存储.高可扩展性和高可用性这些难题.不过就是因为这些问题Nosql诞生了. 转载自严澜的博文——<如何搭建高效的 ...

  6. MongoDB高可用集群配置的方案

    >>高可用集群的解决方案 高可用性即HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性. ...

  7. MongoDB高可用复制集分片集群搭建

    1     逻辑架构 1.1     逻辑架构图 1.2     组件说明 一.mongos(query routers):查询路由,负责client的连接,并把任务分给shards,然后收集结果.一 ...

  8. [MongoDB] 高可用架构方案

    一.缘由: 众所周知,Mongodb是在高速发展期,一些特性架构难免会发生变化.这里就总结下,我目前所知道的Mongodb 的高可用架构都有哪些.目前Mongodb版本3.2. 二.结构介绍: 1.R ...

  9. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一)

    最近在学习的时候,发现微服务架构中,假如只有一个注册中心,那这个注册中心挂了可怎么办,这样的系统,既不安全,稳定性也不好,网上和书上找了一会,发现这个spring cloud早就想到了,并帮我们解决了 ...

  10. MongoDB高可用架构:Replica Sets+Sharding

    MongoDB的sharding解决了海量存储和动态扩容的问题.但是遇到单点故障就显得无能为力了.MongoDB的副本集可以很好的解决单点故障的问题.所以就有了Sharding+Replica Set ...

随机推荐

  1. Silky微服务框架之模块

    模块的定义 Silky是一个包括多个nuget包构成的模块化的框架,每个模块将程序划分为一个个小的结构,在这个结构中有着自己的逻辑代码和自己的作用域,不会影响到其他的结构. 模块类 一般地,一个模块的 ...

  2. 为什么CSS中的calc函数可能会不生效?

    前言 在早期如果想要对某一些样式进行动态计算,绝大多数的做法都是使用JavaScript来进行,当时的CSS在面对这种场景显得有点无能为力.但是,当CSS3中新增了calc函数时,面对这种场景,Jav ...

  3. js函数组合

    纯函数和柯里化容易引起洋葱代码 函数组合可以让我们把细粒度的函数重新组合生成一个新的函数 函数组合并没有减少洋葱代码,只是封装了洋葱代码 函数组合执行顺序从右到左 满足结合律既可以把g和h组合 还可以 ...

  4. @confirguration(proxyBeanMethods = false)的作用,如何选择Full模式和Lite模式

    @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件 public class MyConfig { @Bean ...

  5. pod(八):pod的调度——将 Pod 指派给节点

    目录 一.系统环境 二.前言 三.pod的调度 3.1 pod的调度概述 3.2 pod自动调度 3.2.1 创建3个主机端口为80的pod 3.3 使用nodeName 字段指定pod运行在哪个节点 ...

  6. Xmake v2.7.3 发布,包组件和 C++ 模块增量构建支持

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具. 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时. 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLis ...

  7. KeeWiDB的高性能修炼之路:架构篇

    数据也有冷热之分,你知道吗? 根据访问的频率的高低可将数据分为热数据和冷数据,访问频率高的则为热数据,低为冷数据.如果热.冷数据不区分,一并存储,显然不科学.将冷数据也存储在昂贵的内存中,那么你想,成 ...

  8. centos7 redis6.2.6安装

    1. 源码包下载并解压 wget http://download.redis.io/releases/redis-6.2.6.tar.gz tar -zxvf redis-6.2.6.tar.gz 2 ...

  9. 【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析

    一.前言 上篇的文章中我们介绍了AQS源码中lock方法和unlock方法,这两个方法主要是用来解决并发中互斥的问题,这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法.signal方法 ...

  10. python(牛客)试题解析1 - 简单

    导航: 一.NC103 反转字符串 二.NC141 判断是否为回文字符串 三.NC151 最大公约数 四.NC65 斐波那契数列 五.字符按排序后查看第k个最小的字母 六.数组内取出下标相同的元素求和 ...