段合并

本文探讨了Elasticsearch中因频繁自动刷新导致段数量激增的问题及其带来的负面影响,介绍了Elasticsearch如何通过后台自动段合并来解决该问题,同时讨论了如何手动优化段数以提高搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。

Elasticsearch通过在后台进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。

段合并的时候会将那些旧的已删除文档 从文件系统中清除。 被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。

启动段合并不需要你做任何事。进行索引和搜索时会自动进行。这个流程像在下图描述的一样工作:

1、 当索引的时候,刷新(refresh)操作会创建新的段并将段打开以供搜索使用。

2、 合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中。这并不会中断索引和搜索。

两个提交了的段和一个未提交的段正在被合并到一个更大的段

Two commited segments and one uncommited segment in the process of being merged into a bigger segment

3、一旦合并结束,老的段被删除,说明合并完成时的活动:

  • 新的段被刷新(flush)到了磁盘。   ** 写入一个包含新段且排除旧的和较小的段的新提交点。
  • 新的段被打开用来搜索。
  • 老的段被删除。

一旦合并结束,老的段被删除

一旦合并结束,老的段被删除

合并大的段需要消耗大量的I/O和CPU资源,如果任其发展会影响搜索性能。Elasticsearch在默认情况下会对合并流程进行资源限制,所以搜索仍然 有足够的资源很好地执行。

提示

查看 段和合并 来为你的实例获取关于合并调整的建议。

optimize API

optimize API大可看做是 强制合并 API 。它会将一个分片强制合并到 max_num_segments 参数指定大小的段数目。 这样做的意图是减少段的数量(通常减少到一个),来提升搜索性能。

警告

optimize API 不应该 被用在一个动态索引————一个正在被活跃更新的索引。后台合并流程已经可以很好地完成工作。 optimizing 会阻碍这个进程。不要干扰它!

在特定情况下,使用 optimize API 颇有益处。例如在日志这种用例下,每天、每周、每月的日志被存储在一个索引中。 老的索引实质上是只读的;它们也并不太可能会发生变化。

在这种情况下,使用optimize优化老的索引,将每一个分片合并为一个单独的段就很有用了;这样既可以节省资源,也可以使搜索更加快速:

POST /logstash-2014-10/_optimize?max_num_segments=1 

合并索引中的每个分片为一个单独的段

警告

请注意,使用 optimize API 触发段合并的操作一点也不会受到任何资源上的限制。这可能会消耗掉你节点上全部的I/O资源, 使其没有余裕来处理搜索请求,从而有可能使集群失去响应。 如果你想要对索引执行 `optimize`,你需要先使用分片分配(查看 迁移旧索引)把索引移到一个安全的节点,再执行。













SQL中的合并通常涉及到对间字进行分组并聚合,以便合并那些相邻的或者填充缺失的间点。这种操作常见于日志分析、销售数据统计等场景中,比如计算每个内的总和、计数或其他汇总值。 例如,如果你有一个记录用户活动的日志表,每个记录包含用户ID、活动开始间和结束间,你可以通过以下步骤合并: 1. **找出连续的**: 使用`LAG()`函数获取前一条记录的结束间,并与当前记录的开始间比较,判断是否为连续。 2. **创建新的间范围字**: 如果是连续的,创建一个新的字表示合并后的起始间;如果不是,添加该行到结果集中。 3. **聚集和合并数据**: 对每个合并后的应用聚合函数,如SUM()用于累计某种量,COUNT()用于计数事件次数等。 4. **处理边界情况**: 可能需要特别处理第一行和最后一行,因为它们可能是单独的一间,而不是合并的结果。 以下是一个简单的示例查询(假设表名为`activity_logs`,有`user_id`, `start_time`, `end_time`列): ```sql WITH CTE AS ( SELECT user_id, start_time, end_time, COALESCE(LAG(end_time) OVER (PARTITION BY user_id ORDER BY start_time), start_time) + INTERVAL '1 second' as new_start_time FROM activity_logs ) SELECT user_id, MIN(new_start_time) as merged_start, MAX(end_time) as merged_end, SUM(some_quantity_column) as total_quantity FROM CTE GROUP BY user_id, DATE_TRUNC('minute', new_start_time); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值