ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-01 10:59:33  阅读:147  来源: 互联网

标签:shard id version 文档 routing 分片 主键 路由


扫描关注持续好文

目录

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"

}

图片

可以看到右侧id为1。

  • 自动生成ID

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

 

POST user_info/_doc

{

   "name":"张三",

   "birthdate":"1988-09-01"

}

图片

可以看到右侧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将递增。

图片

可以到右侧_version的值为1

  • 外部版本号

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

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

图片

  • 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都是活跃的,才可以执行这个写操作,主分片和副本都是可用的。

 

扫描关注持续好文

标签:shard,id,version,文档,routing,分片,主键,路由
来源: https://blog.csdn.net/test_test111/article/details/116326266

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有