如何避免EventhubTriggered Function App出现重复数据处理问题
Event Hub触发Function App重复处理问题解决方案
配置调整方案(降低重复出现概率)
你当前遇到的5%重复率远高于正常的至少一次交付基线重复率,可以先调整以下配置解决:
- 优化批量异常处理逻辑:当前
batchCheckpointFrequency=1的配置是合理的,只有整批处理完全成功才会提交检查点。如果你的批量处理逻辑中存在单条消息处理失败就抛出未捕获异常的情况,会导致整批检查点不提交,下次拉取重复处理整个批次。建议将单条消息的处理逻辑包裹异常捕获,只记录错误日志不抛出异常,确保整批处理完成后正常提交检查点。 - 固定Function App实例数:当前20个Event Hub分区对应20个实例是最优配比,如果开了自动伸缩,实例上下线会触发分区重平衡,重平衡过程中未提交的检查点会导致消息被新的所有者实例重复拉取。可以将Function App的最小实例数固定为20,关闭不必要的自动伸缩规则,减少重平衡触发频率。
- 调整拉取参数匹配:当前
maxBatchSize=100,可以将配套的prefetchCount参数设置为150~200,避免拉取批次超时导致的重复拉取。
跨批次重复数据识别方案
Function App本身没有内置跨批次去重能力,需要自行实现:
- 基于消息唯一ID去重:Event Hub的每条事件自带唯一
MessageId属性(发送端未自定义时系统会自动生成),你可以维护一个去重缓存(可用Redis或实例本地内存缓存),缓存已处理的MessageId,每次拉取批次后先过滤掉缓存中已存在的ID再处理,处理完成后将新的ID写入缓存。需要给缓存设置大于Event Hub消息保留时长的过期时间,避免缓存失效导致重复识别失效。 - 业务层实现幂等处理:这是最稳妥的处理方案,不管消息是否重复,处理逻辑执行多次的结果和执行一次完全一致。比如写入数据库时用业务唯一键做冲突校验,冲突直接跳过;或者使用upsert写入逻辑,重复写入也不会产生脏数据。
内容的提问来源于stack exchange,提问作者Jasmine
相关产品推荐
相关产品推荐

