本文旨在对比Elasticsearch和MongoDB高可用和分片的实现机制。

Elasticsearch

ES天生就是分布式的,那她又是如何做到天生分布式的?

通过ES官方指南我们可以知道:

一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

当一个节点被选举成为主节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以它同时也成为了主节点。

作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。

Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。

一个分片可以是主分片或者副本分片。 索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。

我们在创建一个索引的时候,可以定义其主分片数量和副本分片数量:

PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}

如果主分片和副本分片都集中在一个节点上,那是没办法做到高可用的。ES的集群监控状态会返回yellow。因此,我们需要启动更多的节点来承载副本分片。

此时,如果再增加一个节点至集群,Node 1 和 Node 2 上各有一个分片被迁移到了新的 Node 3 节点,现在每个节点上都拥有2个分片,而不是之前的3个。

如果NODE1宕机了,ES会选举一个新的主节点,并将R1、R2分片提升为主分片。以此来达到高可用的目的。

现在我们大致知道了ES的高可用和分片的方式,但是几个细节任然需要继续深入:

  • ES是通过hash(文档ID) % 主分片数来确认分片的位置的,因为ES的主分片数量不可变
  • 主分片在每次文档的写操作执行前,都会确认大多数副本分片处于存活状态。我们可以通过配置参数调整为只要主分片状态 ok 就允许执行写操作或必须要主分片和所有副本分片的状态没问题才允许执行写操作
  • 跨分片查询时,客户端发送一个 search 请求到 Node 3 , Node 3 会创建一个大小为 from + size 的空优先队列。

    Node 3 将查询请求转发到索引的每个主分片或副本分片中。每个分片在本地执行查询并添加结果到大小为 from + size 的本地有序优先队列中。

    每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点,也就是 Node 3 ,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
  • Elasticsearch 增加了一个 translog ,或者叫事务日志,在每一次对 Elasticsearch 进行操作时均进行了日志记录。一个文档被索引之后,就会被添加到内存缓冲区,并且 追加到了 translog。translog 提供所有还没有被刷到磁盘的操作的一个持久化纪录。当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点去恢复已知的段,并且会重放 translog 中所有在最后一次提交后发生的变更操作。
  • Elasticsearch使用了类bully的算法来实现选主。对所有可以成为master的节点根据nodeId排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。

    如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举。

MongoDB

MongoDB通过复制集(Replica Set)来实现高可用。

复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。

复制还允许您从硬件故障和服务中断中恢复数据。



主节点负责所有的写操作,从节点同步主节点的数据。仲裁节点不维护数据集,只参与选主过程。

MongoDB是通过oplog来实现复制集间的数据同步。当主节点完成写操作后,从节点会检查自己的local数据上的oplog集合,找出最近一条记录的时间戳。然后查询主节点上的oplog集合,找出大于此时间戳的记录。最后将这些oplog查到到本地集合中并执行oplog中的操作。

MongoDB实例每个两秒就会向其他成员发送一个心跳包来判断其他成员的存活状态。如果复制集的主节点不可用了,那么系统就会触发一次选主。

选主需要时间,在选主的过程中,复制集是没有主节点的,所有的成员都变成只读状态。

MongoDB也是采用Bully算法选主,选主时,有资格成为主节点的副本节点就会向其他节点发起一个选举,希望别的节点选择其作为主节点。若赞成票过半则设置自己为主节点。有反对票时,保持自己为从节点。

复制集中的其他成员在收到选主请求时,会判断发起节点的数据版本是否过低。如过低则投反对票。

MongoDB分片时,需要引入路由服务器(mongos)和配置服务器(config servers)。配置服务器是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。路由服务器起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息。

MongoDB通过分片键(Shard Keys)对集合进行划分。每个分片集合只能有一个分片键,分片后分片键不可修改。目前支持两种分片策略,范围分片和hash分片。一旦分片键选择完成,数据就以 数据块(chunk) 为单位(默认64MB)根据分片键分散到后端1或多个分片上。mongos记录每个块中的数据量,达到某个阈值,就检查是否需要拆分块。如拆分块,mongos更新config server的块元数据,config server诞生新块,修改旧块的范围(拆分点)。

查询时,查询请求不包含shard key,则mongos必须将查询分发到所有的shard,然后合并查询结果返回给客户端。查询请求包含shard key,则直接根据shard key计算出需要查询的chunk,向对应的shard发送查询请求。

插入时,必须包含shard key,mongos根据shard key算出文档应该存储到哪个chunk,然后将写请求发送到chunk所在的shard。更新、删除请求的查询条件必须包含shard key或者_id,如果是包含shard key,则直接路由到指定的chunk,如果只包含_id,则需将请求发送至所有的shard。

参考文献

https://www.elastic.co/guide/en/elasticsearch/guide/master/distributed-cluster.html

https://docs.mongodb.com/manual/core/replica-set-elections/

