分布式之搜索解决方案es

一 ES初识

1.1 概述

  ElasticSearch:是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据。是ELK的一个组成,是一个产品,而且是非常完善的产品,ELK代表的是:E就是ElasticSearch,L就是Logstach,K就是kibana

  • E:EalsticSearch 搜索和分析的功能。
  • L:Logstach 搜集数据的功能,类似于flume(使用方法几乎跟flume一模一样),是日志收集系统。
  • K:Kibana 数据可视化(分析),可以用图表的方式来去展示,文不如表,表不如图,是数据可视化平台
    分布式之搜索解决方案es_第1张图片

  分析日志的用处:假如一个分布式系统有 1000 台机器,系统出现故障时,我要看下日志,还得一台一台登录上去查看,是不是非常麻烦?

  但是如果日志接入了 ELK 系统就不一样。比如系统运行过程中,突然出现了异常,在日志中就能及时反馈,日志进入 ELK 系统中,我们直接在 Kibana 就能看到日志情况。如果再接入一些实时计算模块,还能做实时报警功能。

  这都依赖ES强大的反向索引功能,这样我们根据关键字就能查询到关键的错误日志了。

ES官网:https://www.elastic.co/cn/elasticsearch/

1.2 ES由来

  在上一篇文章中搜索实现之lucene中讲述了lunece和es的关系,下面就再说说两个直接的联系吧。
Lucene有两个难以解决的问题:

  • 数据越大,存不下来,那我就需要多台服务器存数据,那么我的Lucene不支持分布式的,那就需要安装多个Lucene然后通过代码来合并搜索结果。这样很不好
  • 数据要考虑安全性,一台服务器挂了,那么上面的数据不就消失了。

  ES就是分布式的集群,每一个节点其实就是Lucene,当用户搜索的时候,会随机挑一台,然后这台机器自己知道数据在哪,不用我们管这些底层。
分布式之搜索解决方案es_第2张图片
ES的优点:

  • 分布式的功能
  • 数据高可用,集群高可用
  • API更简单和更高级。
  • 支持的语言很多
  • 支持PB级别的数据
  • 完成搜索的功能和分析功能
  • 基于Lucene,隐藏了Lucene的复杂性,提供简单的API

ES的性能比HBase高,咱们的竞价引擎最后还是要存到ES中的。

二 ES概念,安装和使用

2.1 基本概念

1,NRT(Near RealTime) 近实时。
分布式之搜索解决方案es_第3张图片
2,Cluster集群
  ES是一个分布式的系统,且ES直接解压不需要配置就可以使用,在hadoop1上解压一个ES,在hadoop2上解压了一个ES,接下来把这两个ES启动起来。他们就构成了一个集群。
  在ES里面默认有一个配置,clustername 默认值就是ElasticSearch,如果这个值是一样的就属于同一个集群,不一样的值就是不一样的集群。
  集群中的每一台服务器就是Node节点。

3,index 索引(索引库)
  我们为什么使用ES?因为想把数据存进去,然后再查询出来。我们在使用Mysql或者Oracle的时候,为了区分数据,我们会建立不同的数据库,库下面还有表的。其实ES功能就像一个关系型数据库,在这个数据库我们可以往里面添加数据,查询数据。
  ES中的索引非传统索引的含义,ES中的索引是存放数据的地方,是ES中的一个概念词汇。index类似于我们Mysql里面的一个数据库 create database user; 好比就是一个索引库
4,type类型
  类型是用来定义数据结构的。在每一个index下面,可以有一个或者多个type,好比数据库里面的一张表。相当于表结构的描述,描述每个字段的类型。
5,document
  文档就是最终的数据了,可以认为一个文档就是一条记录。是ES里面最小的数据单元,就好比表里面的一条数据
6,Field字段
  好比关系型数据库中列的概念,一个document有一个或者多个field组成。
例如:

  • 朝阳区:一个Mysql数据库
  • 房子:create database chaoyaninfo
  • 房间:create table people

7,shard:分片
  一台服务器,无法存储大量的数据,ES把一个index里面的数据,分为多个shard,分布式的存储在各个服务器上面
