Elasticsearch7.12主键/version/routing/consistency写一致

Elasticsearch7.12主键/version/routing/consistency写一致
扫描关注持续好文

目录

ID生成介绍

VERSION介绍

外部版本号

文档路由原理

默认路由机制

自定义路由

文档写一致性

quorum

all


ID生成介绍

    映射也就是mapping,用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、分词等属性。自动生成id,和手动生成id的适应场景:

  • 手动指定ID

    从某些其他的系统中,导入一些数据到es时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为es中document的id。比如说,我们现在在开发一个电商网站,做搜索功能。这个时候,数据首先会在网站系统或者IT系统内部的数据库中,会先有一份数据,此时需要把数据导入es这时比较适合用库里的id。

POST user_info/_doc/1

{

   "name":"张三",

   "birthdate":"1988-09-01"

}

Elasticsearch7.12主键/version/routing/consistency写一致

可以看到右侧id为1。

  • 自动生成ID

    如果数据直接存入es,那么这个时候,可能就不太适合说手动指定document id的形式了,因为你也不知道id应该是什么,此时可以采取下面要讲解的让es自动生成id的方式。

 

POST user_info/_doc

{

   "name":"张三",

   "birthdate":"1988-09-01"

}

Elasticsearch7.12主键/version/routing/consistency写一致

可以看到右侧id为 JWCVJXkB-WsrqdxVu0fQ

VERSION介绍

      es在创建索引的过程中会为每个文档创建一个version变量,这个变量是用于解决冲突用的。es在更新文档时是一次读取原生文档,做修改然后重新索引整个文档,最先请求将成功,此时文档的versinon会加1,如果在同一时刻其他人也修改了该文档,他们的修改将丢失。在数据库领域中,有两种方法通常备用来确保并发更新时变更不会丢失:

    1、悲观并发控制

        这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。

    2、乐观并发控制

        Elasticsearch 中使用的这种方法,它假定冲突是不可能发生的,所以不会阻塞正在尝试的操作。然而,如果源数据在读写当中被修改version与原来的值不一致,更新将会失败。应用程序接下来将决定该如何解决冲突。可以设置重试更新次数、或者将相关情况报告给用户即抛出异常。

  • 内部版本号

      使用内部版本号是要求指定的version字段和当前的version号相同,,当文档被修改时版本号递增。ElasticSearch使用这个_version确保变更以正确的顺序得到执行。如果旧版本的文档在新版本之后到达,它可以被简单的忽略。我们可以用_version来确保应用中相互冲突的变更不会导致数据的丢失。我们通过指定想要修改文档的_version来达到这个目的。如果该版本不是当前版本号,我们请求将失败

POST /user_info/user_info?version=1

version可以不用写,默认从1开始,每修改一次version将递增。

Elasticsearch7.12主键/version/routing/consistency写一致

可以到右侧_version的值为1

  • 外部版本号

     version_type:外部版本号校验类型,有两种:external(默认,外部版本号必须要大于内部版本号),external_gte(外部版本号大于等于内部版本号),如果请求成功,外部版本号作为文档新的version号进行存储。

POST /user_info/user_info?version=5&version_type=external

Elasticsearch7.12主键/version/routing/consistency写一致

  • op_type 

    es默认添加数据时es的ID相同会更新,不同会创建。op_type 参数可以指定为create来强制执行创建操作,此操作是不存在则创建,如果指定id的文档已经存在,则此操作失败;也可以通过_create指定此值。

op_type=create 或_create

文档路由原理

      Elasticsearch中每个index由多个shard组成,7.0之后,默认主分片是1个可修改。shard分为主分片和副本分片,在文档写入时,会根据_routing来计算(OperationRouting类)得出文档要写入哪个分片。这里的写入请求只会写主分片,当主分片写入成功后,会同时把写入请求发送给所有的副本分片,当副本分片写入成功后,会传回返回信息给主分片,主分片得到所有副本分片的返回信息后,再返回给客户端。

  • 默认路由机制

     保存文档时,文档会通过一个公式路由到一个索引中的一个分片上。默认的公式如下:shard_num = hash(_routing) % num_primary_shards

默认情况下时通过_routing字段进行路由的,这个字段的值默认时等于文档_id字段的。

routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了

 

  • 自定义路由

   自定义路由比较简单,如下,一旦设置routing参数将替换_id字段路由文档。

POST my_index/my_type/1?routing=user1&refresh=true

{

  "title": "This is a document"

}

GET my_index/my_type/1?routing=user1

如果不设置路由,每个一个查询都会去搜索索引中的全部分片,所以自定义路由可以提高搜索性能(只搜索路由指定的分片)。在索引的时候只能指定一个路由,但搜索的时候可以指定一个或多个路由,这样可以大大提高搜索的灵魂性,如下:

POST my_index/_search?routing=user1,user2

{

  "query": {

    "match": {

      "title": "document"

    }

  }

}

文档写一致性

      es的一个操作请求比如:增删改操作时put /index/type/id,都可以带上一个consistency参数,指明我们想要的写一致性是什么。

POST  /index/_doc/id?consistency=quorum

    one:要求我们这个写操作,只要有一个primary shard是active活跃可用的,就可以执行

    all:要求我们这个写操作,必须所有的primary shard和replica shard都是活跃的,才可以执行这个写操作

    quorum:默认的值,要求所有的shard中,必须是大部分的shard都是活跃的,可用的,才可以执行这个写操作

  • quorum

     在写之前必须确保大多数shard都可用,int(primary + number_of_replicas)/2)+1,当number_of_replicas>1时才生效quorum = int( (primary + number_of_replicas) / 2 ) + 1举个例子,3个primary shard,number_of_replicas=1,总共有3 + 3 * 1 = 6个shard,quorum = int( (3 + 1) / 2 ) + 1 = 3,所以要求6个shard中至少有3个shard是active状态的,才可以执行这个写操作,如果节点数少于quorum数量,可能导致quorum不齐全,进而导致无法执行任何写操作。3个primary shard,replica=1,要求至少3个shard是active,3个shard按照之前学习的shard&replica机制,必须在不同的节点上,如果说只有2台机器的话,是不是有可能出现说,3个shard都没法分配齐全,此时就可能会出现写操作无法执行的情况。

    es提供了一种特殊的处理场景,就是说当number_of_replicas>1时才生效,因为假如说,你就一个primary shard,replica=1,此时就2个shard((1 + 1) / 2) + 1 = 2,要求必须有2个shard是活跃的,但是可能就1个node,此时就1个shard是活跃的,如果你不特殊处理的话,导致我们的单节点集群就无法工作,quorum不齐全时,wait,默认1分钟,timeout,100,30s, 等待期间,期望活跃的shard数量可以增加,最后实在不行,就会timeout我们其实可以在写操作的时候,加一个timeout参数,比如说put /index/type/id?timeout=30,这个就是说自己去设定quorum不齐全的时候,es的timeout时长,可以缩短,也可以增长。

  • one

要求我们这个写操作,只要有一个primary shard是active活跃可用的,就可以执行。

  • all

   要求我们这个写操作,必须所有的primary shard和replica shard都是活跃的,才可以执行这个写操作,主分片和副本都是可用的。

 

Elasticsearch7.12主键/version/routing/consistency写一致
扫描关注持续好文
上一篇:Istio Routing极简教程


下一篇:HCNP Routing&Switching之OSPF虚连接