ES 异常写入解决流程

文章描述了一次在处理Elasticsearch大量数据写入引发的CircuitBreakingException问题的解决过程。首先尝试降低并发度和提高内存阈值,然后分析并解决未分配分片和集群状态异常,最后通过调整G1GC参数成功缓解问题。总结中提到,问题可能因索引数据过大和GC速度慢引起,建议改进写入策略和优化GC设置。

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

问题说明
一天下午,在北京客户现场的同学反馈我们elasticsearch出现的大量的异常,他反馈说他使用多线程写入大量数据到elasticsearch集群时,隔一段时间之后就会出现CircuitBreakingException,多尝试几次后,他就把问题反馈到我们这边了


解决思路
1.降低并发度
看到这个问题我首先想到的是减少写入的并发量,毕竟很明显是达到内存的阈值
ES 为了避免 OOM 会设置一些 circuit breaker (断路器),这些断路器的作用就是在内存不够的时候主动拒绝接下来的操作,而不是进一步的分配内存最终产生 OutOfMemoryError,断路器的作用就是保护整个进程不至于挂掉。
因此我就跟现场同学说,先把并发度降下来,我们是16个进程,先改为4个进程,发现问题还存在,于是我就跟现场同学说,把并发度降低为单线程,结果问题依然存在。
2.提高阈值
竟然降低并发解决不了,我们就想到能不能提高的elasticsearch熔断的阈值,给它更大的内存进行处理,当然这种方式是指标不治本的,于是我们参考官方熔断阈值设置,因此我将一些阈值动态的调大了,结果发现线程同学反馈问题依旧存在,调大了没有起到什么作用。而且过了一会,现场同学反馈我们集群状态变为yello了,出现了很多unassign的分片,而且此时kibana也变得很不稳定,经常性的卡死,同时还出现节点丢失的情况


3.尝试解决未分配分片
因为,于是就让现场同学停止写入,先等待集群状态恢复为green,决定先等半个小时,让es集群自动进行平衡,结果半小时之后,es集群并没有恢复,此时觉得问题有些大了,感觉集群出了较大的问题,于是我们尝试分析unassign的原因,于是使用Cluster allocation explain API对这些unassign的分片进行分析,分析结果如下 


根据分析,大致是recover失败,超过了最大的尝试次数,建议我们通过手动的形式去处理,因此我们尝试通过Cluster reroute API进行手动迁移分片,当然是显而易见的失败了,错误如下

 


4.限制集群节点的流量
虽然觉察到可能是由于GC引起了,但我们首先希望能够通过非重启的方法先暂时去解决,然后再去分析原因,最后在最终找到解决方案,
因为我们此时节点是黄的,此时集群的容错率很低,万一为了修改某些参数在重启的过程中,存在或者某一台节点出现问题,无法正常启动,导致数据数据丢失,不到万不得已,不会重建集群。
于是我们就想到控制节点的流量,降低传输的速度,于是我们就做了如下事情
1.取消有问题的副本
2.使用Index Recover设置集群传输的速度
indices.recovery.max_bytes_per_sec:限制每个节点的出栈入站流量,默认40mb,我们这里改为20mb;indices.recovery.max_concurrent_file_chunks:每次恢复并行发送的文件块请求的数量,默认为2,这里改为1
3.重新将副本设置为1
及时,这样问题还是没有解决,过了一会依旧出现了这样的问题
5.GC参数调整
虽然之前认为GC可能存在问题,但我认为GC是果,不是因,尝试去解决让GC不正常的问题,当然都失败了。
查看kibana的监控,找到出现问题节点的监控,图如下


根据此图发现es节点内存占用率一直在上升,说明申请的内存大于回收的内存空间,那么到内存快满的时候还有请求进行,那么必然内存不足,触发CircuitBreakingException。那么此时会进行fullgc,导致节点假死,就出现图中的现象。
我们使用的是G1
因此,就这种情况我就提出了我的想法,能够提前GC,那么就能够降低内存不足状况的概率,当然这样子的话,GC会更加频繁,降低系统的吞吐量,对比现状,显然是保护es集群更加重要,于是我们就参照这个想法去调整G1回收器的参数
查询G1参数列表如下

 


-XX:InitiatingHeapOccupancyPercent=30 默认为45%,这里是为了让垃圾回收器提前进入垃圾回收周期
-XX:G1ReservePercent=25% 默认10%,保留更多的内存空间,避免内存不足导致错误

重启集群
此时由于集群时yello状态,表明集群万一有一台重启失败或者出现意外,那么就势必导致数据丢失,因此必要要慎重。于是,我们跟现场同步进行沟通,指定重启步骤
1.提前修改所有节点的配置
2.将有问题的索引的副本设置为0
3.限制节点流程和传输,参考上面
4.禁止集群自动分配,避免因为重启导致集群重启导致分片自动分配,同时也为了数据快速恢复,参考Cluster-level shard allocation and routing settings