8,replica:副本
  一个分布式的集群,难免会有一台或者多台服务器宕机,如果我们没有副本这个概念。就会造成我们的shard发生故障,无法提供正常服务。我们为了保证数据的安全,我们引入了replica的概念,跟hdfs里面的概念是一个意思。可以保证我们数据的安全。
  在ES集群中,我们一模一样的数据有多份,能正常提供查询和插入的分片我们叫做 primary shard,其余的我们就管他们叫做 replica shard(备份的分片)

  当我们去查询数据的时候,我们数据是有备份的,它会同时发出命令让我们有数据的机器去查询结果,最后谁的查询结果快,我们就要谁的数据(这个不需要我们去控制,它内部就自己控制了)
9,总结
  在默认情况下,我们创建一个库的时候,默认会帮我们创建5个主分片(primary shrad)和5个副分片(replica shard),所以说正常情况下是有10个分片的。

  同一个节点上面,副本和主分片是一定不会在一台机器上面的,就是拥有相同数据的分片,是不会在同一个节点上面的。

  所以当你有一个节点的时候,这个分片是不会把副本存在这仅有的一个节点上的,当你新加入了一台节点,ES会自动的给你在新机器上创建一个之前分片的副本。
分布式之搜索解决方案es_第4张图片
10,举例
  比如一首诗,有诗题、作者、朝代、字数、诗内容等字段,那么首先,我们可以建立一个名叫 Poems 的索引,然后创建一个名叫 Poem 的类型,类型是通过 Mapping 来定义每个字段的类型。
  比如诗题、作者、朝代都是 Keyword 类型,诗内容是 Text 类型,而字数是 Integer 类型,最后就是把数据组织成 Json 格式存放进去了。
分布式之搜索解决方案es_第5张图片
Keyword 类型是不会分词的,直接根据字符串内容建立反向索引,Text 类型在存入 Elasticsearch 的时候,会先分词,然后根据分词后的内容建立反向索引。
分布式之搜索解决方案es_第6张图片

2.2 安装

咱们如果想很爽的使用ES,需要安装3个东西:ES、Kibana、ElasticSearch Head。通过Kibana可以对ES进行便捷的可视化操作,通过ElasticSearch Head可以查看ES的状态及数据,可以理解为ES的图形化界面。

2.2.1 安装ES和Kibana

首先开始安装ES、Kibana,同时安装这两个加启动,一共需要3步,3行代码搞定:
1,搜索docker镜像库里可用的ES镜像:可以看到,stars排名第一的是官方的ES镜像,第二是大牛已经融合了ES7.7和Kibana7.7的镜像,那咱们就用第二个了。

docker search elasticsearch

分布式之搜索解决方案es_第7张图片
2,拉取镜像

docker pull nshou/elasticsearch-kibana

分布式之搜索解决方案es_第8张图片
3,最后咱们把镜像启动为容器就可以了,端口映射保持不变,咱们给这个容器命名为eskibana,到这里ES和Kibana就安装配置完成了!容器启动后,它们也就启动了,一般不会出错,是不是非常方便?节省大把时间放到开发上来,这也是我一直推荐docker的原因。

docker run -d -p 9200:9200 -p 9300:9300 -p 5601:5601 --name eskibana  ns
hou/elasticsearch-kibana

2.2.2 安装ElasticSearch Head

ElasticSearch Head,它相当于是ES的图形化界面,这个更简单,它是一个浏览器的扩展程序,直接在chrome浏览器扩展程序里下载安装即可:
1,打开chrome浏览器,在扩展程序chrome应用商店那里,搜索elasticsearch:
分布式之搜索解决方案es_第9张图片
2,选择ElasticSearch Head,点击添加至Chrome,进行扩展程序的安装即可:
分布式之搜索解决方案es_第10张图片

2.2.3 验证

到这里咱们的ES、Kibana、ElasticSearch Head都已经安装完成了,下面咱们验证一下,看是否安装成功!
1,验证ES
打开浏览器,输入IP:端口,比如我的:http://127.0.0.1:9200/,然后就看到了那句经典的:You Know, for Search:
分布式之搜索解决方案es_第11张图片
2,验证Kibana:

