data replication model

本节首先简要介绍Elasticsearch的data replication model,然后详细描述以下CRUD api:

1、读写文档(Reading and Writing documents)

1.1 介绍(Introduction)

在es中的每个索引都会被划分成一组分片,并且每个分片都有多个副本。这些副本是一组副本分片并且当删除或者添加文档的时候必须同步到各个副本。如果我们没有做到这点,从不同副本中读取的数据会不一致。我们把分片副本同步和使其能读取的过程,叫做data replication model.

es 数据分发模型基于primary-backup模型,并且在Microsoft Research 的PacificA paper中描述得非常好。这个模型从主分片获取副本。我们把非主分片的分片叫做副本分片。主分片是所有索引操作的入口。它负责验证索引操作是否有效。一旦主分片接受一个索引操作,主分片的副本分片也会接受该操作。

这章节的目的是,讲述 Elasticsearch replication model的高层概念和讨论读写操作之间隐含的多种交互。

1.2 基本的写模型(Basic write model)

每个索引操作首先会使用routing参数解析到replication group(分片组,包含主分片和副本分片),通常基于文档ID。一旦确定 replication group ,就会内部地转发该操作 到分片组的主分片中。主分片负责验证操作和转发它到其他副本分片。es维护一个可以接收该操作的分片副本列表(shard copies 包含主分片和副本分片)。这个列表叫做in-sync copies并由master节点维护。正如名字那样,担保这些分片都会处理所有的索引和删除操作,这些操作都会经过用户确认。主分片负责维护不变性(各个副本保持一致),因此必须副本这些操作到列表中的每个副本。

主分片的处理过程:

  1. 验证操作,如果它的结构有错就拒绝该操作(例如,对object字段指定一个数字值)
  2. 在本地执行操作。即索引或删除相关文档。这也会验证字段的内容,如果不通过就拒绝操作(例如,字段串的长度超出Lucene的定义的长度)
  3. 转发该操作到当前in-sync 副本组的所有副本分片。如果有多个副本分片,会并行转发。
  4. 一旦所有的副本分片成功执行该操作就会返回给主分片,主分片把请求的成功执行的信息返回给用户。

1.3 错误处理(Failure handling)

索引期间会发送很多错误,例如硬盘坏了,节点丢失和其他节点的连接,或者某些配置错误会导致不能在副本分片上执行某个操作,尽管该操作成功地在主分片上执行。虽然这是罕见的,但是主分片必须汇报这些错误信息。

对于主分片自身错误的情况,它所在的节点会发送一个消息到master节点。这个索引操作会等待(默认最多一分钟)master节点提升一个副本分片为主分片。这个操作会被转发给新的主分片处理。注意master同意会监控节点的健康,并且可能会主动降级主分片。这通常发生在主分片所在的节点和集群失去联系的时候。查看这里连接更多细节。

一旦操作在主分片执行成功,主分片必须处理可能在副本分片上发生的错误。错误发生的原因可能是,在副本分片上执行操作时发生的错误,也可能是因为网络阻塞导致主分片无法转发操作到副本分片,或者副本分片无法返回结果给主分片。这些错误都会导致相同的结果:in-sync replica set中的一个分片丢失一个即将要确认的操作。为了避免出现不一致,主分片会发送一条消息到master节点,要求它把有问题的分片从in-sync replica set中移除。 一旦master确认移除了该分片,主分片就会确认这次操作。注意master也会指导另一个节点建立一个新的分片副本,以便把系统恢复成健康状态。

当转发请求到副本分片,主分片会使用副本分片验证它是否仍是是一个活跃的主分片。如果主分片因为网络原因被孤立了,在它被降级之前,他会继续处理索引操作。来自陈旧的主分片的操作将会被副本分片拒绝。当主分片接收到来自副本分片的拒绝响应时主分片将不会再访问master,并且知道自己已经被取代了。这个操作会被路由到新的主分片。

如果没有副本分片会发生什么?

索引配置副本分片为0,或者所有的副本分片不可用的时候会发生这种情况。这时候在没有任何外部验证的情况下处理该操作,可能会导致问题。另一方面,主分片不能使它分片失效,但它会请求master使它们失效 。这意味着,master知道只有主分片才是一个可用的副本。因此我们担保master不会提升任何其他分片副本(过时)为主分片,并且主分片上的操作也不会丢失。

