分布式之搜索解决方案es

一 ES初识

1.1 概述

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

  • E:EalsticSearch 搜索和分析的功能。
  • L:Logstach 搜集数据的功能,类似于flume(使用方法几乎跟flume一模一样),是日志收集系统。
  • K:Kibana 数据可视化(分析),可以用图表的方式来去展示,文不如表,表不如图,是数据可视化平台
    在这里插入图片描述

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

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

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

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

1.2 ES由来

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

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

  ES就是分布式的集群,每一个节点其实就是Lucene,当用户搜索的时候,会随机挑一台,然后这台机器自己知道数据在哪,不用我们管这些底层。
在这里插入图片描述
ES的优点:

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

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

二 ES概念,安装和使用

2.1 基本概念

1,NRT(Near RealTime) 近实时。
在这里插入图片描述
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会自动的给你在新机器上创建一个之前分片的副本。
在这里插入图片描述
10,举例
  比如一首诗,有诗题、作者、朝代、字数、诗内容等字段,那么首先,我们可以建立一个名叫 Poems 的索引,然后创建一个名叫 Poem 的类型,类型是通过 Mapping 来定义每个字段的类型。
  比如诗题、作者、朝代都是 Keyword 类型,诗内容是 Text 类型,而字数是 Integer 类型,最后就是把数据组织成 Json 格式存放进去了。
在这里插入图片描述
Keyword 类型是不会分词的,直接根据字符串内容建立反向索引,Text 类型在存入 Elasticsearch 的时候,会先分词,然后根据分词后的内容建立反向索引。
在这里插入图片描述

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

在这里插入图片描述
2,拉取镜像

docker pull nshou/elasticsearch-kibana

在这里插入图片描述
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:
在这里插入图片描述
2,选择ElasticSearch Head,点击添加至Chrome,进行扩展程序的安装即可:
在这里插入图片描述

2.2.3 验证

到这里咱们的ES、Kibana、ElasticSearch Head都已经安装完成了,下面咱们验证一下,看是否安装成功!
1,验证ES
打开浏览器,输入IP:端口,比如我的:http://127.0.0.1:9200/,然后就看到了那句经典的:You Know, for Search:
在这里插入图片描述
2,验证Kibana:

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

在这里插入图片描述
在这里插入图片描述
2,修改副本
咱们如果对刚才创建的索引副本数量不满意,可以进行修改,注意:分片不允许修改

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

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

DELETE /ropledata

在这里插入图片描述

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":"欢迎点赞,收藏,关注,一起学习" 
}

在这里插入图片描述
在这里插入图片描述

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

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

大家可以多全局更新几次,会发现每次全局更新之后这个文档的_version都会发生改变!
在这里插入图片描述
2)局部更新

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

这时候我们可以多次去执行上面的局部更新代码,会发现除了第一次执行,后续不管又执行了多少次,_version都不再变化!
在这里插入图片描述

局部更新的底层流程:

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

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

性能对比:

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

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

GET /ropledata/_doc/101

在这里插入图片描述
4,删除数据
比如我们想把ropledata索引下的id为101的文档删除,可以使用如下命令:

DELETE /ropledata/_doc/101

在这里插入图片描述

查询或者删除的时候指定的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选举

在这里插入图片描述

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写数据的整体流程

在这里插入图片描述

  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写数据的详细流程

在这里插入图片描述

  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

猜你喜欢

转载自blog.csdn.net/swimming_in_IT_/article/details/130012230
今日推荐