Elasticsearch-分布式集群调优策略

1. Index(写)调优

职位数据和简历数据,首先都是进入MySQL集群的,我们从MySQL的原始表里面抽取并存储到ES 的Index,而MySQL的原始数据也是经常在变化的,所以快速写入Elasticsearch、以保持Elasticsearch和MySQL的数据及时同步也是很重要的

  • 副本数置0
    如果是集群首次灌入数据,可以将副本数设置为0,写入完毕再调整回去,这样副本分片只需要拷贝,节省了索引过程
PUT /my_temp_index/_settings
{
"number_of_replicas": 0
}
  • 自动生成doc ID
       通过Elasticsearch写入流程可以看出,如果写入doc时如果外部指定了id,则Elasticsearch会先尝试读取原来doc的版本号,以判断是否需要更新。这会涉及一次读取磁盘的操作,通过自动生成doc ID可以避免这个环节

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

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

  • 对analyzed的字段禁用norms
        Norms用于在搜索时计算doc的评分,如果不需要评分,则可以将其禁用

title": {
"type": "string",
"norms": {
"enabled": false
}
  • 调整索引的刷新间隔
    该参数缺省是1s,强制ES每秒创建一个新segment,从而保证新写入的数据近实时的可见、可被搜索到。比如该参数被调整为30s,降低了刷新的次数,把刷新操作消耗的系统资源释放出来给index操作使用
PUT /my_index/_settings
{"index" : {
      "refresh_interval": "30s"
    }
}

这种方案以牺牲可见性的方式,提高了index操作的性能。

  • 批处理
    批处理把多个index操作请求合并到一个batch中去处理,和mysql的jdbc的bacth有类似之处
    在这里插入图片描述
    比如每批1000个documents是一个性能比较好的size。每批中多少document条数合适,受很多因素影响而不同,如单个document的大小等。ES官网建议通过在单个node、单个shard做性能基准测试来确定这个参数的最优值
  • 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
在这里插入图片描述
值得注意的是线程数虽然降低了,但是单批的处理耗时可能增加了。和提高刷新间隔方法类似,这有可
能会延长数据不见的时间

Search(读)调优

在存储的Document条数超过10亿条后,我们如何进行搜索调优。

  • 数据分组
    很多人拿ES用来存储日志,日志的索引管理方式一般基于日期的,基于天、周、月、年建索引。如下图,基于天建索引
    在这里插入图片描述
    当搜索单天的数据,只需要查询一个索引的shards就可以。当需要查询多天的数据时,需要查询多个索引的shards。这种方案其实和数据库的分表、分库、分区查询方案相比,思路类似,小数据范围查询而不是大海捞针。

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

在这里插入图片描述

  • 使用Filter替代Query
    在搜索时候使用Query,需要为Document的相关度打分。使用Filter,没有打分环节处理,做的事情更少,而且filter理论上更快一些。
    如果搜索不需要打分,可以直接使用filter查询。如果部分搜索需要打分,建议使用’bool’查询。这种方式可以把打分的查询和不打分的查询组合在一起使用,如
GET /_search
{
"query": {
"bool": {
"must": {
"term": {
"user": "kimchy"
}
},
"filter": {
"term": {
"tag": "tech"
}
}
}
}
}
  • ID字段定义为keyword
    一般情况,如果ID字段不会被用作Range 类型搜索字段,都可以定义成keyword类型。这是因为keyword会被优化,以便进行terms查询。Integers等数字类的mapping类型,会被优化来进行range类型搜索
    将integers改成keyword类型之后,搜索性能大约能提升30%

  • 别让用户的无约束的输入拖累了ES集群的性能
    拉勾工程师通过监控发现所有node的CPU 使用及其负载突然异常飙高。通过对Slow Logs分析发现,
    用户查询输入的条件中夹带了很多’OR’语句以及通配符“*”开头的字符串,如下
    在这里插入图片描述
    为了不让用户无约束的查询语句拖累ES集群的查询性能,可以限制用户用来查询的keywords。对于可以用来查询的keyworkds,也可以写成文档来帮助用户更正确的使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值