ES查询优化案例01-业务层面优化

ES查询优化案例

更多请关注:https://t.zsxq.com/fhroW

现状

背景:聊天业务,销售与客户聊天数据统计。

索引:effect_chat 存储销售与客户的聊天消息数,以员工、客户、日期维度存储,一个销售与一个客户一天的聊天统计为一条数据。

优化点:effect_chat索引按月拆分,每月数据量2亿。
按时间筛选查询销售沟通客户数量,需要在ES中聚合、去重,比较耗时耗内存。

原查询语句:

{
  "size": 0,
  "query ": {
    "bool": {
      "must": [
        {
          "term": {
            "corpid": {
              "value": "xxxxxxx"
            }
          }
        },
        {
          "range": {
            "effect_date": {
              "from": "2024-06-25 00:00:00",
              "to": "2024-06-28 23:59:59"
            }
          }
        },
        {
          "bool": {
            "should": [
              {
                "term": {
                  "userid": {
                    "value": "363062119469760"
                  }
                }
              },
              {
                "term": {
                  "userid": {
                    "value": "377390053632704"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  },
  "aggregations": {
    "uids": {
      "terms": {
        "field": "userid",
        "size": 10000,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "uniq_customer": {
          "cardinality": {
            "field": "chatid",
            "precision_threshold": 3000
          }
        }
      }
    }
  }
}
  • 查询语句解析
    聚合部分以销售id分组,每个分组下根据chatid去重(chatid=销售id+客户id) ,实现查询日期范围内与销售有过聊天的客户数量。
  • 优化点
    1. 该索引的拆分索引每个月2亿数据量,aggs聚合时耗费内存。
    2. 聚合后对数据去重,ES在处理大量数据时,采用近似计算,所以得到的数据并不准确,precision_threshold越大越耗内存、越准确(见文末拓展)。
    3. 该查询是个高频查询
优化

索引数据量很大时,聚合查询自然更耗费内存,所以首先想到的是拆分索引,但是该索引已经拆分过了,再拆分就不符合业务了,普通查询可能会走到很多歌索引中。

所以方案为新增索引distinct_effect_chat,索引结构为销售-客户维度。索引中也记录时间,但这个时间会被最新的聊天更新。相当于effect_chat索引记录了每天的聊天情况,distinct_effect_chat记录最新的聊天情况。从而省去了聚合和去重。

该查询走distinct_effect_chat索引,避免了聚合和去重。
但这个新索引只能查询截至日期为当日的统计情况,而不能查询历史数据,历史数据依然要走旧查询。

但是即使是这样,也给ES集群减少了很大压力,因为我们分析客户习惯发现,客户的查询习惯是查询近七天或者某个日期到今天的数据,也正是因为这个客户习惯,才针对性的做出新索引的数据结构。

另外,旧查询还有个优化点,若查询单日数据,则不需要聚合。也是从业务中总结出的。

总结:分析用户使用习惯,针对性的优化查询,减轻ES集群压力。

拓展

ES在处理大量数据时,采用近似计算方法(如HyperLogLog++算法)而不是精确计算有几个重要原因:

1. 性能和资源限制
  • 内存消耗:精确计算唯一值需要在内存中维护一个哈希表或集合,存储所有唯一值。这在数据量非常大时会占用大量内存,可能导致内存不足或性能下降。
  • 计算时间:精确计算需要逐一处理所有数据,这在处理海量数据时会非常耗时,影响查询响应速度和系统的整体性能。
2. 可扩展性
  • 分布式计算:在分布式系统中(如Elasticsearch),数据分布在多个节点上。进行精确计算需要在所有节点上收集和合并数据,这会导致大量的网络传输和数据聚合操作,增加复杂度和开销。
  • 高并发:系统需要处理大量并发查询时,近似计算可以提供更快的响应时间,提升用户体验。
3. 实际需求
  • 业务需求:在许多实际应用中,近似结果已经足够满足业务需求。例如,营销分析、监控和统计报告等场景中,近似值可以提供足够的决策支持,而不需要精确到每一个数据点。
  • 统计学接受度:很多统计分析方法和工具都允许一定范围内的误差,近似计算结果在可接受误差范围内时,完全可以满足分析需求。

更多请关注:https://t.zsxq.com/fhroW

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值