打开浏览器,输入Kibana的IP:端口,比如我的:http://127.0.0.1:5601/,然后会看到如下界面:
分布式之搜索解决方案es_第12张图片
这里面可以提供很多模拟数据,感兴趣的可以自己玩玩,咱们学习期间只要使用左下角那个扳手形状的Dev Tools就可以了,点击后,会出现如下界面:
分布式之搜索解决方案es_第13张图片
3,验证Es head
这个更简单,只需要点击之前咱们安装的那个扩展程序图标就可以了:
分布式之搜索解决方案es_第14张图片
点击信息,还可以看到集群或者索引的信息,很方便,大家没事可以玩一玩,熟悉一下:
分布式之搜索解决方案es_第15张图片
通过验证,我们已经全部安装配置成功了,那么接下来,就让我们一起练习一下基础的增删改查,加深对ES的理解吧!

2.3 基本使用

前面我们已经介绍过了ES 是RESTful 风格的系统,所以我们需要先掌握RESTful 的四个关键词:PUT(修改),POST(添加),DELETE(删除),GET(查询)。其中在ES里面PUT和POST的界限并不是很分明,有时候PUT也作为添加。

2.3.1 索引操作

1,创建一个空索引
如下代码,咱们创建了一个0副本2分片的ropledata索引,然后咱们可以在Elasticsearch Head里刷新一下,并查看索引的信息:

PUT /ropledata
{
  "settings": { 
    "number_of_shards": "2", 
    "number_of_replicas": "0"
  } 
}

分布式之搜索解决方案es_第16张图片
分布式之搜索解决方案es_第17张图片
2,修改副本
咱们如果对刚才创建的索引副本数量不满意,可以进行修改,注意:分片不允许修改

PUT ropledata/_settings 
{ 
  "number_of_replicas" : "2" 
}

3,删除索引
当这个索引不想用了,可以进行删除,执行如下命令即可,执行成功后,刷新ElasticSearch Head可以看到刚才创建的ropledata索引消失了:

DELETE /ropledata

分布式之搜索解决方案es_第18张图片

2.3.2 数据操作

1,插入数据
插入数据的时候可以指定id,如果不指定的话,ES会自动帮我们生成。我们以指定id为例,如下代码是我们创建了一个101的文档,创建成功后,可以在Elasticsearch Head的数据浏览模块里看到这些数据,代码及演示如下:

//指定id 
POST /ropledata/_doc/101 
{
  "id":1,
  "name":"且听_风吟",
  "page":"https://ropledata.blog.csdn.net",
  "say":"欢迎点赞,收藏,关注,一起学习" 
}

分布式之搜索解决方案es_第19张图片
分布式之搜索解决方案es_第20张图片

2,修改数据
这里大家要特别注意,ES里的文档是不可以修改的,但是可以覆盖,所以ES修改数据本质上是对文档的覆盖。ES对数据的修改分为全局更新和局部更新,咱们分别进行code并对比:
1)全局更新:

PUT /ropledata/_doc/101
{ 
  "id":1,
  "name":"且听_风吟",
  "page":"https://ropledata.blog.csdn.net",
  "say":"再次欢迎点赞,收藏,关注,一起学习" 
}

大家可以多全局更新几次,会发现每次全局更新之后这个文档的_version都会发生改变!
分布式之搜索解决方案es_第21张图片
2)局部更新

POST /ropledata/_update/101 
{
  "doc":
  {
    "say":"奥力给"
  } 
}

这时候我们可以多次去执行上面的局部更新代码,会发现除了第一次执行,后续不管又执行了多少次,_version都不再变化!
分布式之搜索解决方案es_第22张图片

局部更新的底层流程:

内部先获取到对应的文档;

  1. 将传递过来的字段更新到文档的json中(这一步实质上也是一样的);
  2. 将老的文档标记为deleted(到一定时候才会物理删除);
  3. 将修改后的新的文档创建出来。

性能对比:

  1. 全局更新本质上是替换操作,即使内容一样也会去替换;
  2. 局部更新本质上是更新操作,只有遇到新的东西才更新,没有新的修改就不更新;
  3. 局部更新比全局更新的性能好,因此推荐使用局部更新。

3,查询数据
ES的数据查询知识点非常多,也非常复杂,后面我打算单独讲解演示,本文只展示最基本的根据id搜索数据的code:

GET /ropledata/_doc/101

