Elasticsearch HTML文件搜索性能提升实战

集群内存设置

Elasticsearch默认安装后设置的内存是1GB,对于任何一个现实业务来说,这个设置实在太小了,稍有大批量查询或者写入操作,集群很快就会出现问题。
ES在6.x版本后,通过修改安装路径elasticsearch/jvm.options文件来设置内存

-Xms10g
-Xmx10g

将内存设置为10g,重启服务后生效

systemctl restart elasticsearch.service

一个常见的问题是配置一个大内存,假设你有一个64G内存的机器,按照正常思维思考,你可能会认为把64G内存都给Elasticsearch比较好,但现实是这样吗, 越大越好?

当然,内存对于Elasticsearch来说绝对是重要的,用于更多的内存数据提供更快的操作,而且还有一个内存消耗大户-Lucene。

Lucene的设计目的是把底层OS里的数据缓存到内存中。Lucene的段是分别存储到单个文件中的,这些文件都是不会变化的,所以很利于缓存,同时操作系统也会把这些段文件缓存起来,以便更快的访问。
如果将所有的内存都分配给Elasticsearch,不留一点给Lucene,那全文检索性能会很差的。

所以标准的建议是把50%的内存给elasticsearch,剩下的50%也不会没有用处的,Lucene会很快吞噬剩下的这部分内存用于文件缓存。
推荐安装cerebro来查看ES集群的状态: cerebro.
在这里插入图片描述

副本和分片

分片(shard)

当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。
当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。

副本(replica)

为提高查询吞吐量或实现高可用性,可以使用分片副本。
副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。当主分片不可用时,集群将副本提升为新的主分片。
ES默认是5个分片1个副本,设置方法:

curl -XPUT 'http://127.0.0.1:9200/_template/template_http_request_record' 
-H 'Content-Type: application/json' -d 
{
  "index_patterns": [
    "test"#index
  ],
  "settings": {
    "number_of_shards": 1,#分片
    "number_of_replicas": 1#副本
  }
}

索引分片如何设置合理?
在Elasticsearch中,每个查询在每个分片的单个线程中执行。然而,可以并行处理多个分片,并可以在相同分片上执行多个查询和聚合。

【小分片的利弊】这意味着,在不涉及高速缓存时,最小查询延迟将取决于数据、查询的类型、分片的大小。查询大量小分片将使得每个分片的处理速度更快,但是随着更多的任务需要按顺序排队和处理,它不一定要比查询较小数量的更大的分片更快。如果有多个并发查询,则有很多小碎片也会降低查询吞吐量。

ElasticSearch推荐的最大JVM堆空间是30~32G, 所以把分片最大容量限制为30GB, 然后再对分片数量做合理估算. 例如, 你的数据能达到200GB, 我们推荐你最多分配7到8个分片.

查询分页

size+from浅分页

当Elasticsearch响应请求时,它必须确定docs的顺序,排列响应结果。如果请求的页数较少(假设每页10个docs), Elasticsearch不会有什么问题,但是如果页数较大时,比如请求第100页,Elasticsearch不得不取出第1页到第100页的所有docs,再去除第1页到第99页的docs,得到第100页的docs。

scroll深分页

相对于from和size的分页来说,使用scroll可以模拟一个传统数据的游标,记录当前读取的文档信息位置。这个分页的用法,不是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部的数据)。

因为这个scroll相当于维护了一份当前索引段的快照信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。

from+size方式以及scroll方式优缺点对比:
1)对于from+size方式:当结果足够大的时候,查询页码越大,会大大加大内存和CPU的消耗。但该方式使用非常方便,可以任意跳页。所以这种分页方式需要做一些限制,比如只能查询前100页等

2)对于scroll方式: 当结果足够大的时候, scroll 性能要比from+size效率高很多。但是只能下一页 下一页的返回数据,不能跳页。类似微博或者新闻app往下滑刷新内容的应用场景还是非常不错的,但scroll的缓存时间设置不宜过长,占内存。
因为我的业务数据量左右,所以我用的scroll的方式,每次返回10条记录,使用者根据需求点击获取更多数据,效果还是非常不错的。
在这里插入图片描述

高亮对比

通过论坛中网友的建议来看,都推荐对于大文件高亮使用: fast-vector-highlighter。

Plain highlighter

ES默认的配置方式,官网明确说明该方式匹配慢,如果出现性能问题,请考虑其他高亮方式。

Postings highlighter

支持postings高亮方式,需要在mapping下添加如下信息:

"type": "text",
"index_options" : "offsets"

posting高亮方式的特点:
1)速度快,不需要对高亮的文档再分析。文档越大,获得越高 性能 。
2)比fvh高亮方式需要的磁盘空间少。
3)将text文件分割成语句并对其高亮处理。对于自然语言发挥作用明显,但对于html则不然。
4)将文档视为整个语料库,并 使用BM25算法 为该语料库中的文档打分。

PUT /example
{
  "mappings": {
    "doc" : {
      "properties": {
        "comment" : {
          "type": "text",
          "index_options" : "offsets"
        }
      }
    }
  }
}

Fast vector highlighter

如果在mapping中的text类型字段下添加了如下信息:

"type": "text","term_vector" : "with_positions_offsets"

fvh高亮方式的特点如下:
1)当文件>1MB(大文件)时候,尤其适合fvh高亮方式。
2)自定义为 boundary_scanner的扫描方式。
3) 设定了 term_vector to with_positions_offsets会增加索引的大小。
4)能联合多字段匹配返回一个结果,详见matched_fields。
5)对于不同的匹配类型分配不同的权重,如:pharse匹配比term匹配高。

因为我的业务场景是对HTML文件进行多词匹配,文件很多都是大于1M,用ES默认的Plain highlighter,所以平均搜索时间都在5秒以上,复杂的可能需要20S以上。
在这里插入图片描述
将services.banner字段修改为f’vh后,搜索效率大大提升,即使是复杂的搜索也在毫秒级。

{
	"mappings": {
		"doc": {
			"properties": {
				"services.banner": {
					"type": "text",
					"term_vector": "with_positions_offsets"
				}
			}
		}
	}
}

在这里插入图片描述
参考链接:
https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index.
http://doc.codingdict.com/elasticsearch/106/.
https://cloud.tencent.com/developer/article/1066368.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值