本文章收录于【Elasticsearch 系列】,将详细的讲解 Elasticsearch 整个大体系,包括但不限于ELK讲解、ES调优、海量数据处理等

一、elasticsearch的写一致性原理

主要是基于consistency来来进行操作的,其语法如下所示

put /index/_doc/id?consistency=quorum

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

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

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

我们在发送任何一个增删改操作的时候,比如说put /index/type/id,都可以带上一个consistency参数,指明我们想要的写一致性是什么

1、quorum机制

quorum机制,写之前必须确保大多数shard都可用,int( (primary + number_of_replicas) / 2 ) + 1,当number_of_replicas>1时才生效

公式:

quroum = int( (primary + number_of_replicas) / 2 ) + 1

举个例子,4个primary shard,number_of_replicas=2,总共有4 + 4 * 2 = 12个shard,得出结果quorum = int( (4 + 2) / 2 ) + 1 = 4。所以,要求12个shard中至少有4个shard是active状态的,才可以执行这个写操作

如果节点数少于quorum数量,可能导致quorum不齐全,进而导致无法执行任何写操作,所以es提供了一种特殊的处理场景,就是说当number_of_replicas>1时才生效,因为假如说,你就一个primary shard,replica=1。此时就2个shard(1 + 1 / 2) + 1 = 2,要求必须有2个shard是活跃的,但是可能就1个node,此时就1个shard是活跃的,如果你不特殊处理的话,导致我们的单节点集群就无法工作..

举例说明如下:

1个primary shard,replica=3,quorum=((1 + 3) / 2) + 1 = 3,要求1个primary shard + 3个replica shard = 4个shard,其中必须有3个shard是要处于active状态的。如果这个时候只有2台机器的话,会出现什么情况呢?

答:

当quorum不齐全时,es会进行等待(wait)默认1分钟,等待期间,期望活跃的shard数量可以增加,最后实在不行,就会timeout,我们其实可以在写操作的时候,加一个timeout参数,比如说put /index/type/id?timeout=30,这个就是说自己去设定quorum不齐全的时候,es的timeout时长,可以缩短,也可以增长

二、搜索结果数据解析

在kibana或者是elasticsearch head 插件中发起查询请求:

GET /_search

其返回的结果如下:

{"took" : 1,"timed_out" : false,"_shards" : {"total" : 3,"successful" : 3,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 34,"relation" : "eq"},"max_score" : null,"hits" : [ ]}
}
  • took:整个搜索请求花费了多少毫秒

  • hits.total.value:本次搜索,返回了几条结果

  • hits.max_score:本次搜索的所有结果中,最大的相关度分数是多少,每一条document对于search的相关度,越相关,_score分数越大,排位越靠前

  • hits.hits:默认查询前10条数据,完整数据,_score降序排序

  • _shards:shards fail的条件(primary和replica全部挂掉),不影响其他shard。默认情况下来说,一个搜索请求,会打到一个index的所有primary shard上去,当然了,每个primary shard都可能会有一个或多个replic shard,所以请求也可以到primary shard的其中一个replica shard上去。

  • shards:total表示打到的全部分片,

  • shards:successful表示打到的分片中查询成功的分片,

  • shards:skipped表示打到的分片中跳过的分片,

  • shards:failed表示打到的分片中查询失败的分片

  • timeout:默认无timeout,latency平衡completeness,手动指定timeout,timeout查询执行机制

三、搜索的timeout机制底层的原理

默认情况下,es的timeout机制是关闭的。比如,如果你的搜索特别慢,每个shard都要花好几分钟才能查询出来所有的数据,那么你的搜索请求也会等待好几分钟才会返回。

但是我们有些应用系统对时间是非常敏感的,比如说电商网站,你不能让用户等5分钟才能等到一次搜索请求的结果。

timeout机制就可以指定每个shard只能在timeout时间范围内,将搜索到的部分数据(也可能是全部数据),直接返回给客户端,而不是等到所有的数据全部搜索出来以后再返回。确保一次搜索请求可以在用户指定的timeout时长内完成,为一些时间敏感的搜索应用提供良好的支持。