分布式之搜索解决方案es_第23张图片
4,删除数据
比如我们想把ropledata索引下的id为101的文档删除,可以使用如下命令:

DELETE /ropledata/_doc/101

分布式之搜索解决方案es_第24张图片

查询或者删除的时候指定的ID是文档里面得字段id吗?
  不是的,这点容易混淆,查询或者删除时候用到的ID是创建文档时候指定或者ES自动生成的那个id,而不是文档里面的那个叫id 字段!文档里面的文档字段是可以没有id 的。

三 ES常见问题

ES基础相关

1,ES的基本概念

  • index 索引:索引类似于mysql 中的数据库,Elasticesearch 中的索引是存在数据的地方,包含了一堆有相似结构的文档数据。
  • type 类型:类型是用来定义数据结构,可以认为是 mysql 中的一张表,type 是 index 中的一个逻辑数据分类。
  • document 文档:类似于 MySQL 中的一行,不同之处在于 ES 中的每个文档可以有不同的字段,但是对于通用字段应该具有相同的数据类型,文档是es中的最小数据单元,可以认为一个文档就是一条记录。
  • Field 字段:Field是Elasticsearch的最小单位,一个document里面有多个field。
  • shard 分片:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。
  • replica 副本:任何服务器随时可能故障或宕机,此时 shard 可能会丢失,通过创建 replica 副本,可以在 shard 故障时提供备用服务,保证数据不丢失,另外 replica 还可以提升搜索操作的吞吐量。

2,docs_value的作用

  倒排索引虽然可以提高搜索性能,但也存在缺陷,比如我们需要对数据做排序或聚合等操作时,lucene 会提取所有出现在文档集合的排序字段,然后构建一个排好序的文档集合,而这个步骤是基于内存的,如果排序数据量巨大的话,容易造成内存溢出和性能缓慢。
  doc_values 就是 es 在构建倒排索引的同时,会对开启 doc_values 的字段构建一个有序的 “document文档 ==> field value” 的列式存储映射,可以看作是以文档维度,实现了根据指定字段进行排序和聚合的功能,降低对内存的依赖。另外 doc_values 保存在操作系统的磁盘中,当 doc_values 大于节点的可用内存,ES可以从操作系统页缓存中加载或弹出,从而避免发生内存溢出的异常,但如果 docValues 远小于节点的可用内存,操作系统就自然将所有 doc_values 存于内存中(堆外内存),有助于快速访问。
mapping配置项详解

3,text 和 keyword类型的区别

两个类型的区别主要是分词:keyword 类型是不会分词的,直接根据字符串内容建立倒排索引,所以keyword类型的字段只能通过精确值搜索到;Text 类型在存入 Elasticsearch 的时候,会先分词,然后根据分词后的内容建立倒排索引

4,query 和 filter 的区别?

  • query:查询操作不仅仅会进行查询,还会计算分值,用于确定相关度;
  • filter:查询操作仅判断是否满足查询条件,不会计算任何分值,也不会关心返回的排序问题,同时,filter 查询的结果可以被缓存,提高性能。

5,ES的分布式原理

  • Elasticsearch 会对存储的数据进行切分,划分到不同的分片上,同时每一个分片会生成多个副本,从而保证分布式环境的高可用。ES集群中的节点是对等的,节点间会选出集群的 Master,由 Master 会负责维护集群状态信息,并同步给其他节点。
  • Elasticsearch 的性能会不会很低:不会,ES只有建立 index 和 type 时需要经过 Master,而数据的写入有一个简单的 Routing 规则,可以路由到集群中的任意节点,所以数据写入压力是分散在整个集群的。

6,ES的Master选举

分布式之搜索解决方案es_第25张图片

Elasticsearch 的选主是 ZenDiscovery 模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分;

  1. 确认候选主节点的最少投票通过数量(elasticsearch.yml 设置的值 discovery.zen.minimum_master_nodes)
  2. 选举时,集群中每个节点对所有 master候选节点(node.master: true)根据 nodeId 进行字典排序,然后选出第一个节点(第0位),暂且认为它是master节点。
  3. 如果对某个节点的投票数达到阈值,并且该节点自己也选举自己,那这个节点就是master;否则重新选举一直到满足上述条件。

补充:master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。

7,Elasticsearch是如何避免脑裂现象:

