• es 聚合性能优化


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

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

    本质上就是通过预先加载全局字典到内存中来减少磁盘I/O操作,从而提高查询速度。以空间换时间。

    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. {
    3. "mappings": {
    4. "properties": {
    5. "tags": {
    6. "type": "keyword",
    7. "eager_global_ordinals": true
    8. }
    9. }
    10. }
    11. }

    注意:开启 eager_global_ordinals 会影响写入性能,因为每次刷新时都会创建新的全局序号。为了最大程度地减少由于频繁刷新建立全局序号而导致的额外开销,请调大刷新间隔 refresh_interval。

    动态调整刷新频率的方法如下:

    1. PUT /my_index
    2. {
    3. "mappings": {
    4. "properties": {
    5. "tags": {
    6. "type": "keyword",
    7. "eager_global_ordinals": true
    8. }
    9. }
    10. },
    11. "settings": {
    12. "refresh_interval": "30s"
    13. }
    14. }

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

    • Index sorting (索引排序)可用于在插入时对索引进行预排序,而不是在查询时再对索引进行排序,这将提高范围查询(range query)和排序操作的性能。
    • 在 Elasticsearch 中创建新索引时,可以配置如何对每个分片内的段进行排序。
    • 这是 Elasticsearch 6.X 之后版本才有的特性。
    1. PUT /my_index
    2. {
    3. "mappings": {
    4. "properties": {
    5. "create_time": {
    6. "type": "date"
    7. }
    8. }
    9. },
    10. "settings": {
    11. "index": {
    12. "sort.field": "create_time",
    13. "sort.order": "desc"
    14. }
    15. }
    16. }

    注意:预排序将增加 Elasticsearch 写入的成本。在某些用户特定场景下,开启索引预排序会导致大约 40%-50% 的写性能下降。也就是说,如果用户场景更关注写性能的业务,开启索引预排序不是一个很好的选择。

    使用节点查询缓存

    节点查询缓存(Node query cache)可用于有效缓存过滤器(filter)操作的结果。如果多次执行同一 filter 操作,这将很有效,但是即便更改过滤器中的某一个值,也将意味着需要计算新的过滤器结果。

    例如,由于 “now” 值一直在变化,因此无法缓存在过滤器上下文中使用 “now” 的查询。

    那怎么使用缓存呢?通过在 now 字段上应用 datemath 格式将其四舍五入到最接近的分钟/小时等,可以使此类请求更具可缓存性,以便可以对筛选结果进行缓存。

    1. DELETE /my_index
    2. PUT /my_index/_doc/1
    3. {
    4. "create_time":"2024-03-16T02:48:55.328Z"
    5. }
    6. #以下 filter 无法使用缓存
    7. GET /my_index/_search
    8. {
    9. "query": {
    10. "constant_score": {
    11. "filter": {
    12. "range": {
    13. "create_time": {
    14. "gte": "now-10h",
    15. "lte": "now"
    16. }
    17. }
    18. }
    19. }
    20. }
    21. }
    22. #下面的示例 可以使用缓存
    23. GET /my_index/_search
    24. {
    25. "query": {
    26. "constant_score": {
    27. "filter": {
    28. "range": {
    29. "create_time": {
    30. "gte": "now-10h/m",
    31. "lte": "now/m"
    32. }
    33. }
    34. }
    35. }
    36. }
    37. }

    上述示例中的“now-1h/m” 就是 datemath 的格式。

    如果当前时间 now 是:11:48:55,那么range query 将匹配 my_date 介于:01:48:00 和 11:48:59 之间的时间数据。同理,聚合的前半部分 query 中如果有基于时间查询,或者后半部分 aggs 部分中有基于时间聚合的,建议都使用 datemath 方式做缓存处理以优化性能。

    使用分片请求缓存

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

    1. GET /my_flights/_search
    2. {
    3. "size": 0,
    4. "aggs": {
    5. "weather": {
    6. "terms": {
    7. "field": "OriginWeather"
    8. }
    9. }
    10. }
    11. }

    拆分聚合,使聚合并行化

    Elasticsearch 查询条件中同时有多个条件聚合,默认情况下聚合不是并行运行的。当为每个聚合提供自己的查询并执行 msearch 时,性能会有显著提升。因此,在 CPU 资源不是瓶颈的前提下,如果想缩短响应时间,可以将多个聚合拆分为多个查询,借助:msearch 实现并行聚合

    1. #常规的多条件聚合实现
    2. GET /employees/_search
    3. {
    4. "size": 0,
    5. "aggs": {
    6. "job_agg": {
    7. "terms": {
    8. "field": "job.keyword"
    9. }
    10. },
    11. "max_salary":{
    12. "max": {
    13. "field": "salary"
    14. }
    15. }
    16. }
    17. }
    18. # msearch 拆分多个语句的聚合实现
    19. GET _msearch
    20. {"index":"employees"}
    21. {"size":0,"aggs":{"job_agg":{"terms":{"field": "job.keyword"}}}}
    22. {"index":"employees"}
    23. {"size":0,"aggs":{"max_salary":{"max":{"field": "salary"}}}}

    感谢观看!!!感兴趣的小伙伴可以关注收藏,持续更新中~~~

  • 相关阅读:
    Mybatis—动态sql和分页
    多线程环境下事务与锁的问题
    SpringMVC返回不带引号的字符串方案汇总
    Ajax--初识Ajax--接口和案例 - 图书管理
    拾光者,云南白药!
    城商行两地三中心存储架构设计实践分享
    各种ide配置gitignore的模版文件内容
    一起Talk Android吧(第四百零一回:如何使用TableLayout布局)
    业务可视化-让你的流程图“Run“起来(6.定时任务&Spring-Batch的集成)
    【Web】PHP反序列化的一些trick
  • 原文地址:https://blog.csdn.net/weixin_59367598/article/details/136757794