一.简介

  ES中的索引都进行分片,每个分片都会保存多个副本。这些副本称为复制组,在添加或删除索引时必须同步副本。如果不这样,从不同的副本中读取的索引可能截然不同。保持分片副本同步并从中提供读取的过程被称为数据复制模型。

  ES的数据复制模型基于主备份模型。该模型基于单一复制的副本组,该模型对应的分片充当主分片【primary shard】。其它副本称为备份分片【replica shards】。主分片作为全部索引操作的主入口,它负责验证副本并确保副本的正确性。当主分片接受到一个索引操作请求时,它还负责将操作复制到其它副本。

二.写模型

  ES中的每个索引操作首先使用路由解析为复制组,通常基于索引id。确定复制组后,操作将在内部转发到组的当前主分片。主分片负责验证操作并将其转发到其它副本。由于副本可以脱机,因此不需要将主副本复制到所有副本。相反,ES维护应该接受操作的分片副本列表。此列表称为同步副本,由主节点维护。顾名思义,这些维护好的分片副本的集合,保证已经处理了所有向用户确认的索引操作。主副本负责维护此不变量,因此必须将所有操作复制到此集合中的每个副本上。

  主分片遵守以下基本流程:

    1.验证传入操作并在结构无效时拒绝执行【例如:在数字字段中传入对象】。

    2.在本地执行索引操作,即添加索引或修改索引时,也将验证字段的内容并在需要的时候拒绝执行【例如:关键字值太长,无法在ES中创建索引】。

    3.将操作转发到当前同步副本集中的每个副本。如果有多个副本,则并行执行同步。

    4.一旦所有副本成功同步并响应主服务器,主服务器就会确认成功完成对客户端的请求。

三.失败处理

  ES在索引创建过程中可能会出现一些问题,磁盘可能会损坏,节点可能会断开连接,或者某些配置错误导致复制副本出错,尽管它在服务器上是成功的。这些情况并不多见,但主分片必须做出响应。在主分片本身发生故障的情况下,托管主分片的服务器节点会向主服务器发送相关信息。索引操作将进入等待状态【默认情况下最多等待1分钟】,以便主服务器将其中一个副本提升为新的主分片。然后,索引相关操作将被转发到新的主分片上进行处理。请注意,主服务器还会监控节点的运行状况,并可能决定主动降级主分片。当因网络问题导致拥有主分片的节点断开集群连接时,通常会这样操作。

  一旦在主服务器上成功执行了索引操作,主服务器就必须处理在副本分片上执行索引操作时它可能出现的故障。这可能是由副本上的实际故障或者网络问题导致索引操作无法到达副本【或者阻止副本响应】引起的。所有这些都会具有相同的最终结果:作为同步副本集的一部分的副本错过了即将被确认的索引操作。为了避免违反副本一致性,主分片向主服务器发送消息,请求从副本集中删除有问题的分片。只有在主节点确认删除了这些分片之后,主分片才会确认操作。此外,主服务器还将指示另一个节点复制新的副本分片,以确保副本维持在一个相对合理的数量。

  在将操作转发到副本时,主分片将使用副本来验证它仍然是活动的主分片。如果因网络分区【或者长时间GC】而被隔离,则它可能会在意识到它已被降级之前继续处理传入的索引操作。复制分片将拒绝来自旧主分片的操作。当主分片收到来自副本的拒绝其请求的的响应时,因它不再是主分片,那么它将联系主服务器并将知道自己已被降级。然后它将索引操作路由到新的主分片服务器上。

  当没有副本时,这可能是由于索引配置或仅因为所有副本都已经失败导致的。在这种情况下,主分片处理操作而没有任何外部验证,这看起来有问题。另一方面,主分片本身不能使其它分片失败,除非请求主服务器代表它执行此操作。这意味着主节点知道主分片是唯一的正确副本。因此,我们保证主节点不会将任何其它【过时的】分片副本提升为新的主分片,并且任何索引到主分片的操作都不会丢失。当然,由于此时我们只使用单个数据副本运行,因此物理硬件问题可能导致数据丢失。