脑裂产生原因:

  • 网络问题:集群间的网络延迟导致一些节点访问不到 master,认为 master 挂掉了从而选举出新的master,并对 master 上的分片和副本标红,分配新的主分片。
  • 节点负载:主节点的角色既为 master 又为 data,访问量较大时可能会导致 ES 停止响应造成大面积延
    迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
  • 内存回收:data 节点上的 ES 进程占用的内存较大,引发 JVM 的大规模内存回收,造成 ES 进程失去响应。

解决方案:

  • 减少误判:discovery.zen.ping_timeout 节点状态的响应时间(超过这个时间就会重新选举master),默认为 3s,可以适当调大,如果 master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如 6s,discovery.zen.ping_timeout:6),可适当减少误判。
  • 选举触发:discovery.zen.minimum_master_nodes:1。该参数是用于控制选举行为发生的最小集群主节点数量。当备选主节点的个数大于等于该参数的值,且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n/2)+1,n 为主节点个数(即有资格成为主节点的节点个数)。
  • 角色分离:即 master 节点与 data 节点分离,限制角色

主节点配置为:node.master: true node.data: false
从节点配置为:node.master: false node.data: true

ES的CURD流程

1,ES写数据的整体流程

分布式之搜索解决方案es_第26张图片

  1. 客户端选择 ES 的某个 node 发送请求过去,这个 node 就是协调节点 coordinating node
  2. coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)
  3. 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node
  4. coordinating node 等到 primary node 和所有 replica node 都执行成功之后,最后返回响应结果给客户端。

2,ES写数据的详细流程

分布式之搜索解决方案es_第27张图片

  1. 主分片先将数据写入ES的 memory buffer,然后定时(默认1s)将 memory buffer 中的数据写入一个新的 segment 文件中,并进入操作系统缓存 Filesystem cache(同时清空 memory buffer),这个过程就叫做 refresh;每个 segment 文件实际上是一些倒排索引的集合, 只有经历了 refresh 操作之后,这些数据才能变成可检索的。

ES 的近实时性:数据存在 memory buffer 时是搜索不到的,只有数据被 refresh 到 Filesystem cache 之后才能被搜索到,而 refresh 是每秒一次, 所以称 es 是近实时的;可以手动调用 es 的 api 触发一次 refresh 操作,让数据马上可以被搜索到;

  1. 由于 memory Buffer 和 Filesystem Cache 都是基于内存,假设服务器宕机,那么数据就会丢失,所以 ES 通过 translog 日志文件来保证数据的可靠性,在数据写入 memory buffer 的同时,将数据也写入 translog 日志文件中,当机器宕机重启时,es 会自动读取 translog 日志文件中的数据,恢复到 memory buffer 和 Filesystem cache 中去。

ES 数据丢失的问题:translog 也是先写入 Filesystem cache,然后默认每隔 5 秒刷一次到磁盘中,所以默认情况下,可能有 5 秒的数据会仅仅停留在 memory buffer 或者 translog 文件的 Filesystem cache中,而不在磁盘上,如果此时机器宕机,会丢失 5 秒钟的数据。也可以将 translog 设置成每次写操作必须是直接 fsync 到磁盘,但是性能会差很多。

  1. flush 操作:不断重复上面的步骤,translog 会变得越来越大,不过 translog 文件默认每30分钟或者 阈值超过 512M 时,就会触发 commit 操作,即 flush操作,将 memory buffer 中所有的数据写入新的 segment 文件中, 并将内存中所有的 segment 文件全部落盘,最后清空 translog 事务日志。
  1. 将 memory buffer 中的数据 refresh 到 Filesystem Cache 中去,清空 buffer;
  2. 创建一个新的 commit point(提交点),同时强行将 Filesystem Cache 中目前所有的数据都 fsync 到磁盘文件中;
  3. 删除旧的 translog 日志文件并创建一个新的 translog 日志文件,此时 commit 操作完成

详细可参考:https://blog.csdn.net/a745233700/article/details/118076845

3,ES更新和删除流程

