• 注册
  • 关于作者
    企业认证:趣记站长
    关注 6 粉丝 4 喜欢 9 内容 992
    江西省·南昌市
    聊天 送礼
    • 查看作者
    • MongoDB–副本集基本信息【面试必备】

      副本集的概念

      副本集是一组服务器,其中有一个是主服务器(primary),用于处理客户端请求;还有多个备份服务器(secondary),用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器会自动将其中一个成员升级为新的主服务器。

      副本集特征:
        · N 个节点的集群
        · 任何节点可作为主节点
        · 所有写入操作都在主节点上
        · 自动故障转移
        · 自动恢复
      副本集还有以下几个需要注意的地方:
        1. 最小构成是:primary,secondary,arbiter,一般部署是:primary,2 secondary。
        2. 成员数应该为奇数,如果为偶数的情况下添加arbiter,arbiter不保存数据,只投票。
        3. 最大50 members,但是只能有 7 voting members,其他是non-voting members。

       

      1、数据同步
          Mongo的复制功能是通过oplog实现的oplog包含了主节点的每一次写操作,是主节点的local数据库中的一个固定集合,备份节点通过查询这个集合就可以知道需要进行复制的操作。每个备份节点有自己的oplog,这样每个成员就可以当作同步源提供给其他成员使用。备份节点从当前同步源中获取需要执行的操作,然后在自己的数据集上执行这些操作,最后将这些操作写入自己的oplog。

          如果备份节点挂了,当它重启后,会自动从oplog中最后一个操作开始同步,由于复制操作的过程是先复制数据再写入oplog,所以备份节点有可能在已经同步过的数据上再次执行复制操作。Mongo是这么处理的:将oplog中的同一操作执行多次与只执行一次的效果是一样

          由于oplog大小是固定的,通常它的使用空间的增长速度与系统处理写请求的速率近乎相同。但是有些例外情况:如果单次处理能够影响到多个文档,那么每个受影响的文档都会对应oplog的一条日志。比如执行db.coll.remove()删除了1000000个文档,那么oplog中就会有1000000条操作日志,这样oplog很快就会被填满。

       

      2、仲裁节点
        仲裁者唯一的作用就是选举,不保存数据,也不会为客户端提供服务,它只是为了满足“大部分”的要求

        添加仲裁者的两种方式

          >rs.addArb(“server-5:27017”)

          >rs.add({“_id”:4,”host”:” server-5:27017”,”arbiterOnly”:true})

       

       仲裁的缺点

          比如有三个成员的副本集,其中一个是仲裁节点。当一个数据节点挂了,那么另一个数据节点成为主节点,为了保证数据安全,就需要添加一个新的备份节点,但由于仲裁节点无数据,那么新节点的数据传输只能靠当前的主节点完成。那么它不仅要处理应用程序请求,还要数据复制到备份节点,会造成服务器压力巨大

          所以尽量配置成奇数个数据成员,而不使用仲裁者

       

       

      3、优先级
        优先级表示一个成员渴望成为主节点的程度,取值范围0-100,默认1,0代表永远不能成为主节点(passive member)

        优先级别高的会优先选举为主节点(只要他能得到大部分的支持,并且数据是最新的)

      4、心跳
        每个成员每隔两秒都会向其他成员发送一个心跳请求,用于检查每个成员的状态,知道自己是否符合大多数的条件。

       

      5、回滚
        如果主节点执行了一次写请求后挂了,但是备份节点还没来得及复制这次操作,那么新选举出来的主节点就会漏掉这次写操作。这时就会执行回滚过程。

       

      6、内存管理mmap

        
      mongodb的所有数据实际上是存放在硬盘的,所有要操作的数据通过
      mmap的方式映射到
      内存某个区域内。   然后,
      mongodb就在这块区域里面进行数据修改,避免了零碎的硬盘操作。   至于mmap上的内容flush到硬盘就是操作系统的事情了,所以,如果,mongodb在内存中修改了数据,然后,mmap数据flush到硬盘之前,系统当机了,就会丢失数据了。     mysql,无论数据还是索引都存放在硬盘中。到要使用的时候才交换到内存中。能够处理远超过内存总量的数据。     数据量和性能     
      当物理内存够用的时候,redis》mongodb》mysql     mysql垫底是肯定的。至于,redis为什么比mongodb快。还是跟场景和使用业务有关系的。   大部分情景下,由于mongodb要兼顾它特有的弱表结构下复杂的查询,在很多存取过程上做了妥协。   其实,这里并不想说redis和mongodb的性能怎样,只想说明下随着数据量的增长,redis和mongodb,mysql是怎么变化的。     当物理内存不够用的时候   redis和mongodb都会使用虚拟内存。   实际上如果redis要开始虚拟内存,那很明显要么加内存条,要么你换个数据库了。   但是,mongodb不一样,只要,业务上能保证,冷热数据的读写比,使得热数据在物理内存中,mmap的交换较少。mongodb还是能够保证性能。有人使用mongodb存储了上T的数据。   mysql,mysql根本就不需要担心数据量跟内存下的关系。不过,内存的量跟热数据的关系会极大地影响性能表现。     当物理内存和虚拟内存都不够用的时候   估计除了mysql你没什么好选择了。       其实,从数据存储原理来看,我更倾向于将mongodb归类为硬盘数据库,但是使用了mmap作为加速的手段而已。

             MongoDB应该分配的内存大小最好满足内存大小>索引+热数据+连接占用内存,通过db.stats()命令可查看到当前数据库的索引大小情况
           db.stats()

            下面是公司的MongoDB存储了14亿数据,占1.4T存储空间

      shard1:SECONDARY> db.stats()
      {
          "db" : "database",            // 当前使用的数据库  "collections" : 662,             // 多少张表 "objects" : 1405948982,         // 所有表的多少条数据   -- 14.05亿 "avgObjSize" : 1134.649427176014,    // 平均每条数据大小      "dataSize" : 1595259207065,      // 总数据大小         -- 1.485TB "storageSize" : 768647647232,     // 所有数据占磁盘的大小   -- 715.85G "numExtents" : 0,
          "indexes" : 1098,            // 索引数量 "indexSize" : 173431967744,      // 索引大小          -- 160G "ok" : 1
      }

       

    • 0
    • 0
    • 0
    • 99
    • 单栏布局 侧栏位置: