Elasticsearch系列---补充几个知识点

概要

bulk api有趣的json格式

前面《简单入门实战》一节中,有介绍bulk的使用示例,大家一定很奇怪,还有这么有趣的JSON格式,必须严格照他的换行来做,我想把JSON搞得美观可读性好一点,居然给我报错!

{"action": {"meta"}}\n
{"data"}\n
{"action": {"meta"}}\n
{"data"}\n

它为什么要这样规定?

我们想想bulk设计的初衷,批处理的执行效率肯定是第一优先级,此时效率>可读性,如果我们允许随意换行,用标准格式的JSON串,会有什么区别?

如果是标准格式的JSON串,处理流程一般会是这样:

  1. 将整个json数组全部加载,解析为JSONArray对象,这时内存中同时有json串文本和JSONArray对象。
  2. 循环遍历JSONArray对象,获取每个请求中的document进行路由信息。
  3. 把路由到同一个shard的请求合在一组,开辟一个新的请求数组,将JSONObject放在数组里。
  4. 序列化请求数组,发送到对应的节点上去。
  5. 收集各节点的响应,汇总后返回给Coordinate Node。
  6. Coordinate Node收到所有的汇总信息,返回给客户端。

这种方式唯一的缺点就是占用内存多,一份json串,解析为JSONArray对象,内存占用翻番,bulk里面多则几千条请求,如果JSON报文大一点,这内存耗费不是开玩笑的,如果bulk占用的内存过多,就可能会挤压其他请求的内存使用量,如搜索请求、数据分析请求等,整体性能会急速下降,严重的情况可能会触发Full GC,会导致整个JVM工作线程暂停。

再看看现有的格式定义:除了delete操作占一行,其他操作都是占两行的,ES收到bulk请求时,就可以简单的按行进行切割,也不用转成json对象了,切割完的JSON读取里面的meta信息,直接路由到相应的shard,收集完响应返回即可。
这样的好处切割逻辑更简单,都是处理小json字符串,内存快拿快放,整个ES避免对内存的大块占用,尽可能保证性能。

增删改文档内部原理

增删改的过程整体与查询文档过程一致,只是多了一个数据同步的步骤,整个过程如图所示:

相似的步骤不赘述。
步骤3的前提是primary shard操作成功,异步请求,所有的replica都返回成功后,node2响应操作成功的消息给Coordinate Node,最后Coordinate Node向客户端返回成功消息,此时所有的primary shard和replica shard均已完成数据同步,数据是一致的。

查询文档内部原理

当我们使用客户端(Java或Restful API)向Elasticsearch搜索文档数据时,可以向任意一个node发送请求,此时接受请求的node就是Coordinate Node,整个过程如图所示:

  1. Coordinate Node接收到请求后,根据_id信息或routing信息,确定该document的路由信息,即在哪个shard里,比如说P0。
  2. Coordinate Node转发请求,使用round-robin随机轮询算法 ,在primary shard或replica shard随机挑一个,让读请求负载均衡,如node-3的R0-1
  3. 接收请求的node-3搜索完成后,响应结果给Coordinate Node。
  4. Coordinate Node将响应结果返回给客户端。

注意一个问题,如果document还在建立索引过程中,可能只有primary shard有,任何一个replica shard都没有,此时可能会无法读取到document,但是等document完成索引建立后,primary shard和replica shard就都有了,这个时间间隔,大概1秒左右。

写一致性要求

Elasticsearch在尝试执行一个写操作时,可以带上consistency参数,声明我们的写一致性的级别,正确地使用这个级别,为了避免因分区故障执行写操作,导致数据不一致,这个参数有三个值供选择:

  • one:只要有一个primary shard是active活跃可用的,就可以执行写操作
  • all:必须所有的primary shard和replica shard都是活跃的,才可以执行这个写操作
  • quorum:默认的值,要求所有的shard中,必须是大部分的shard都是活跃的,可用的,才可以执行这个写操作
这个大部分,该怎么算呢?

这个大部分,叫规定数量(quorum),有个计算公式:

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

  • primary 即一个索引下的primary shard数量;
  • number_of_replicas即每个primary shard拥有的副本数量,注意不是一个索引所有的副本数量。

如果一个索引有3个primary shard,每个shard拥有1个replica shard,共6个shard,这样number_of_replicas就是1,代入公式计算:
quorum = int ((3 + 1) / 2) + 1 = 3

所以6个shard中必须有3个是活跃的,才让你写,如果你只启用2个node,这样活跃的replica shard只会有1个,加上primarys shard ,结果最多是2。这样是达不到quorun的值,因此将无法索引和删除任何文档。
此时你必须启动3个节点,才能满足quorum写一致性的要求。

quorum不够时的超时处理

如果写操作检查前,活跃的shard不够导致无法写入时,Elasticsearch会等待,希望宕机的node能够恢复,默认60秒,可以使用timeout参数修改默认值。

单node的写一致性

照上面的公式算,1个node的,1个索引1个primary shard,number_of_replicas为1的情况,计算公式:

quorum = int ((1 + 1) / 2) + 1 = 2

实际只有一个primary shard是活跃的,岂不是永远无法写入?我研发机器只启动一个node,不照样增删改查?

原来是Elasticsearch为了避免单一node的无法写入问题,加了判断逻辑:只有number_of_replicas大于1的时候,quorum才会生效。

小结

本篇从性能优先的角度简单对bulk的设计作了一些补充,并对文档查询,写操作的原理过程,一致性级别,quorum的计算做了一些简单讲解,谢谢。

专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区

原文地址:https://www.cnblogs.com/huangying2124/p/12065697.html

时间: 2024-11-09 07:27:56

Elasticsearch系列---补充几个知识点的相关文章

web网页简单设计补充的css知识点

了解了web的基本框架,html和css,补充几点知识点常见表示颜色的几种方法:red#f00rgb(255,0,0)rgba(255,0,0,0.5) 带透明度的色彩值 opacity: 50%;透明度border-radius:圆角 border-radius:值值:a 表示四角都为相同的圆角状态值:a b 表示 左上,右下都为a,右上,左下都为b值:a b c 表示左上为a 右上和左下为b 右下为c值:a b c d 依次表示 左上 右上 右下 左下值:50% 表示圆或椭圆 cursor:

【SpringBoot MQ 系列】RabbitMq 核心知识点小结

[MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 AMQP 协议实现的企业级消息系统,想要顺畅的玩耍的前提是得先了解它,本文将主要介绍 rabbitmq 的一些基本知识点 特点 基本概念 消息投递消费的几种姿势 事务 集群 I. 基本知识点 它是采用 Erlang 语言实现的 AMQP(Advanced Message Queued Protoco

Elasticsearch系列---定制mapping

概要 本篇接着前一篇内容,继续介绍mapping信息,重点倾向于自定义mapping.自定义对象以及数组集合类的底层结构. 自定义mapping 上一篇文章介绍的都是Elasticsearch的自动mapping,我们在创建索引时,可以先指定好mapping的信息,还是以music索引为例: PUT /music { "mappings": { "children": { "properties": { "content":

Elasticsearch系列---实战零停机重建索引

前言 我们使用Elasticsearch索引文档时,最理想的情况是文档JSON结构是确定的,数据源源不断地灌进来即可,但实际情况中,没人能够阻拦需求的变更,在项目的某个版本,可能会对原有的文档结构造成冲击,增加新的字段还好,如果要修改原有的字段,只能重建索引了. 概要 本篇以实战方式讲解如何零停机完成索引重建的三种方案. 外部数据导入方案 整体介绍 系统架构设计中,有关系型数据库用来存储数据,Elasticsearch在系统架构里起到查询加速的作用,如果遇到索引重建的操作,待系统模块发布新版本后

Elasticsearch系列---索引管理

概要 Elasticsearch让索引创建变得非常简单,只要索引一条新的数据,索引会自动创建出来,但随着数据量的增加,我们开始有了索引优化和搜索优化的需求之后,就会发现自动创建的索引在某些方面不能非常完美的适应我们的需求,我们开始考虑手动创建适合我们业务需求的索引. 索引的CRUD 为了更好地贴切我们的业务数据需求,我们开始更精细的管理我们的索引. 创建索引 创建索引的语法示例如下: PUT /music { "settings": { "number_of_shards&q

Elasticsearch系列---shard内部原理

概要 本篇我们来看看shard内部的一些操作原理,了解一下人家是怎么玩的. 倒排索引 倒排索引的结构,是非常适合用来做搜索的,Elasticsearch会为索引的每个index为analyzed的字段建立倒排索引. 基本结构 倒排索引包含以下几个部分: 某个关键词的doc list 某个关键词的所有doc的数量IDF(inverse document frequency) 某个关键词在每个doc中出现的次数:TF(term frequency) 某个关键词在这个doc中的次序 每个doc的长度:

Elasticsearch系列---前缀搜索和模糊搜索

概要 本篇我们介绍一下部分搜索的几种玩法,我们经常使用的浏览器搜索框,输入时会弹出下拉提示,也是基于局部搜索原理实现的. 前缀搜索 我们在前面了解的搜索,词条是最小的匹配单位,也是倒排索引中存在的词,现在我们来聊聊部分匹配的话题,只匹配一个词条中的一部分内容,相当于mysql的"where content like '%love%'",在数据库里一眼就能发现这种查询是不走索引的,效率非常低. Elasticsearch对这种搜索有特殊的拆分处理,支持多种部分搜索格式,这次重点在于not

elasticsearch系列(一) 术语

elasticsearch(以下简称es)是一款开源的搜索引擎,基于apach lucene.最近在做nlp的时候顺便研究一下. 下面是官方列举的术语解释 Near Realtime 接近实时的查询,通常情况下,延迟在1s以内 Cluster 一个集群由1个或者多个节点组成,这些节点提供整个数据和索引,性能来源于每个节点.一个集群有一个唯一的名字,默认为"elasticsearch", Node 一个node启动的时候分配一个唯一的id(UUID),自动会加入名为"elast

elasticsearch系列(五)score

概述 score在ES中有着很重要的作用,有了它才有了rank,是验证文档相关性的关键数据,score越大代表匹配到的文档相关性越大 官方解释 查询的时候可以用explain来展示score的计算过程,也可以增加format=yaml来讲json转成yaml方便阅读 类似xxx/_search?explain&format=yaml 下图是通过explain看到的一部分json,其实这个解释中就展示出了计算公式,不得不说ES在这点上还是很人性化的 计算方式 常说的相关性是指计算一个全文(full