1.4 基本的读模型(Basic read model)

通过id查找是非常轻量的,一个复杂的查询并且需要进行聚合预算的请求需要消耗大量cpu资源。 primary-backup model 一个好处是保证所有的分片副本都是一致(正在执行的操作例外)。因此,单个 in-sync 副本也可以服务请求。

当一个读请求被节点接收,这个节点负责转发它到其他涉及相关分片的节点,并整理响应结果,发送给客户端。我们叫这个节点为这个请求的协调节点。基本流程如下:

  1. 把读请求发送到相关分片。注意,因为大多数搜索都会发送到一个或多个索引,通常需要从多个分片读取,每个分片都保存这数据的一部分。
  2. 从shard replication group选择一个相关分片的活跃副本。它可以是一个主分片或者副本分片。默认,es会简单地循环遍历这些分片。
  3. 发送一个分片level的读请求到被选中的副本
  4. 合并结果和响应客户端。注意对与通过id查找的get请求 ,会跳过这个步骤,因为这种请求只有一个相关的分片。

1.5 错误处理(Failure handling)

当分片不能响应一个读请求,协调节点会从replication group中选择另一个副本,并发送请求到该副本代替不可用的副本。没有可用的分片副本会导致重复的错误。某些情况下,es更喜欢尽早响应,即使只有部分的结果,而不是等待问题解决(你可以在响应结果的_shards字段,检查本次结果是完整的还是部分的)

1.6 一些简单的暗示(A few simple implications)

读和写的流程决定es行为。而且,因为读和写请求可以并发执行,这两个流程会相互交替。因此一些固有的暗示:

Efficient reads

正常情况每个读操作仅仅在每个相关的分片执行一次。仅仅在出现错误的情况下,需要对同一个分片的多个副本执行操作。

Read unacknowledged

因为索引操作首先在主分片执行,有可能在主分片还没确认的情况下,同时会发送一个读请求。

Two copies by default

当仅仅维护2个副本时,这个模型可以具备容错能力。这与基于法定数量的系统形成对比,其中容错的最小副本数为3。

1.7 错误(Failures)

A single shard can slow down indexing(某个分片可能会减慢整体索引的速度)

因为每次操作,主分片都会等待所有(in-sync copies)中的副本分片,如果其中有一个分片很慢,将会导致整个操作变慢。这是为了上述所说的一致性,需要付出的代价。当然,也会减慢搜索速度。

Dirty reads(脏读)

一个孤立的主分片能够暴露那些没有确认的写操作。因为仅仅当它发送请求到它的副本分片或者访问master的时候,才意识到它被孤立了。在这一刻,这个操作已经写到了主分片,并且同时可以被读取。es 通过每秒(默认)ping一次master降低这种错误,并且,如果联系不上master,会拒绝索引操作。

1.8 冰山一角(The Tip of the Iceberg)

本文档提供一个关于es如何处理数据的高层概念。当然,在底层还有很多很多细节。例如 primary terms,集群状态和master选举等都可以在保持系统正常运行方面发挥作用。本文档也未覆盖已知或重要的bug(包括关闭的和开启的)。我们认识到GitHub很难跟上。为了帮助人们掌控这些,我们在我们的网站上维护了一个专用的页面。我们强烈建议你阅读它。

2、Rest High Level Client

建立SpringBoot项目,加入es依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wtc.elasticsearch</groupId>
    <artifactId>java_high_rest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>java_high_rest</name>
    <description>官方API</description>

    <properties>
        <java.version>1.8</java.version>
        <!--
            必须在 properties 中指定版本 否则在SpringBoot 2.1+中会使用默认的6.4
            详见:https://discuss.elastic.co/t/org-springframework-web-util-nestedservletexception-handler-dispatch-failed-nested-exception-is-java-lang-nosuchmethoderror-org-elasticsearch-action-index-indexrequest-ifseqno-j/176627
        -->
        <elasticsearch.version>6.7.1</elasticsearch.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