PUT _cluster/settings
{
 "persistent": {
   "cluster.routing.allocation.enable": "none"
 }
}

5.依次重启每一台几点
6.打开集群分片设置,设置策略为 "all"
7.恢复索引副本设置
上述步骤执行完成后,我们就等待集群恢复,发现副本能够正常恢复,同时并发写入也没有问题了,当然我们降低了并发度
总结
垃圾回收器改变带来的影响
一周前我们使用的垃圾回收器为CMS回收器,因为项目并发问题修改为G1,在使用CMS的时候这个问题并没有出现,但改成G1后出出现了
CMS和G1区别
CMS分为老年代和年轻代,当内存区域即将耗尽时会进行垃圾回收,回收时是线程停止的
G1内存是按region进行划分的,虽然也分年轻代和老年代,但并不严格,那块region是老年代或者新生代并非一成不变的,这是由垃圾回收器自动进行管理的,G1可以提供可预测的停顿,这是由region划分这个特性决定的
原因分析
索引数据体积过大,写入消耗内存过快,同时由于垃圾回收速度过慢,导致内存不停上涨,导致错误的发生
后续改进
1.由于应用直接多线程大量数据写入,导致es集群压力过大,中间缺少一层对写入流量进行控制,同时应当对集群进行压测,了解集群的写入状况,避免集群过载
2.GC改进,有上面总结,造成熔断的一个重要原因是垃圾回收过慢,为什么回收过慢,是因为我们设置-XX:MaxGCPauseMillis=200,这个参数表示最长垃圾回收时间,该属性设置过小,导致垃圾回收过慢,因此我们可以适当调大该属性,具体多少就该进行测试了
G1回收时并非我们常见那种对所有内存区域进行回收,而是选择一部分内存块进行回收,具体回收多少,有用户设置进行决定,这里由于设置过小,导致回收过慢,也是导致熔断的原因
参考
Elasticsearch新增节点引发CircuitBreakingException错误 - 御坂研究所
Elasticsearch Guide [8.6] | Elastic

