背景:聊天业务,销售与客户聊天数据统计。
索引: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
}
}
}
}
}
}
索引数据量很大时,聚合查询自然更耗费内存,所以首先想到的是拆分索引,但是该索引已经拆分过了,再拆分就不符合业务了,普通查询可能会走到很多歌索引中。
所以方案为新增索引distinct_effect_chat,索引结构为销售-客户维度。索引中也记录时间,但这个时间会被最新的聊天更新。相当于effect_chat索引记录了每天的聊天情况,distinct_effect_chat记录最新的聊天情况。从而省去了聚合和去重。
该查询走distinct_effect_chat索引,避免了聚合和去重。
但这个新索引只能查询截至日期为当日的统计情况,而不能查询历史数据,历史数据依然要走旧查询。
但是即使是这样,也给ES集群减少了很大压力,因为我们分析客户习惯发现,客户的查询习惯是查询近七天或者某个日期到今天的数据,也正是因为这个客户习惯,才针对性的做出新索引的数据结构。
另外,旧查询还有个优化点,若查询单日数据,则不需要聚合。也是从业务中总结出的。
总结:分析用户使用习惯,针对性的优化查询,减轻ES集群压力。
ES在处理大量数据时,采用近似计算方法(如HyperLogLog++算法)而不是精确计算有几个重要原因:
1. 性能和资源限制
- 内存消耗:精确计算唯一值需要在内存中维护一个哈希表或集合,存储所有唯一值。这在数据量非常大时会占用大量内存,可能导致内存不足或性能下降。
- 计算时间:精确计算需要逐一处理所有数据,这在处理海量数据时会非常耗时,影响查询响应速度和系统的整体性能。
2. 可扩展性
- 分布式计算:在分布式系统中(如Elasticsearch),数据分布在多个节点上。进行精确计算需要在所有节点上收集和合并数据,这会导致大量的网络传输和数据聚合操作,增加复杂度和开销。
- 高并发:系统需要处理大量并发查询时,近似计算可以提供更快的响应时间,提升用户体验。
3. 实际需求
- 业务需求:在许多实际应用中,近似结果已经足够满足业务需求。例如,营销分析、监控和统计报告等场景中,近似值可以提供足够的决策支持,而不需要精确到每一个数据点。
- 统计学接受度:很多统计分析方法和工具都允许一定范围内的误差,近似计算结果在可接受误差范围内时,完全可以满足分析需求。
更多请关注:https://t.zsxq.com/fhroW
因篇幅问题不能全部显示,请点此查看更多更全内容