ElasticSearch-聚合性能优化

打印 上一主题 下一主题

主题 537|帖子 537|积分 1611


  • 启用 eager global ordinals 提拔高基数聚合性能
  • 插入数据时对索引进行预排序
  • 使用节点查询缓存
  • 使用分片请求缓存
  • 拆分聚合,使聚归并行化



  • 启用 eager global ordinals 提拔高基数聚合性能

    • 高基数聚合场景中的高基数含义:一个字段包罗很大比例的唯一值
    • 实用场景:高基数聚合

  • global ordinals(全局序号),是一种数据布局,应用场景:

    • 基于 keyword,ip 等字段的分桶聚合

      • 包罗:terms聚合、composite 聚合等

    • 基于 text 字段的分桶聚合(条件条件是:fielddata 开启)
    • 基于父子文档 Join 类型的 has_child 查询和父聚合

  • global ordinals 使用一个数值代表字段中的字符串值,然后为每一个数值分配一个 bucket(分桶)
  • global ordinals 的本质是:启用 eager_global_ordinals 时,会在刷新(refresh)分片时构建全局序号

    • 这将构建全局序号的本钱从搜索阶段转移到了数据索引化(写入)阶段

  • 创建索引的同时开启:eager_global_ordinals
  1. PUT /my‐index
  2. {"mappings":{"properties":{"tags":{"type":"keyword",
  3.    "eager_global_ordinals":true}}}
复制代码


  • 开启 eager_global_ordinals 会影响写入性能,因为每次刷新时都会创建新的全局序号

    • 为了最大水平地镌汰由于频繁刷新创建全局序号而导致的额外开销,请调大刷新隔断 refresh_interval

  • 动态调整刷新频率
  1. PUT my‐index/_settings
  2. {"index":{"refresh_interval":"30s"}
复制代码



  • 插入数据时对索引进行预排序

    • Index sorting (索引排序)可用于在插入时对索引进行预排序,而不是在查询时再对索引进行排序

      • 这将进步范围查询(range query)和排序操纵的性能

    • 创建新索引时,可以配置怎样对每个分片内的段进行排序(Elasticsearch 6.X 之后版本才有的特性)

  1. PUT /my_index
  2. {"settings":{"index":{"sort.field":"create_time","sort.order":"desc"}},
  3.  "mappings":{"properties":{"create_time":{"type":"date"}}}}
复制代码


  • 预排序将增长 Elasticsearch 写入的本钱

    • 在某些用户特定场景下,开启索引预排序会导致大约 40%-50% 的写性能下降
    • 如果用户场景更关注写性能的业务,开启索引预排序不是一个很好的选择




  • 使用节点查询缓存:节点查询缓存(Node query cache)可用于有效缓存过滤器(filter)操纵的结果

    • 如果多次实行同一 filter 操纵,这将很有效,但是即便更改过滤器中的某一个值,也将意味着需要盘算新的过滤器结果

  1. GET /my_index/_search
  2. {"query":{"constant_score":{"filter":{
  3.  "range":{"create_time":{"gte":"now‐1h/m","lte":"now/m"}}}}}}
复制代码


  • “now-1h/m” 就是 datemath 的格式:将其四舍五入到最接近的分钟/小时等

    • 如果当前时间 now 是:16:31:29,那么range query 将匹配 my_date 介于:15:31:00 和 15:31:59 之间
    • 聚合的前半部门 query 中如果有基于时间查询,大概后半部门 aggs 部门中有基于时间聚合的,建议都使用 datemath 方式做缓存处置惩罚以优化性能




  • 使用分片请求缓存

    • 聚合语句中,设置size:0,就会使用分片请求缓存缓存结果
    • size = 0 的含义是:只返回聚合结果,不返回查询结果

  1. GET /es_db/_search
  2. {"size":0,"aggs":{"remark_agg":{"terms":{"field":"remark.keyword"}}}}
复制代码



  • 拆分聚合,使聚归并行化

    • Elasticsearch 查询条件中同时有多个条件聚合,默认情况下聚合不是并行运行的
    • 当为每个聚合提供自己的查询并实行 msearch 时,性能会有显著提拔
    • 如果想缩短响应时间,可以将多个聚合拆分为多个查询

      • 借助:msearch 实现并行聚合


  1. GET _msearch
  2. {"index":"employees"}
  3. {"size":0,"aggs":{"job_agg":{"terms":{"field":"job.keyword"}}}}
  4. {"index":"employees"}
  5. {"size":0,"aggs":{"max_salary":{"max":{"field":"salary"}}}}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表