<think>嗯,用户现在问的是关于ElasticsearchES)的异常情况报警的详解。之前他们问过Percolator,这次可能是想进一步了解如何在实际应用中结合报警机制,特别是在监控和实时警报方面。 首先,我需要确定用户的需求是什么。他们可能在使用ES进行日志管理或应用监控,想要设置自动化的异常检测和警报。可能需要了解不同的报警方案,比如使用内置的Watcher、第三方工具如ElastAlert,或者结合Percolator来实现。 用户之前已经了解过Percolator,所以可能对实时触发机制有一定认识。现在他们想知道如何将异常检测与报警结合起来。这时候需要比较不同的方法,各自的优缺点,适用场景,以及如何配置。 接下来要考虑用户的潜在问题。他们可能关心实时性、配置复杂度、维护成本,以及如何选择适合自己业务的方案。比如,小团队可能倾向于使用简单的Watcher,而需要复杂规则的可能选择ElastAlert,或者自研系统。 需要分步骤解释,包括核心机制、报警方案对比、配置示例、优化建议和案例。同时,要提醒用户不同ES版本的兼容性问题,比如Watcher在开源版本中的限制,或者Percolator在ES 6.x后的变化。 还要注意用户可能对性能有要求,比如高吞吐下的报警延迟,或者如何减少误报。这时候需要给出优化建议,比如使用过滤器、分片策略,或者调整检测频率。 最后,确保回答结构清晰,从原理到实践,逐步引导用户理解如何搭建异常报警系统,并提供实际案例帮助他们应用。同时,补充常见问题解答,解决他们可能遇到的典型问题,比如权限设置或报警疲劳。</think>以下是关于**ElasticsearchES异常情况报警**的详细解析,涵盖核心机制、典型方案与实操步骤: --- ### 一、异常报警的核心逻辑 异常报警的本质是**实时检测ES中的数据变化**(如错误日志、性能指标异常),并通过预设规则触发通知。其流程分为三阶段: $$ \text{数据采集} \Rightarrow \text{规则匹配} \Rightarrow \text{告警触发} $$ --- ### 二、ES异常报警的典型方案 #### 1. **内置方案:Watcher(告警插件)** - **功能**:ES官方插件,支持定时查询+条件判断+通知(邮件、Webhook等)。 - **特点**: - **优点**:集成度高,支持复杂条件(如连续N次触发)。 - **缺点**:企业版功能(开源版需替代方案),配置复杂度高。 **Watcher配置示例**: ```json PUT _watcher/watch/error_log_alert { "trigger": { "schedule": { "interval": "1m" } }, // 每分钟检查一次 "input": { "search": { "request": { "indices": ["logs-*"], "body": { "query": { "match": { "message": "ERROR" } } } } } }, "condition": { "compare": { "ctx.payload.hits.total": { "gt": 0 } } }, // 匹配结果>0时触发 "actions": { "send_email": { "email": { "to": "admin@example.com", "subject": "发现ERROR日志", "body": "近1分钟发现{{ctx.payload.hits.total}}条错误日志" } } } } ``` #### 2. **开源替代方案:ElastAlert** - **功能**:YAML配置规则,支持频率、阈值、变化率等检测模式。 - **特点**: - **优点**:开源免费,社区支持丰富,灵活性高。 - **缺点**:需独立部署,维护成本较高。 **ElastAlert规则示例(YAML)**: ```yaml name: "High Error Rate" type: frequency index: logs-* num_events: 10 # 10分钟内出现超过5次ERROR则告警 timeframe: minutes: 10 filter: - query: query_string: query: "message:ERROR" alert: - "email" email: - "admin@example.com" ``` #### 3. **自研方案:Percolator + 外部服务** - **原理**:利用ES Percolator实时匹配文档,通过外部服务(如Kafka+自定义脚本)触发告警。 - **适用场景**:高频实时检测(如每笔交易日志即时分析)。 **流程示例**: ```plaintext 1. 注册异常查询到.percolator索引 → 2. 日志写入ES → 3. Percolate检测匹配 → 4. 匹配结果推送至Kafka → 5. 消费消息并发送告警 ``` --- ### 三、核心优化策略 #### 1. **降低误报率** - **策略**: - 组合多条件(如`ERROR + status:500`)。 - 设置缓冲期(如连续3次触发才告警)。 - 使用机器学习模型(ES的Anomaly Detection功能)。 #### 2. **提升性能** - **方法**: - 索引按时间分片(如`logs-2023-08-01`),缩小查询范围。 - 使用`keyword`类型替代`text`避免分词开销。 - 限制返回字段(`_source filtering`)。 #### 3. **分级告警** - **规则分层**: ```json { "critical": { "query": "ERROR AND priority:CRITICAL", "channel": "短信" }, "warning": { "query": "WARN", "channel": "邮件" } } ``` --- ### 四、典型异常检测场景与规则 | **场景** | **检测规则示例** | **通知方式** | |------------------------|-------------------------------------------------------|--------------------| | 服务错误日志激增 | 5分钟内`ERROR`日志数 > 50 | 邮件+Slack | | 慢查询超阈值 | 平均响应时间 > 2秒且请求量 > 100/分钟 | 企业微信 | | 磁盘使用率过高 | `node.stats.fs.used_percent` > 85%持续10分钟 | 短信+电话 | | 索引写入速率突降 | 写入速率下降超过50%(对比前1小时基线) | 邮件 | | 安全审计失败 | `event.action: "authentication_failed"` 出现频率突增 | SIEM系统集成 | --- ### 五、告警通道集成 1. **邮件通知**:直接通过SMTP配置(Watcher/ElastAlert均支持)。 2. **即时通讯工具**: - **Slack**:通过Webhook发送JSON消息。 - **企业微信/钉钉**:调用API发送Markdown格式告警。 3. **电话/短信**:集成第三方服务(如阿里云短信、Twilio)。 4. **自动化修复**:触发预置脚本(如重启服务、扩容ES节点)。 --- ### 六、常见问题与解决 1. **告警延迟高** - **原因**:Watcher轮询间隔过长或ES集群负载高。 - **解决**:缩短检测间隔,优化ES查询性能。 2. **误报频繁** - **原因**:规则过于宽泛或日志格式不规范。 - **解决**:细化过滤条件,清洗日志字段。 3. **权限不足** - **场景**:开源版ES无法使用Watcher。 - **替代方案**:ElastAlert或自研Percolator方案。 4. **报警疲劳** - **策略**:合并重复告警,设置免打扰时段,动态调整阈值。 --- ### 七、最佳实践 1. **测试验证**: - 使用历史数据回放验证规则有效性。 - 模拟异常场景(如手动插入ERROR日志)。 2. **监控告警系统自身**: - 对ElastAlert/Watcher的运行状态做监控(如进程存活、资源占用)。 3. **文档化与版本控制**: - 所有告警规则需注释并纳入Git管理,避免配置丢失。 --- 通过合理设计规则、选择适配工具并持续优化,ES异常报警系统可显著提升运维效率,实现从被动响应到主动预防的转变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值