公司服务器最新经常提示ElasticSearch占用cpu太高,查询相关文档,加深了了解。

介绍

全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选。

它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。

Elastic 是 Lucene 的封装,提供了 REST API 的操作接口。

使用

Elastic 需要 Java 8 环境。也可以使用docker安装。

1
docker run -p 9200:9200 -d --name elasticsearch elasticsearch

其默认使用9200端口。打开另一个命令行窗口,请求该端口,会得到说明信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ curl localhost:9200

{
"name" : "atntrTf",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "tf9250XhQ6ee4h7YI11anA",
"version" : {
"number" : "5.5.1",
"build_hash" : "19c13d0",
"build_date" : "2017-07-18T20:44:24.823Z",
"build_snapshot" : false,
"lucene_version" : "6.6.0"
},
"tagline" : "You Know, for Search"
}

Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。

所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。

下面的命令可以查看当前节点的所有 Index。

1
$ curl -X GET 'http://localhost:9200/_cat/indices?v'

CPU占用过高

公司ElasticSearch使用时间长后,最近一直提示CPU占用太高。

查询后,有多种优化方式。可以增加集群节点,或者修改配置,进行优化。

结合公司实际,更简单的办法是,删除过期的index。

公司的index主要是存储日志,日志文件比较大,时间久远后,会占用过多空间。

1
curl -XDELETE http://localhost:9200/索引名字

删除后,重启ElasticSearch

也可以查询热点线程。在 Java 中,热点线程(hot threads)是占用大量 CPU 且执行时间很长的线程。

1
2
3
4
集群所有节点:
curl -XGET `hostname -i`:9200/_nodes/hot_threads
单个节点:
curl -XGET `hostname -i`:9200/_nodes/node-name/hot_threads

索引文档

协调节点默认使用文档ID参与计算(也支持通过routing),以便为路由提供合适的分片。   

shard = hash(document_id) % (num_of_primary_shards)   

当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒)写入到Filesystem Cache,这个从Momery Buffer到Filesystem   

Cache的过程就叫做refresh;   

当然在某些情况下,存在Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush;   

在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。   

flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;

更新和删除文档

删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更;   

磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。

当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。   

在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。

Web工具ElasticHD

ElasticHD 支持 ES监控实时搜索Index template快捷替换修改索引列表信息查看SQL converts to DSL工具等。是一款非常伴的 Dashboard。

可以是https://github.com/360EntSecGroup-Skylar/ElasticHD

1
docker run -p 9800:9800 -d containerize/elastichd

es_cli

相关文档

阮一峰-文搜索引擎 Elasticsearch 入门教程

ElasticHD github

深入解读 Elasticsearch 热点线程 hot_threads