删除和更新都是写操作,但是由于 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;所以 ES 利用 .del 文件 标记文档是否被删除,磁盘上的每个段都有一个相应的.del 文件

  • 删除操作,文档其实并没有真的被删除,而是在 .del 文件中被标记为 deleted 状态。该文档依然能匹配查询,但是会在结果中被过滤掉。
  • 更新操作,就是将旧的 doc 标识为 deleted 状态,然后创建一个新的 doc。

memory buffer 每 refresh 一次,就会产生一个 segment 文件 ,所以默认情况下是 1s 生成一个 segment 文件,这样下来 segment 文件会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment 文件合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,不写入到新的 segment 中,然后将新的 segment 文件写入磁盘,这里会写一个 commit point ,标识所有新的 segment 文件,然后打开 segment 文件供搜索使用,同时删除旧的 segment 文件
有关segment段合并过程,欢迎阅读这篇文章:Elasticsearch搜索引擎:ES的segment段合并原理

4,ES的搜索流程

搜索被执行一共分为两个阶段:

  • query阶段:客户端发送请求到 coordinate node,协调节点将搜索请求广播到所有的 primary shard 或 replica,每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。接着每个分片返回各自优先队列中 所有 docId 和 打分值 给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
  • Fetch阶段:协调节点根据 Query阶段产生的结果,去各个节点上查询 docId 实际的 document 内容,最后由协调节点返回结果给客户端。
  • coordinate node 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
  • 接收请求的 node 返回 document 给 coordinate node 。
  • coordinate node 返回 document 给客户端。

Query Then Fetch 的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了一个预查询的处理,询问 Term 和 Document frequency,这个评分更准确,但是性能会变差。

6,ES在高并发下如何保证读写一致性

  • 对于更新操作:可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖。

每个文档都有一个_version 版本号,这个版本号在文档被改变时加一。Elasticsearch使用这个 _version 保证所有修改都被正确排序,当一个旧版本出现在新版本之后,它会被简单的忽略。利用_version的这一优点确保数据不会因为修改冲突而丢失,比如指定文档的version来做更改,如果那个版本号不是现在的,我们的请求就失败了。

  • 对于写操作,一致性级别支持 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,副本将会在一个不同的节点上重建。

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

  • 对于读操作,可以设置 replication 为 sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置replication 为 async 时,也可以通过设置搜索请求参数 _preference 为 primary 来查询主分片,确保文档是最新版本。

ES的性能提升相关

1,建立索引阶段性能提升方法

  1. 如果是大批量导入,可以设置 index.number_of_replicas: 0 关闭副本,等数据导入完成之后再开启副本
  2. 使用批量请求并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。
  3. 如果搜索结果不需要近实时性,可以把每个索引的 index.refresh_interval 改到30s
  4. 增加 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比如 1 GB
  5. 使用 SSD 存储介质
  6. 段和合并:Elasticsearch 默认值是 20 MB/s。但如果用的是 SSD,可以考虑提高到 100–200 MB/s。如果你在做批量导入,完全不在意搜索,你可以彻底关掉合并限流。

2,ES的深度分页与滚动搜索scroll

  • 深度分页:深度分页其实就是搜索的深浅度,比如第1页,第2页,第10页,第20页,是比较浅的;第10000页,第20000页就是很深了。搜索得太深,就会造成性能问题,会耗费内存和占用cpu。而且es为了性能,他不支持超过一万条数据以上的分页查询。那么如何解决深度分页带来的问题,我们应该避免深度分页操作(限制分页页数),比如最多只能提供100页的展示,从第101页开始就没了,毕竟用户也不会搜的那么深。

  • 滚动搜索: 一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll。 滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个锚标记 ,随后再次滚动搜索会需要上一次搜索滚动id,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的。

3,ES在部署的时候Linux的那些设置优化

  1. 关闭缓存 swap;
  2. 堆内存设置为:Min(节点内存/2, 32GB);
  3. 设置最大文件句柄数;
  4. 线程池+队列大小根据业务需要做调整;
  5. 磁盘存储 raid 方式——存储有条件使用 RAID10,增加单节点性能以及避免单节点存储故障。

参考文档:
https://blog.csdn.net/JENREY/article/details/81290535
https://blog.csdn.net/qq_26803795/article/details/106423578
https://blog.csdn.net/a745233700/article/details/115585342

你可能感兴趣的:(分布式,elasticsearch,lucence,安装,基本使用,常见问题)