elasticsearch6.7 05. Document APIs(1)data replication model的更多相关文章

  1. elasticsearch6.7 05. Document APIs(2)Index API

    Single document APIs Index API Get API Delete API Update API Multi-document APIs Multi Get API Bulk ...

  2. elasticsearch6.7 05. Document APIs(6)UPDATE API

    5. UPDATE API 更新操作可以使用脚本来更新.更新的时候会先从索引中获取文档数据(在每个分片中的集合),然后运行脚本(使用可选的脚本语言和参数),再果进行索引(还允许删除或忽略该操作).它使 ...

  3. elasticsearch6.7 05. Document APIs(9)Bulk API

    8.Bulk API 可以把多个index或delete操作放在单个bulk API中执行.这样可以极大地提高索引速度. /_bulkAPI使用如下的JSON结构: action_and_meta_d ...

  4. elasticsearch6.7 05. Document APIs(8)Multi Get API

    7.Multi Get API(Multi Get API) multi GET API 允许你一次性获取多个文档,你需要指定docs数组,其中包含了所有你需要查询的文档,每个查询结构至少包含索引,类 ...

  5. elasticsearch6.7 05. Document APIs(4)Delete API

    3.Delete API delete API 可以让你删除一个特定id的文档,下面例子删除twitter索引中_doc类型.id为1的文档: DELETE /twitter/_doc/1 返回结果: ...

  6. elasticsearch6.7 05. Document APIs(3)GET API

    2.GET API get API 可以通过文档id从索引中获取json格式的文档,以下示例从twitter索引中获取type为_doc,id值为0为的JSON文档: GET twitter/_doc ...

  7. elasticsearch6.7 05. Document APIs(10)Reindex API

    9.REINDEX API Reindex要求为源索引中的所有文档启用_source. reindex 不会配置目标索引,不会复制源索引的设置.你需要在reindex之前先指定mapping,分片数量 ...

  8. elasticsearch6.7 05. Document APIs(5)Delete By Query API

    4.Delete By Query API _delete_by_query API可以删除某个匹配条件的文档: POST twitter/_delete_by_query { "query ...

  9. elasticsearch6.7 05. Document APIs(7)Update By Query API

    6.Update By Query API _update_by_query 接口可以在不改变 source 的情况下对 index 中的每个文档进行更新.这对于获取新属性或其他联机映射更改很有用.以 ...

随机推荐

  1. 程序中使用now()函数对性能的影响

    这两天从某平台的慢查询日志中发现了一些很简单的,原本执行时间在0.01-0.03s的SQL,慢查询日志中记录的执行时间在2s左右. 排查后发现,表设计及索引建设均没有什么问题.但是SQL语句中使用了n ...

  2. 内置函数_zip()

    zip() zip()函数用来把多个可迭代对象中的元素压缩到一起,返回一个可迭代的zip对象,其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组,最终结果中包含的元素个数取决于所有参数序列或 ...

  3. array_flip()函数

    array_flip() 函数用于反转/交换数组中所有的键名以及它们关联的键值. array_flip() 函数返回一个反转后的数组,如果同一值出现了多次,则最后一个键名将作为它的值,所有其他的键名都 ...

  4. java web 测试

    1.功能测试 bugfree mantis 2.性能测试:loadrunner 3.安全测试: burpsuite

  5. git 命令(基础篇)的本质理解

    主要命令 1. 提交,git commit 本质:创建一个节点(node),标志了当前位置(node)与以前的node存在不同之处,如下图中的 c0 <-- c1 <-- c2 等等 图中 ...

  6. html canvas 的宽高以及像素限制

    canvas 宽高设置不合适的话,是画不出东西出来的 https://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-elem ...

  7. Javascript高级编程学习笔记(6)—— 流程控制语句

    话不多说,我们直接开始进入今天的主题 流程控制语句 首先什么是流程控制语句呢? 顾名思义,就是控制流程的语句. 在JS中语句定义了ECMAScript中的主要语法,让我们可以使用一系列的关键字来完成指 ...

  8. Data - Spark简介

    Spark简介 Spark是基于内存计算的大数据并行计算框架,可用于构建大型的.低延迟的数据分析应用程序. HomePage:http://spark.apache.org/ GitHub:https ...

  9. HW2017笔试编程题

    一.写一个转换字符串的函数 1.题目描述 将输入字符串中下标为偶数的字符连成一个新的字符串输出,需要注意两点: (1)如果输入字符串的长度超过20,则转换失败,返回“ERROR!”字符串: (2)输入 ...

  10. Jenkins配置AD域认证

    Jenkins配置AD域认证 #检测域控地址ping youad.com指向的IP #如果不是实际域控ip地址,则修改hosts vi /etc/hosts #192.168.100.100替换为实际 ...