四.读模型

  ES中的读取可以是ID非常轻量级的查找,也可以是具有复杂聚合的大量搜索请求,这些聚合会占用非常多的CPU。主备份模型的优点之一是他使所有分片副本保持一致【还未完成的操作除外】。因此,单个同步副本足以提供读取请求。

  当节点收到读取请求时,该节点负责将其转发到保存相关分片的节点上,整理响应并反馈给客户端。我们将该节点称为该请求的协调节点【coordinating node】。基本流程如下:

  1.将读取请求解析为相关分片。请注意,由于大多数搜索将被发送到一个或多个索引,因此它们通常需要从多个分片中读取,每个分片代表数据的不同子集。

  2.从分片复制组中选择每个相关分片的活动副本。这可以是主副本或副本。默认情况下,ES将简单的在分片副本之间循环。

  3.将分片级读取请求发送到所选的副本上。

  4.结合结果并作出回应。请注意,在通过ID查找的情况下,只有一个分片是相关的,此时可以跳出这个流程,直接发送到指定的分片!

五.失败处理

  当分片无法响应读取请求时,协调节点将从同一复制组中选择另一个副本,并将分片级别的搜索请求发送到该副本。重复失败可能导致没有可用的分片副本。在某些情况下,例如:search,ES更愿意快速响应,经管只有部分结果,而不是等获取到全部结果之后才做出反馈。

六.特点

  1.高效读取

    在正常操作下,对每个相关复制组只执行一次读取操作。只有在操作失败的情况下,同一个分片的多个副本才会执行相同的搜索。

  2.读取未确认

    由于主分片在本地然后复制请求发送到其它分片,因此并发读取可能在确认之前就已经看到了更新。

  3.默认2份副本

    此模型可以容错,同时只保留两份副本。这与基于法定数量的系统形成鲜明的对比,其中容错的最小副本数为3。

  4.故障

    4.1 单分片可以降低索引速度,由于主服务器在每个操作期间等待同步副本集中的所有副本,因此单个慢速分片可能会降低整个复制组的同步速度。当然,单个慢速分片也会降低已经路由到这个分片的不幸索引的索引速度。

    4.2 脏读,隔离的主分片可以暴露无法识别的写入。这是因为隔离的主服务器只有在向其它副本发送请求或向主服务器发送请求时才会意识到它已经被隔离了。此时,操作已经索引到主分片中,并且可以通过并发读取来读取索引。ES通过每秒ping一次主服务器【默认】并在没有master知道的情况下拒绝索引操作来减轻这种风险。

