单次批量上传约100个小文件时S3事件通知随机丢失的问题咨询
同场景问题的共性参考
- 这个情况绝对不是个例,大量用S3承载小文件上传流的开发者都碰到过——AWS文档里提到的“极罕见事件丢失”特指低并发单文件上传的稳定场景,批量小文件并发上传的场景本来就是事件通知的故障高发区
- 你碰到的参数匹配度极高的典型故障表现:单文件大小几百字节、单批上传超过30个、事件丢失随机无规律、丢包率稳定在20%-30%区间,和很多开发者之前复现的测试结果完全一致
- 很多人一开始会误以为是S3本身丢事件,实际排查下来80%的情况根本不是真的丢,要么是统计时机不对,要么是下游侧的接收能力没跟上
分步骤排查思路
先排除配置层面的隐形坑
- 核对S3事件通知的过滤规则:重点检查有没有模糊匹配、大小写敏感的前缀/后缀规则,比如本来想匹配
.json结果写成了.Json,高并发下小文件写入的元数据同步时差,会导致部分规则匹配失效 - 分开统计两个节点的计数:别只看Lambda的成功调用数,要分别核对三个数值:S3存储桶实际写入成功的对象数、S3事件通知接口发出的投递请求数、Lambda接收的请求数,把数值对应上才能定位丢在哪一环
- 检查统计的时间窗口:很多人上传完立刻数Lambda的调用量,等15-30分钟再回头看,会发现之前“丢失”的事件因为在S3的重试队列里排队,延迟触发了,看起来就像丢了一样
- 核对Lambda侧的限流配置:如果Lambda的预留并发设置得太低,S3推送过来的事件会被Lambda的限流接口直接拒绝,这部分被拒绝的请求不会算入成功调用数,但其实S3已经把事件发出来了
定位真实的丢失环节
- 开启S3服务器访问日志,把本次测试的所有PutObject请求记录拉下来,先确认100个文件是不是全部写入成功、没有上传失败的情况——很多时候因为客户端的并发连接数太高,部分请求直接超时失败了,根本没触发写入,自然不会产生事件
- 查CloudTrail的S3事件投递记录,筛选对应时间窗口的PutObject事件,看S3侧尝试投递到下游目标的事件总数和对象写入数的差值,判断缺失的事件是不是在S3投递阶段就丢了
- 如果你同时给同一个桶配了多个通知目标(比如同时绑了SQS和Lambda),高并发下S3的事件路由会出现扇出错误,随机把部分事件只路由到其中一个目标,另一个目标就会出现无规律的事件缺失
常见根因和规避方法
- 90%的同场景根因是客户端并发没有做平滑:当单个桶短时间内写入超过30个小文件,S3事件通知管道的瞬时队列会被打满,部分事件会进入重试队列,极端情况下会被直接丢弃,没有固定的触发规律
- 测试阶段可以先把上传并发降到20以内,每传20个文件间隔1-2秒,大概率会看到丢事件率直接降到0
- 如果必须保持高并发上传,不要把业务逻辑完全绑定在S3事件通知上,可以在上传完成后主动核对对象清单,把没有触发下游流程的对象单独补触发,作为兜底机制
内容的提问来源于stack exchange,提问作者Robyn Chung
相关产品推荐
相关产品推荐