语法如下:

GET index/_search?timeout=10ms

四、multi-index和multi-type搜索模式

multi-index和multi-type搜索其实就是告诉你如何一次性搜索多个index和多个type下的数据

  • /_search:所有索引,所有type下的所有数据都搜索出来

  • /index1/_search:指定一个index,搜索其下所有type的数据

  • /index1,index2/_search:同时搜索两个index下的数据

  • /*1,*2/_search:按照通配符去匹配多个索引

  • /index1/type1/_search:搜索一个index下指定的type的数据

  • /_all/type1,type2/_search:_all,可以代表搜索所有index下的指定type的数据

五、分页搜索以及deep paging性能问题

1、如何使用es进行分页搜索

使用es的分页搜索,其核心是通过from和size关键字来实现的

from:从哪个角标开始搜索

size:共搜索多少条

举例说明如下:

假如product索引共有五条数据,其_id分别为12345,当我们进行分页搜索,每页显示两条数据,其返回结果如下

第一页:搜索出_id为4,5的数据

GET product/_search?from=0&size=2

第二页:搜索出_id为3,1的数据

GET product/_search?from=2&size=2

第三页:搜索出_id为2的数据

GET product/_search?from=4&size=2

注意:当数据超过5W条时,不建议from的方式进行分页查询,因为当数据大于5W时使用from分页数据会比较慢,推荐使用scroll游标的方式,在下文中我会详细讲解为啥要怎么做。

2、什么是deep paging性能问题?如何解决该问题呢?

(1)什么是deep paging性能问题

deep paging简单来说,就是搜索的特别深,比如index总共有60000条数据,存放在3个primary shard,每个shard上分20000条,每页是10条数据,这个时候你要搜索到第1000页,实际上要拿到的是10001-10010,该怎么拿呢?

请求首先可能是打到一个不包含这个index的shard的node上,这个node就是一个coordinate node(协调节点),这个coordinate node(协调节点)就会将搜索请求转发到index的三个shard所在的node上去。

要搜索60000条数据中的第1000页,实际上每个shard都要将内部的20000条数据中的第1-10010条数据拿出来,不是10条,是10010条数据,3个shard每个shard都返回10010条数据给coordinate node,coordinate node会收到总共30030条数据,然后根据_score(相关度分数)排序取到所需的那10条数据,其实就是我们要的最后的第1000页的10条数据。

举个例子,现在有100个带编号的乒乓球(从1到100),我现在随机给他们放到三个篮子里面(他们在篮子里面已经排好序了),现在我要取出第10-12个球,那我是不是应该先把各个篮子里面前12个球取出来放到一起(篮子里面的乒乓球是随机放的,无规律),共计36个球,然后汇总进行排序后,在这个结果中取出第10-12个乒乓球!!!

缺点

搜索过深的时候就需要在coordinate node上保存大量的数据,还要进行大量数据的排序,排序之后再取出对应的那一页,所以这个过程,既消耗网络宽带,耗费内存,还消耗cpu。这就是deep paging的性能问题,我们应该尽量避免出现这种deep paging操作。

(2)deep paging性能问题解决方案:使用scroll方式

为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式,这个滚动的方式原理就是通过每次查询后,返回一个scroll_id。根据这个scroll_id 进行下一页的查询。可以把这个scroll_id理解为通常关系型数据库中的游标。但是,这种scroll方式的缺点是不能够进行反复查询,也就是说,只能进行下一页,不能进行上一页。

经过分析,如果数据达到了50000条以上,那么用户基本上是不会考虑每条都去看的,用户需要的是最后对数据分析处理后的结果。而如果小于50000条的时候我们可以使用from size的方式进行分页的查询。那么这种方式存在是为了什么情景呢。应该是为了分批次的检索所有数据。

实现步骤

a、以product索引举例说明。

首先取出前2条,并且得到scroll_id(这里的30s代表的是持续滚动时间,如果过了30秒钟,还没有查询下一页,那么这个scroll_id就会失效)。

GET product/_search?scroll=30s&size=2

返回结果

{"_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAfIdMWekdubkw4eF9TNS1GSW9UY1AxdzEtZw==","took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 5,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "product","_type" : "_doc","_id" : "4","_score" : 1.0,"_source" : {"id" : "4","name" : "罗技 T60 鼠标","desc" : "这是一个无线鼠标 T60","price" : 25,"producer" : "罗技"}},{"_index" : "product","_type" : "_doc","_id" : "5","_score" : 1.0,"_source" : {"id" : "5","name" : "罗技 T501 鼠标","desc" : "new 这是一个无线鼠标","price" : 25,"producer" : "罗技"}}]}
}

b、再次查询下一页

注意,这里查询时不需要指定index,只需要指定scroll_id和本次的持续滚动时间。

想要第几页,循环请求几次就行了,在设置的时间内scroll_id是不会变的

GET /_search/scroll?scroll=30s&scroll_id=DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAfIdMWekdubkw4eF9TNS1GSW9UY1AxdzEtZw==

或者

POST /_search/scroll
{"scroll" : "30s","scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAfIdMWekdubkw4eF9TNS1GSW9UY1AxdzEtZw=="
}

以上两种方式都可以使用,得出的结果也是一样的。

删除对应scroll_id

当我们搜索完毕或者说已经滚动到最后的时候,我们可以选择删除scroll_id

DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAfIdMWekdubkw4eF9TNS1GSW9UY1AxdzEtZw=

删除所有scroll_id

DELETE /_search/scroll/_all

六、query string基础语法

一个是掌握q=field:search content的语法,还有一个是掌握+和-的含义,以下用两个例子来说明

查询product索引中name字段值为罗技的数据

GET product/_search?q=name:罗技

或者

GET product/_search?q=+name:罗技

这两个语法都会把product索引中name字段中包含罗技的所有数据给返回

查询product索引中name字段值不等于罗技的数据

GET product/_search?q=-name:罗技

七、_all metadata的原理和作用

GET /product/_doc/_search?q=罗技

直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。我们在进行中搜索的时候,难道是对document中的每一个field都进行一次搜索吗?其实并不是的,是通过es中的_all元数据进行搜索的。

es中的_all元数据,在建立索引的时候,我们插入一条document,它里面包含了多个field,此时,es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引

后面如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field,其中是包含了所有field的值的

举个例子

{"id":"1","name":"清风纸巾","desc":"这是一个纸巾","price":25,"producer":"清风"
}

"1 清风纸巾 25 清风",作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引

ps:es6.x默认已禁用全文索引(_all),es7.0 彻底废弃_all字段支持,为提升性能默认不再支持全文检索,即7.0之后版本进行该项配置会报错。

详情见官方文档:Breaking changes in 7.0 | Elasticsearch Guide [7.4] | Elastic

< END >

本文章收录于【Elasticsearch 系列】,将详细的讲解 Elasticsearch 整个大体系,包括但不限于ELK讲解、ES调优、海量数据处理等。

14_Elasticsearch 内部原理详细解析(上篇)相关推荐

  1. 15_Elasticsearch 内部原理详细解析(下篇)

    本文章收录于[Elasticsearch 系列],将详细的讲解 Elasticsearch 整个大体系,包括但不限于ELK讲解.ES调优.海量数据处理等 目录 一.什么是mapping 二.精确匹配与 ...

  2. springMVC——SpringMVC原理详细解析

    SpringMVC 谈到这个问题,我们不得不提提之前 Model1 和 Model2 这两个没有 Spring MVC 的时代. ----Model1 时代 : 很多学 Java 后端比较晚的朋友可能 ...

  3. 大剑无锋----SpringMVC原理详细解析

    SpringMVC 谈到这个问题,我们不得不提提之前 Model1 和 Model2 这两个没有 Spring MVC 的时代. ----Model1 时代 : 很多学 Java 后端比较晚的朋友可能 ...

  4. 大数据之Kafka内部原理详细介绍

    目录 前言: 1.Kafka整体结构 2.Consumer与topic关系 3.Kafka消息的分发 4.Consumer的负载均衡 5.kafka文件存储机制 总结: 目录 前言: 本篇文章所介绍的 ...

  5. Kafka 设计架构原理详细解析(超详细图解)

    什么是Kafka? Apache Kafka是一个开放源代码的分布式事件流平台,成千上万的公司使用它来实现高性 能数据管道,流分析,数据集成和关键任务等相关的应用程序. Kafka的应用场景 构造实时 ...

  6. 机械硬盘的工作原理详细解析,以及机械硬盘和固态硬盘的优缺点对比

    硬盘有机械硬盘(HDD)和固态硬盘(SSD)之分.机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,磁头控制器,数据转换器,接口,缓存等几个部分组成. 磁头可沿盘片的半径方向运动,加上 ...

  7. Spark底层原理详细解析(深度好文,建议收藏)

    Spark简介 Apache Spark是用于大规模数据处理的统一分析引擎,基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark部署在大量硬件之上, ...

  8. Spark底层原理详细解析

    Spark简介 Apache Spark是用于大规模数据处理的统一分析引擎,基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark部署在大量硬件之上, ...

  9. 服务器是怎么工作的?(二)——arp工作原理详细解析

    一.什么是ARP协议(Address Resolution Protocol) ARP协议是地址解析协议(Address Resolution Protocol)是通过解析IP地址得到MAC地址的,是 ...

最新文章

  1. 从CPU缓存看缓存的套路
  2. 实用 | 宝藏男孩教你如何魔改 Grafana 主题!
  3. JSP自定义标签_控制标签体是否执行
  4. win7如何打开防火墙某个端口的tcp连接
  5. 重庆大学光电工程学院 贾旭滨 对 “句柄” “指针” 有下面的描述(AfxGetMainWnd GetSafeHwnd() AfxGetAppName() AfxGetThread)...
  6. Nginx 网站定义自己的错误页面
  7. 前端学习(1781):前端调试之security节点讲解
  8. 技术动态 | 知识图谱从哪里来:实体关系抽取的现状与未来
  9. JOptionPane弹框常用实例
  10. 15拆分成3个不同的自然数_一个简单的算法 - 将一个正整数拆分成指定几个正整数的组合...
  11. 购买女装摩托车(踏板车)
  12. python爬虫架构设置_Python爬虫进阶三之Scrapy框架安装配置
  13. java冒泡排序经典代码_15道经典Java算法题(含代码) 建议收藏
  14. 开课吧Java课堂:如何通过接口引用实现接口?
  15. 码农如何写好一封邮件/1
  16. codeforces 并查集_codeforces 892E 可撤销并查集
  17. 用邮件备份手机数据是必然趋势
  18. 计算机软件如何助力科研,研究生必备科研绘图软件,助力科学研究
  19. 如果说《热带风暴》在你身上刮过,你还剩下什么?
  20. 黑鲨helo支持html吗,黑鲨游戏手机Helo发布 张大仙公布私人配置

热门文章

  1. java 最烧脑的继承题_最烧脑的10道智力题!答对5道就是天才!
  2. 【全栈开发实战小草看书之Web端(八)主入口】
  3. 精品课程申报系统实战开发代码全纪录
  4. Habit-基于JFinal+vue+element的后台通用模板项目
  5. HTML5期末大作业:个人网站设计——彭于晏明星(15页)带特效 带登录 带轮播 带音乐 HTML+CSS+JavaScript 大学生毕设网页设计源码HTML (1)
  6. 亚马逊重组游戏开发部门:数个未发布游戏被“扼杀”;台积电明年开始为苹果iPhone生产5nm处理器……...
  7. 设计模式--谈谈IoC、DI、DIP、IoC Container、控制反转与依赖注入
  8. 软件构造课程心得——软件构造实验二(Lab2)
  9. android 获取wifi信号强度,获取wifi当前手机连接的wifi信息以及信号强度
  10. 拜托,不要再问我Git如何回滚代码