Elasticsearch 分布式集群调优策略

1. Index(写)调优

1.1 副本数置0

如果是集群首次灌入数据,可以将副本数设置为0,写入完毕再调整回去,这样副本分片只需要拷 贝,节省了索引过程。

PUT /my_temp_index/_settings 
{
"number_of_replicas": 0 
}
1.2 自动生成doc ID

通过Elasticsearch写入流程可以看出,如果写入doc时如果外部指定了id,则Elasticsearch会先尝试 读取原来doc的版本号,以判断是否需要更新。这会涉及一次读取磁盘的操作,通过自动生成doc ID可 以避免这个环节。

1.3 合理设置mappings
  1. 将不需要建立索引的字段index属性设置为not_analyzed或no。对字段不分词,或者不索引,可以 减少很多运算操作,降低CPU占用。 尤其是binary类型,默认情况下占用CPU非常高,而这种类 型进行分词通常没有什么意义。
  2. 减少字段内容长度,如果原始数据的大段内容无须全部建立 索引,则可以尽量减少不必要的内容。
  3. 使用不同的分析器(analyzer),不同的分析器在索引过程中 运算复杂度也有较大的差异。
1.4 调整_source字段

source字段用于存储doc原始数据,对于部分不需要存储的字段,可以通过includes excludes 过滤,或者将source禁用,一般用于索引和数据分离,这样可以降低 I/O 的压力,不过实际场景中大多不会禁用_source。

1.5 对analyzed的字段禁用norms

Norms用于在搜索时计算doc的评分,如果不需要评分,则可以将其禁用:

"title": {
  "type": "string",
  "norms": {
    "enabled": false
  }
1.6 调整索引的刷新间隔

该参数缺省是1s,强制ES每秒创建一个新segment,从而保证新写入的数据近实时的可见、可被搜索 到。比如该参数被调整为30s,降低了刷新的次数,把刷新操作消耗的系统资源释放出来给index操作使 用。这种方案以牺牲可见性的方式,提高了index操作的性能。

PUT /my_index/_settings
{
 "index" : {
      "refresh_interval": "30s"     }
}
1.7 批处理

批处理把多个index操作请求合并到一个batch中去处理,和mysql的jdbc的bacth有类似之处。如图:
在这里插入图片描述
比如每批1000个documents是一个性能比较好的size。每批中多少document条数合适,受很多因素 影响而不同,如单个document的大小等。ES官网建议通过在单个node、单个shard做性能基准测试来 确定这个参数的最优值。

1.8 Document的路由处理

当对一批中的documents进行index操作时,该批index操作所需的线程的个数由要写入的目的shard的个数决定。看下图:
在这里插入图片描述
上图中,有2批documents写入ES, 每批都需要写入4个shard,所以总共需要8个线程。如果能减少 shard的个数,那么耗费的线程个数也会减少。例如下图,两批中每批的shard个数都只有2个,总共线 程消耗个数4个,减少一半。
默认的routing就是id,也可以在发送请求的时候,手动指定一个routing value,比如: put /index/doc/id?routing=user_id

在这里插入图片描述
值得注意的是线程数虽然降低了,但是单批的处理耗时可能增加了。和提高刷新间隔方法类似,这有可 能会延长数据不见的时间。

2. Search(读)调优

2.1 数据分组

很多人拿ES用来存储日志,日志的索引管理方式一般基于日期的,基于天、周、月、年建索引。如下 图,基于天建索引:
在这里插入图片描述

当搜索单天的数据,只需要查询一个索引的shards就可以。当需要查询多天的数据时,需要查询多个索 引的shards。这种方案其实和数据库的分表、分库、分区查询方案相比,思路类似,小数据范围查询而 不是大海捞针。

开始的方案是建一个index,当数据量增大的时候,就扩容增加index的shard的个数。当shards增大 时,要搜索的shards个数也随之显著上升。基于数据分组的思路,可以基于client进行数据分组,每一 个client只需依赖自己的index的数据shards进行搜索,而不是所有的数据shards,大大提高了搜索的性 能,如下图:

在这里插入图片描述

2.使用Filter替代Query

在搜索时候使用Query,需要为Document的相关度打分。使用Filter,没有打分环节处理,做的事情更少,而且filter理论上更快一些。
如果搜索不需要打分,可以直接使用filter查询。如果部分搜索需要打分,建议使用’bool’查询。这种方式可以把打分的查询和不打分的查询组合在一起使用,如:

GET /_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "user": "kimchy"
        }
      },
      "filter": {
        "term": {
          "tag": "tech"
       } 
     }
   } 
 }
}
3.ID字段定义为keyword

一般情况,如果ID字段不会被用作Range 类型搜索字段,都可以定义成keyword类型。这是因为 keyword会被优化,以便进行terms查询。Integers等数字类的mapping类型,会被优化来进行range类 型搜索。
将integers改成keyword类型之后,搜索性能大约能提升30%。

4. 别让用户的无约束的输入拖累了ES集群的性能

通过监控发现所有node的CPU 使用及其负载突然异常飙高。通过对Slow Logs分析发现, 用户查询输入的条件中夹带了很多’OR’语句以及通配符“*”开头的字符串,如下图

在这里插入图片描述

为了不让用户无约束的查询语句拖累ES集群的查询性能,可以限制用户用来查询的keywords。对于可以用来查询的keyworkds,也可以写成文档来帮助用户更正确的使用。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值