https://docs.mongodb.com/manual/sharding/

Elasticsearch和MongoDB分片及高可用对比的更多相关文章

  1. MongoDB 3.4 高可用集群搭建(二)replica set 副本集

    转自:http://www.lanceyan.com/tech/mongodb/mongodb_repset1.html 在上一篇文章<MongoDB 3.4 高可用集群搭建(一):主从模式&g ...

  2. mongodb副本集高可用架构

    一.简介 Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点. Mongodb Driver(客户端)的所有数据都写入Primary,Sec ...

  3. MongoDB复制集高可用选举机制(三)

    复制集高可用选举机制 在上一章介绍了MongoDB的架构,复制集的架构直接影响着故障切换时的结果.为了能够有效的故障切换,请确保至少有一个节点能够顺利升职为主节点.保证在拥有核心业务系统的数据中心中拥 ...

  4. MongoDB三节点高可用模式安装

    设备: 三个1G.20G.1核的虚拟机,系统是SentOS7 min 清除原始自数据目录: rm -fr /home/mongosingle/ 创建目录: mkdir -p /home/mongosi ...

  5. 生产环境下搭建mongodb复制集高可用环境(python)

    环境描述:有三台ubuntu服务器,,每台服务器上已经有mongodb实例.创建3个mongo2.4的新实例,分别作为三个复制集节点,同时保证了当前单节点环境的稳定 3台服务器都已经有单个mongo实 ...

  6. Elasticsearch和MongoDB

    Elasticsearch和MongoDB分片及高可用对比 本文旨在对比Elasticsearch和MongoDB高可用和分片的实现机制. Elasticsearch ES天生就是分布式的,那她又是如 ...

  7. 搭建高可用mongodb集群—— 分片

    从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大? 数据压力大到机器支撑不了的时候能否做到自动扩展? 在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出 ...

  8. TiDB和MongoDB分片集群架构比较

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近阅读了TiDB源码的说明文档,跟MongoDB的分片集群做了下简单对比. 首先展示TiDB的整体架构 M ...

  9. ELK架构下利用Kafka Group实现Logstash的高可用

    系统运维的过程中,每一个细节都值得我们关注 下图为我们的基本日志处理架构 所有日志由Rsyslog或者Filebeat收集,然后传输给Kafka,Logstash作为Consumer消费Kafka里边 ...

随机推荐

  1. SharpGL(46)用Billboard绘制头顶文字

    CSharpGL(46)用Billboard绘制头顶文字 本文介绍CSharpGL用Billboard绘制头顶文字的方法.效果如下图所示. 下载 CSharpGL已在GitHub开源,欢迎对OpenG ...

  2. Java多线程与并发模型之锁

    这是一篇总结Java多线程开发的长文.文章是从Java创建之初就存在的synchronized关键字引入,对Java多线程和并发模型进行了探讨.希望通过此篇内容的解读能帮助Java开发者更好的理清Ja ...

  3. python进阶------进程线程(五)

    Python中的IO模型 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别 ...

  4. Vue学习笔记-Vue基础入门

    此篇文章是本人在学习Vue是做的部分笔记的一个整理,内容不是很全面,希望能对阅读文章的同学有点帮助. 什么是Vue? Vue.js (读音 /vjuː/,类似于 view) 是一套构建用户界面的渐进式 ...

  5. 【转】使用PowerDesigner的建模创建升级管理数据库

    使用PowerDesigner的建模创建升级管理数据库 PowerDesigner是一种著名的CASE建摸工具,最开始为数据库建模设计,即物理模型(Physical Data Model)用于生成数据 ...

  6. javascript 的继承

    我们的JavaScript比较特别了,主要通过原型链实现继承的. 下面介绍各种实现继承的方式:原型链继承,借用构造函数,组合继承,原型式继承,寄生式继承,寄生组合式继承. 二.实现继承方式 1.原型链 ...

  7. Centos下mongodb的安装与配置

    安装MongoDB的方法有很多种,可以源代码安装,在Centos也可以用yum源安装的方法. 1.准备工作 运行yum命令查看MongoDB的包信息 yum info mongodb-org (提示没 ...

  8. 那些年我们写js烦的不疼不痒的错误

    1.Js 字符变量不加双/单引号. 列如:var strJsonInfo = '@Html.Raw(ViewBag.JsonInfo)'; 2.js 对象初始化器,最后一个属性值加逗号. 例如:var ...

  9. 使用OpenCV进行网络摄像头的图像采集及视频存储

    rtspURL格式 rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream 1) username ...

  10. Java IO(2)阻塞式输入输出(BIO)的字节流与字符流

    在上文中<Java IO(1)基础知识——字节与字符>了解到了什么是字节和字符,主要是为了对Java IO中有关字节流和字符流有一个更好的了解. 本文所述的输出输出指的是Java中传统的I ...