ES读写索引内幕分析的更多相关文章

  1. Elasticsearch核心技术(四):索引原理分析

    本文探讨Elasticsearch的数据请求.路由和写入过程的原理,主要涉及ES的分布式存储架构.节点和副本的写入过程.近实时搜索的原因.持久化机制等. 4.1 ES存储架构 我们经常说,看一件事情千 ...

  2. MySQL 索引性能分析概要

    上一篇文章 MySQL 索引设计概要 介绍了影响索引设计的几大因素,包括过滤因子.索引片的宽窄与大小以及匹配列和过滤列.在文章的后半部分介绍了 数据库索引设计与优化 一书中,理想的三星索引的设计流程和 ...

  3. oracle如何进行索引监控分析和优化

    在生产环境.我们会发现: ① 索引表空间 I/O 非常高     ② "db file sequential read" 等待事件也比较高   这种迹象表明.整个数据库系统.索引的 ...

  4. MySQL高级学习笔记(四):索引优化分析

    文章目录 性能下降 SQL慢 执行时间长 等待时间长 查询语句写的烂 查询数据过多 关联了太多的表,太多join 没有利用到索引 单值 复合 服务器调优及各个参数设置(缓冲.线程数等)(不重要DBA的 ...

  5. ES读写数据过程及原理

    ES读写数据过程及原理 倒排索引 首先来了解一下什么是倒排索引 倒排索引,就是建立词语与文档的对应关系(词语在什么文档出现,出现了多少次,在什么位置出现) 搜索的时候,根据搜索关键词,直接在索引中找到 ...

  6. MySQL InnoDB索引介绍以及在线添加索引实例分析

    引言:MySQL之所以能成为经典,不是没有道理的,B+树足矣! 一.索引概念 InnoDB引擎支持三种常见的索引:B+树索引,全文索引和(自适应)哈希索引.B+树索引是传统意义上的索引,构造类似二叉树 ...

  7. SQL Server2005索引碎片分析和解决方法

    SQL Server2005索引碎片分析和解决方法 本文作者(郑贤娴),请您在阅读本文时尊重作者版权. 摘要: SQL Server,为了反应数据的更新,需要维护表上的索引,因而这些索引会形成碎片.根 ...

  8. 161220、使用Spring AOP实现MySQL数据库读写分离案例分析

    一.前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量. 在进行数据库读写分离的时候,我们首先要进行数据库 ...

  9. SQL Server索引进阶第十一篇:索引碎片分析与解决

    相关有关索引碎片的问题,大家应该是听过不少,也许也很多的朋友已经做了与之相关的工作.那我们今天就来看看这个问题. 为了更好的说明这个问题,我们首先来普及一些背景知识. 知识普及 我们都知道,数据库中的 ...

随机推荐

  1. Linux下查看根目录各文件内存占用情况

    一.服务器运行一点时间后各种的项目文件,日志文件,数据库备份登,会越来越多,在linux下可以使用 du 和 df 命令查看. 1.df -h 命令查看整体磁盘使用情况 2. 使用 du -ah -- ...

  2. Visual-Based Autonomous Driving Deployment from a Stochastic and Uncertainty-Aware Perspective

    张宁 Visual-Based Autonomous Driving Deployment from a Stochastic and Uncertainty-Aware Perspective Le ...

  3. iOS - 获取系统时间年月日,阳历(公历)日期转农历的方法

    //获取当前时间 NSDate *now = [NSDate date]; NSLog(@" now date is: %@ ",now); NSCalendar *calenda ...

  4. Linux磁盘空间查看、磁盘被未知资源耗尽

    Linux系统中,当我们使用rm在Linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄, 那么Linux内核还是不会释放这个文件的磁盘空间,最后造成磁盘空间占用100%, ...

  5. java main方法

    1.问题:Java main方法为什么是  public static void main(String[] args)??? 序号 场景 编译 运行 解释 1 public修改为private pr ...

  6. 【视频开发】opencv不能读取MP4格式文件

    用OpenCV对视频进行处理时,不能打开.mp4格式的文件.后来解决办法是用ffmpeg.exe将mp4文件转码为avi文件,然后再进行处理.但是转码过程比较慢.后来查看opencv源代码,发现它也是 ...

  7. socket-02

    # -- coding: utf-8 -- _author__ = "HuaQiang Yan" import socket def handle_request(client): ...

  8. mybatis-3.5.2增删查改

    这玩意没啥技术含量,只不过长时间不用,就显得生疏了.正好今天想读取一个文件写入数据库,平时都是集成环境,都碰不到这些基础东西,看来还是需要时常给自己找活干. 首先建立一个maven工程. next n ...

  9. Python学习之路:通过分片的方式修改列表的技巧(拓展知识)

    一.为列表添加值 用分片的方式可以在列表的头部和尾部添加值 1.在列表的头部添加值 x = [1, 2, 3] #创建列表x x[:0] = [0] #用分片的方式在列表头部添加值 print(x) ...

  10. c++11多线程记录1 -- std::thread

    启动一个线程 话不多说,直接上代码 void func(); int main() { std::thread t(func); //这里就开始启动线程了 t.join(); // 必须调用join或 ...