数据测试 ES 怎样大批量查询和删除比较高效?

TD · 2023年12月27日 · 最后由 TD 回复于 2023年12月28日 · 4764 次阅读

目前我们埋点数据需要统计,每天数据量千万或亿级别的数据,我需要统计每天这些数据,需要先把数据查询出来然后做些计算(聚合不好实现,python 处理的),我现在的问题是:
1.使用滚动查询,查询一批数据处理一批,但是感觉很慢,怎么都执行不完,然后滚动查询时间一长 cpu 也比较高,看下 load 啥的都很高。这个滚动查询要怎么设置比较好点,还是有其他办法?
2.数据量需要每天删除,之前根据查询删除,异步删除不返回,感觉每天数据量还是不断增多,没有删除干净的感觉,我现在直接删除索引,删除索引有个问题就是有个时间内的数据没处理就被删除了。我想问下大家大批量数据都是怎么删除的?
对 ES 不是很熟悉,望有经验的人多指教一下,谢谢!

共收到 4 条回复 时间 点赞

以下是一些可能的解决方案和建议:

  1. 滚动查询优化:

    • 增大批次大小:在滚动查询时,尝试增大每次查询的数据量,但要注意不要过大导致内存问题。
    • 优化查询语句:确保你的查询语句尽可能高效,避免不必要的字段检索和排序。
    • 使用 scroll 参数:Elasticsearch 的 scroll API 可以用于高效的批量数据检索。它允许你在一段时间内保持搜索上下文,这样你就可以获取大量数据而无需多次重新计算得分。但是请注意,scroll 查询可能会占用更多的内存。
    • 分布式处理:如果可能,将数据处理任务分布到多个节点或实例上,以提高处理速度和减少单个节点的压力。
  2. 大批量数据删除:

    • 使用 Delete By Query API:Elasticsearch 提供了 Delete By Query API,可以用于根据条件删除大批量数据。你可以设置一个定时任务,在每天的特定时间执行删除过期数据的操作。
    • 考虑使用 TTL(Time To Live):为索引中的文档设置 TTL,这样 Elasticsearch 会在文档过期后自动删除它们,无需手动删除。
    • 分批删除:如果一次性删除整个索引或者大量数据导致性能问题,可以考虑分批删除。例如,每次删除一定时间段内的数据,或者限制每次删除的数据量。
  3. 数据保留策略:

    • 确定数据保留期限:根据业务需求,明确数据需要保留多久,然后据此制定删除策略。
    • 使用 curator 或类似的工具:Curator 是一个开源的 Elasticsearch 索引管理工具,可以帮助你自动化一些任务,如索引备份、 rollover 和删除过期数据。

对于 CPU 高和 load 高的问题,除了上述的优化措施外,还需要检查服务器的硬件资源是否足够,以及 Elasticsearch 集群的配置是否合理。可能需要增加硬件资源,或者调整 Elasticsearch 的 JVM 参数、索引分片数等配置以优化性能。

TD #2 · 2023年12月27日 Author
大海 回复
  1. 我现在滚动查询是这样的,有时候数据处理很慢,我的 scroll 时间就设置比较长一点,不知道这个设置多少比较合理,然后依次 query 的 size 不知道设置越大越好还是 10000 这样。目前是 10000 现在这样感觉处理不完。你能帮忙看下这块有啥优化吗?: ```py init_search = es.search( index="dclog_xxxx", scroll='2m',
    body=query, request_timeout=10 )

sid = init_search['_scroll_id'] # 记录下 '_scroll_id'
scroll_size = len(init_search['hits']['hits']) # 记录下初始查询回的结果数
while scroll_size > 0:
page = es.scroll(scroll_id=sid, scroll='6m')
# 更新 scroll_id
sid = page['_scroll_id']
# 更新 scroll_size
scroll_size = len(page['hits']['hits'])
# 打印结果,或者进一步处理数据
# print("scroll size: " + str(scroll_size))
if scroll_size > 0:
deal_data(start, end, page['hits']['hits'])

2.删除我也是定时删除的,使用的_delete_by_query?conflicts=proceed&scroll_size=10000&wait_for_completion=false,之前没有加conflicts=proceed&scroll_size=10000,然后可能删除失败了,数据越来越多,后面数据量太大了就删除不了了。
TD 回复

针对你的滚动查询和删除问题,以下是一些优化建议:

  1. 滚动查询优化:
  • scroll 时间设置:2m 的滚动时间可能较长,这会占用更多的资源。你可以尝试将滚动时间减少到 1m 或者更短,看看是否会影响数据处理的稳定性。理想情况下,滚动时间应该足够长以处理一批数据,但又不能过长以免占用过多资源。
  • size 设置:你目前设置为 10000,这个值可以根据你的系统性能和数据处理速度进行调整。如果处理速度较慢,可以尝试减小 size,比如设置为 50002000,这样每次处理的数据量会减少,可能会提高处理效率。但是请注意,减小 size 会增加网络通信的次数,需要找到一个平衡点。

另外,你可以在处理数据的过程中记录下处理时间和数据量,根据这些信息来动态调整 scroll 时间和 size

  1. 数据删除优化:
  • 使用 _delete_by_query 时,添加 conflicts=proceed 参数可以避免因冲突而导致的删除失败,这是一个好的做法。
  • scroll_size=10000 参数用于控制每次批量删除的数量,这个值可以根据你的系统性能进行调整。如果你的系统能够承受更大的批量删除操作,可以适当增大这个值,但要注意不要过大导致系统压力过大。
  • wait_for_completion=false 参数表示异步删除,这是正确的做法,可以避免长时间阻塞等待删除操作完成。

如果你发现数据量太大导致删除失败,可以考虑分批删除或者在数据生成后立即进行删除,以减少数据积累。

TD #4 · 2023年12月28日 Author
大海 回复

好的,谢谢~

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册