SLS写入超限优化方法:Shard分裂与并发调优指南
业务日志量在高峰期陡增,SLS写限流导致的WriteQuotaExceeded报错常让人措手不及。SLS写入超限优化方法的关键不在单纯扩Shard,而在于理解Shard配额机制与客户端并发模型。云老大在实战排查中发现,多数超限源于对这两个维度的误判。本文从报错识别、分裂操作到并发调优,给出可落地的思路。
一、认识SLS写入流量超限及常见报错
1. 什么是流量超限
SLS写入流量超限指数据写入速率超过Logstore服务端的预设配额。这里的核心变量是Shard,每个Shard都对应独立的写入能力限制,包括网络带宽和请求次数。当Shard数量不足、并发分布不均或单请求过大时,服务端便会触发限流,直接表现为HTTP 401/403或Throttle响应。
2. 报错信息示例
日常运维中,最典型的报错是WriteQuotaExceeded和Throttle。业务高峰时段,日志客户端批量提交后频繁收到这类异常,数据入库延迟被拉大。如果同时观察监控大盘,写入拒绝数会明显飙升。值得注意的是,401/403并不都是权限问题,也可能是配额耗尽后的服务端拒绝,需要结合具体错误码区分。
3. 超限的常见原因
超限原因通常有三类:Shard数量不够导致总配额不足;日志分布不均匀造成单个热Shard被打满;客户端请求过于碎片化,即使Shard充足,请求次数配额也被瞬间耗尽。很多团队只关注第一类,忽略了后两类——这也是“分裂后仍然超限”的现象普遍存在的根源。
二、Shard数量与写入能力的关系
SLS的写入超限,表象上是报错,本质上是配额问题。要理解配额,就必须先理解Shard。很多用户把Shard简单等同于「分区」,这不够准确。在日志服务架构里,Shard是数据写入和读取的基本并发单元——它同时决定了你能写入多快、读取多并行,也直接关联计费。写不进去、读不出来、费用飙升,三个问题的根源往往都指向同一件事:Shard的规划出了问题。
1. Shard是什么:不只是「分区」
Shard在物理上承载着日志数据的哈希区间,每条日志通过MD5 Key映射到特定Shard。这个机制决定了它不仅是存储单元,更是配额单位。每个Shard都有独立的写入配额——包括网络带宽和API请求次数两个维度。单Shard的带宽配额通常在5MB/s左右(具体数值以官方文档为准),请求次数配额则是固定的每分钟请求数上限。
这里有一个容易被忽略的关键点:请求次数和带宽是两条独立的配额线。带宽打满会触发限流,请求次数打满同样触发。很多用户把日志批量打包,以为带宽没问题就万事大吉——但小请求高频次仍然会打爆请求次数配额。这也就是为什么素材中反复强调「并发小请求合并成少量大请求」的原因,它直接作用于请求次数这条配额线。
2. 写入并发如何影响:数量与分布的双重博弈
写入并发对Shard能力的影响,可以从「总量」和「分布」两个维度来拆解。
总量维度:假设一个Logstore有4个Shard,你的峰值写入带宽是15MB/s——单看总量,15MB/s除以5MB/s似乎只需要3个Shard。但实际写入不会均匀分布。如果写入端是多个客户端并发发送小请求(比如每条日志一次HTTP调用),请求次数配额会先被打满,此时即使带宽还有余量,服务端也会返回WriteQuotaExceeded。这也是为什么说「Shard数够了但依然限流」——瓶颈不在Shard数量,而在请求模式。
分布维度:这涉及数据倾斜。如果业务日志没有设计分区键,日志会随机哈希到所有Shard上,分布相对均匀。但如果使用了时间戳等单调递增的值作为路由Key,数据会持续写入同一个MD5区间——大量日志涌向一个热Shard,其余Shard空闲,最终这个热Shard先达到配额上限触发限流。此时继续分裂Shard也无法解决问题——分裂后热数据的哈希区间不变,还是会写入同一批新Shard。
3. 如何计算所需Shard:先算配额,再算分布
计算Shard数量时,建议拆成三步走:
第一步,算带宽:取历史峰值写入流量(MB/s),除以单Shard带宽配额,得出基准Shard数。注意这里要用「峰值」,而非平均值——大促或定时任务触发的流量尖刺才是超限的主因。建议在此基准上预留20%~30%冗余。
第二步,算请求次数:评估你的写入端请求模式。如果使用原生API直写且批量大小偏小(比如每条请求仅几十KB),请求次数配额可能先于带宽打满。这种情况需要额外增加Shard,或者改造为Producer模式合并请求。建议用「预估峰值请求数/单Shard请求配额」校验,取与带宽计算结果中的较大值。
第三步,看分布:这一步依赖业务侧的分区键设计。如果日志中有高基数标识(如订单ID、用户ID),可以设计路由规则均匀哈希。如果没有合适的路由键、只能随机写入,Shard数量略高于理论值即可;如果有热Key无法规避,那么扩容不能解决根本问题,需要优先解决写入端的数据分流逻辑。
从实操角度看,这三步走完得到的Shard数量,才是一个相对可靠的容量基线。很多团队只做了第一步(带宽估算)就扩容上线,上线后发现请求次数超限或者热分区倾斜,再回头调整,反而耽误了大促窗口。这本质上不是「容量不够」,而是「容量规划模型不完整」——缺少了对请求模式和写入分布这两个变量的评估。
三、分裂策略:如何手动与自动扩容
SLS 的写入超限,本质上不是“机器不够”,而是 Shard 配额被打满。Shard 是日志服务处理数据的基本分区单位,每个 Shard 都有独立的写入能力配额。把 Shard 数量从 8 个调到 16 个,看起来是简单的数字变化,但实际涉及 MD5 Key 范围重排、服务端负载均衡和计费变化,并不像“加两台机器”那么直观。分裂策略的核心,是先判断流量峰值落在哪个维度:是带宽先到瓶颈,还是请求次数先超限。
1. 手动分裂:什么时机拆,拆多少
手动分裂适合流量可预期的业务,比如大促、定时任务、每日凌晨的数据集中上报。先看历史监控里的写入峰值,通常取最近 7 天或 30 天的最高值,按“预估峰值 / 单 Shard 能力 × 1.2”计算基准 Shard 数量。例如,某个 Logstore 的日常写入峰值是 40 MB/s,单 Shard 按官方给出的参考值 5 MB/s 估算,至少需要 8 个 Shard;如果要撑住 1.5 倍突发,建议拆到 12~14 个,而不是直接翻倍到 16 个。
这里要特别提醒:分裂不是瞬间生效。服务端需要重新分配 Key 范围,并将旧 Shard 的数据逐步迁移到新 Shard,期间旧 Shard 的配额仍然存在,但新 Shard 的写入能力并不会立刻全部可用。如果业务流量已经逼近限流阈值才去点击分裂,大概率还是会先收到一批 WriteQuotaExceeded。所以,手动分裂必须提前,不能把它当应急手段。
另一个容易被忽略的点是:分裂时选择哪个 Shard 很重要。如果某几个 Shard 写入明显高于其他 Shard,说明存在数据倾斜。此时应该针对热点 Shard 做分裂,而不是均匀地拆所有 Shard。比如订单日志按订单 ID 哈希写入,理论上会散落到所有 Shard;但如果某个大客户单独占用一个 Route Key,对应的 Shard 就会持续过热。这时即使总 Shard 数足够,热点 Shard 依然会先触发限流。
2. 自动分裂:可以依赖,但不能迷信
自动分裂的设计初衷,是应对不可预测的流量毛刺。SLS 的自动分裂机制会在满足条件时,把写满的 Shard 拆成多个新 Shard,但它的触发条件和分裂数量都是有限制的。简单说,自动分裂是“先撞上限流再扩容”,或者更准确地说,它是在流量已经超过某个阈值后才开始动作,而不是提前预判。
在实战中,自动分裂更适合两类场景:一类是业务流量长期缓慢增长,但无法预估具体时间点;另一类是人为值守成本高的中小团队,至少保证极端情况下不会完全写不进去。但对大促、秒杀这类瞬时流量,不能指望自动分裂解决问题。流量在几分钟内翻 5 倍,自动分裂从触发到新 Shard 就绪可能需要更长时间,期间写入请求已经堆积在客户端缓冲区。
云老大在协助多个团队排查 SLS 写入超限时,看到过一种典型误判:认为开启了自动分裂,Shard 数量就会自动适配业务峰值。实际结果是,自动分裂给出的新 Shard 数量远小于需要,并且分裂后没有及时观察写入热点,导致一边限流一边产生大量空 Shard,成本上升但问题没解决。合理的做法是把自动分裂当作兜底策略,同时用监控告警覆盖“写入请求次数、写入流量、Shard 写入热点”三个指标,在限流出现之前就介入。
3. 分裂后的三个隐藏问题
第一个是分区键导致的热点不会因为分裂自动消失。分裂只改变 Shard 的 Key 范围,不改变数据写入的路由规则。如果所有日志都使用同一个 Route Key,写入请求只会落在对应的少数 Shard 上,其他 Shard 即使扩容了也是空闲状态。这种情况下,需要重新设计 Route Key,把写请求分散到更多 Shard 上。
第二个是“Shard 够了”不等于“配额够了”。SLS 的写入配额通常包含流量和请求次数两个维度。如果业务以小日志为主,比如一条日志只有几百字节,但每秒请求次数很高,请求次数维度可能先被打满,而流量维度看起来还很健康。这时单纯增加 Shard 并不能解决问题,需要调整客户端的批量聚合参数,把多个小请求合并成大的批量请求,降低请求次数消耗。
第三个是容量冗余会直接反映在账单上。Shard 数量上去了,如果业务峰值只持续一两个小时,剩余时间大部分 Shard 都处于低利用率状态。峰后通过 OpenAPI 或控制台适时收缩 Shard 数量,并且持续观察一段时间内的写入趋势,避免为了“可能再涨一波”而长期保留过高的配额。从成本控制角度看,Shard 分裂和合并应该是一对常态操作,而不是大促前后的临时动作。
在这一点上,云老大在日志服务运维项目中的经验是:把分裂/合并流程脚本化,用定时任务或弹性伸缩策略来触发,而不是靠运维同学在半夜盯监控手工操作。那些能在业务增长时保持写入稳定的团队,通常不是 Shard 数量给得最多,而是对流量模型和配额维度有更清楚的判断。
四、优化写入并发与消费端配置
提升 SLS 写入能力的核心,除了调整服务端的 Shard 配额之外,更重要的是让客户端把数据"喂"得更高效。假设后端容量已经扩容到位,上游生产者却仍在用短连接、小报文的方式频繁击打服务端接口,限流问题并不会因为 Shard 增加而消失。只有在服务端配额和客户端参数两个维度同时发力,才能真正化解 WriteQuotaExceeded 与 Throttle 报错带来的拥堵。
1. 调整 Producer 参数
很多团队踩过同一个坑:明明 Shard 扩了,控制台写入流量曲线却依旧顶着上限走平,客户端还在不断报错。查看日志后发现请求次数配额被打满——单分区每秒允许的 API 调用次数有限,如果 Producer 的请求模型没有被优化,每秒成千上万个小请求很容易把配额窗口消耗殆尽。
官方 Producer SDK 的默认参数对吞吐场景做了基础适配,但距离生产环境的理想状态仍有距离。在 Java 和 Python 客户端中,比较关键的调整项包括:
- maxRetryTimes:默认值为 3 到 5 次。在超限场景下建议调大到 8 到 10 次,配合指数退避策略,避免因瞬时抖动导致数据直接落盘失败。
- lingerMillis:默认值通常在 100ms 级别。如果日志采集端内存充裕且对秒级延迟不敏感,可以拉升至 500ms 或以上,让 Producer 在内存中聚合更多日志再一次性提交。
- maxIOBufferSize:当客户端内存缓冲偏小时,高频写入场景会出现"缓冲满→触发阻塞→业务线程等待"的连锁反应。按照单核 64MB 的参考值做初步设定,再结合业务线程数微调。
真实的电商大促场景里,一 client 节点吞吐从 12 MB/s 提升到 30 MB/s,往往不是因为后端扩容,而是把 lingerMillis 和批量阈值调大后,请求次数下降了一个数量级。
2. 合理设置批量大小
批量大小和请求次数是一道简单的数学题。SLS 服务端的配额限制描述为"每 Shard 支持每秒 N 次写请求",它并不限制单次请求的包体大小(只限制单次 5MB 上限)。在每次写入数据量不变的情况下,把 1000 条 1KB 的日志合并为一条 1MB 的请求,和拆分为 1000 条独立请求相比,后者消耗的配额次数是前者的 1000 倍。批量设置的价值,就是在延迟容忍度允许的范围内,尽可能压缩请求次数。
这里需要区分"业务侧批量"和"SDK 侧批量"。业务侧批量指的是应用在内存中先攒一批日志再交给 SDK;SDK 侧批量则是 Producer 通过 batchSize 和 lingerMillis 两个参数协同控制的聚合行为。只调 batchSize 而 lingerMillis 过短,聚合窗口还没填满就发出去了,等于是白调。
从实践数据来看,lingerMillis 设在 200ms、batchSize 设在 1MB 组合下,整体吞吐是默认参数组合(50ms/512KB)的两倍以上。但要注意,这个收益在低 QPS 场景下并不明显,因为请求次数本身就不高。建议通过监控曲线确认当前是否处于配额瓶颈中,再决定是否值得调参,避免为了优化而优化。
3. 使用分区键均衡
Shard 分裂解决了"总数不够"的问题,但当数据写入呈明显的头部集中特征时,分裂后的效果会大打折扣。数据分区的策略是按 MD5 Key 的区间路由的,若业务没有显式指定路由键,Producer 会对日志内容做哈希,整体趋向均匀。问题出在许多业务在结构设计上天然携带热点——比如同一台机器的日志专门写固定 Key、某个大客户的日志量占了总量的一半以上。
最佳实践是调用 Producer 的 PutLogs 接口时显式设置 topic 或 routeKey,原则如下:
- 按高基数维度设计分区键:比如用户 ID、订单 ID、设备 ID,这些字段的取值空间足够大,能够均匀打散到所有 Shard。
- 坚决避开单调递增的时间戳和序列号:这些值会持续落在一个固定区间内,永远走同一个 Shard。
- 业务维度比技术维度更可靠:如果日志能自然关联到具体的订单或用户,优先以它作为路由键,而不是靠随机数凑散列效果。
某头部物流企业在做运单轨迹日志接入时,当初用时间戳做路由键,晚高峰时段单个 Shard 写入量比平均高出 7 倍,限流持续了三个小时。更换为运单号哈希路由后,写入热点直接消除,客户端重试率下降了约 90%。
服务端扩 Shard + 客户端调并发 + 分区键打散,是一条完整的链路。很多客户在实际运维中把三者拆开来做,结果总是差一步才能解决问题。云老大在做技术保障服务时,会先帮客户做一次写入链路的诊断,排查请求次数配额和流量配额的分配比例,再针对性调整 Producer 参数和路由策略——这种从整体视角出发的调优方式,往往比单纯在控制台增加 Shard 更有效果。
下一部分讨论常见的操作误区和隐蔽问题,比如自动分裂触发时机不达预期、消费端 Shard 租约不足导致的隐性积压,以及如何设计一套不容易误判的容量监控方案。
五、监控与告警:预防再次超限
前面几节讲的 Shard 分裂和 Producer 参数调优,本质上都是“事后补救”——流量已经打上来,限流已经发生,你才去扩分区、改参数。但生产环境的稳定性,靠的不是手速,而是提前发现风险的能力。这一节把监控和告警的落地方法讲透,目标是让超限问题在影响业务之前就被拦截掉。
1. 监控关键指标:别只盯着“写入量”
很多团队监控 SLS,只看一个“写入流量”曲线,这是远远不够的。写入流量只是表象,真正决定你是否会触发限流的是“请求次数配额”和“Shard 分布”。建议至少盯住以下四个维度的指标:
第一,服务端写拒绝数(WriteQuotaExceeded)。 这是最直接的超限信号。注意,不要把“拒绝数”和“重试数”混为一谈。客户端 SDK 通常会自动重试,控制台上看到的重试次数可能很高,但服务端实际拒绝的请求数才是配额是否打满的真相。建议将拒绝数按分钟聚合,如果连续 3 分钟大于 0,就说明配额已经处于紧绷状态。
第二,单 Shard 的写入热点分布。 这是最容易被忽视的指标。很多团队看到总写入量没过阈值就放松警惕,但 SLS 的配额是按单 Shard 计算的。假如你有 10 个 Shard,某个 Shard 因为日志中某个固定字段(比如 IP 或订单号)被哈希到了同一个分区,它的请求次数可能已经打满,而其他 9 个 Shard 还在空闲。通过查看每个 Shard 的读写流量监控,能直接定位到这个热点 Shard。这里有一个经验值:如果单个 Shard 的请求次数占到了总配额的 80% 以上,即便总流量不高,也需要考虑拆分或调整路由键。
第三,消费端延迟。 写入超限的影响不只是“写入失败”,还会引起数据积压,进而拉长消费链路(如投递到 OSS、离线计算等)的延迟。如果只盯写入端监控,消费端延迟突然升高时你往往毫无察觉。建议把 Logstore 的消费组延迟(毫秒/秒)和投递任务延迟也加进监控大盘,与写入流量放在同一个视图里。写入超限后,这个指标通常会在 5 分钟内出现波峰。
第四,客户端内部指标。 Producer SDK 通常内置了 Metric 输出能力,比如发送队列积压数、单次批量大小、重试次数分布等。这些指标反映了客户端视角的“体感”。如果服务端没有出现拒绝,但客户端重试却在增加,说明网络链路或服务端处理能力存在瓶颈,这类问题同样是隐性的写入超限诱因。
2. 设置告警阈值:分三级,别搞“一刀切”
告警阈值设置过松,等收到通知时已经超限了;设置过紧,告警太频繁,团队很快就“狼来了”失去敏感性。建议按以下三级策略来设定:
P1(红色告警):WriteQuotaExceeded 出现即告警。 只要服务端写拒绝数大于 0,就立即通过短信/电话通知到 Oncall 同学。这个信号说明当前配额已经打满,如果不处理,数据延迟会持续扩大。
P2(橙色告警):单 Shard 请求次数达到配额的 70%,且持续 5 分钟。 70% 是一个提前量。当单 Shard 达到 70% 配额时,留给你的响应时间大约还有 10-15 分钟(取决于业务流量增长斜率)。你可以在这个窗口内执行 Shard 分裂或调整路由策略。特别注意,告警条件里要加上“持续 5 分钟”这个条件,避免因瞬时毛刺产生误报。
P3(黄色告警):消费延迟超过 1 分钟,且持续 10 分钟。 此阈值意味着数据链路已出现积压,但未造成严重故障。建议先看是写入端超限导致的积压,还是消费端计算能力不足。如果是前者,应该触发 P1 流程;如果是后者,需要扩容消费者(比如增加投递任务的并发或分区数)。
3. 定期评估容量:用“波峰利用率”替代“肉眼观察”
与自建 Elasticsearch 不同,SLS 的容量管理是“按用量付费”的,这也意味着 Shard 数量与成本直接挂钩。很多团队在业务稳定后就不再关注容量规划,直到某次大促流量一冲就挂了。建议每两周做一次容量复审,重点看两个指标:
- 波峰利用率:过去 14 天中,每天写入量最高峰的 15 分钟平均值,与当前 Shard 总配额的比值。如果这个比值超过 60%,下一个高峰(比如月末结算、节假日活动)可能就会触碰上限。
- 写入形态变化:对比上周与上上周的请求次数与流量的比值。如果请求次数增长明显快于流量增长,说明业务在产生更多“小请求”(比如日志量没变,但调用次数变多),这时即使总流量没到阈值,也可能先打满请求次数配额。
评估之后,如果发现某段时间的流量波峰是周期性出现的(比如每月 25 号的对账任务),应该把“提前 2 小时自动分裂 Shard、峰后 2 小时自动合并”写成定时运维脚本。不要每次都手动操作——手动操作不仅慢,而且容易忘记合并回来,白白增加成本。
在实际协助企业客户处理这类容量规划问题时,我们通常会让客户提供近两周的控制台监控截图,结合他们业务侧的排期表(比如大促、新品发布)来预估扩容需求,这比单纯看历史曲线更准确。如果你所在的团队对系统稳定性要求较高,又不想频繁手动处理这类扩容缩容操作,市面上的云老大等云管理服务商也有专门的托管巡检方案,可以作为内部 SRE 团队的一个补充参考。
到此,针对 SLS 写入超限的优化方法已经形成了一个完整闭环:从监控发现风险,到提前扩容 Shard,再到调整客户端参数,最后通过告警体系和周期评估预防复发。下次再遇到超限告警,你可以先冷静判断“是 Shard 数量不够,还是数据分布不均,或是客户端配置不合理”——这三个方向,需要的是完全不同的处理动作。记住,一次超限并不可怕,可怕的是每次都靠紧急扩容来“救火”,却从来没有复盘过:为什么监控没提前发现?为什么容量规划没有覆盖这次流量峰值?把这几招用到位,SLS 的写入超限问题,完全可以变成「车到山前必有路」的常规运维项,而不是深夜两点让人冒冷汗的 E-级别故障。
六、实战案例与操作建议
1. 典型场景演示
某电商平台在大促前一周发现日志服务写入频繁出现延迟,监控大盘显示 WriteQuotaExceeded 错误码在高峰时段占比超过总请求量的 15%。该业务当时配置了 8 个 Shard,日常写入流量约为每 Shard 配额上限的 40%,但在大促压测期间流量突增 3 倍,直接触发了服务端限流。
处理过程分为三步。第一步:基于压测峰值反推 Shard 需求量。压测时峰值写入流量约为 280 MB/s,单个 Shard 在写入压缩后的带宽配额按 5 MB/s 估算,得出理论 Shard 下限为 56 个,实际按 80 个 Shard 提前扩容。第二步:改造客户端为 Producer 模式,将 batchSize 从默认 1 MB 调至 4 MB,lingerMillis 设置为 200 毫秒,发送线程数从 2 提升至 8。调整后单请求的平均日志条数从约 50 条提升至 800 条,请求次数配额消耗降至原来的 1/10 以下。第三步:为订单、支付等核心链路日志增加 order_id 作为分区键,使写入分布更均匀,避免个别 Shard 因高热度 Key 成为瓶颈。
扩容后有两点观察值得参考。一是 Shard 分裂后服务端存在一段负载均衡重排时间,写入压力不是立刻平摊,期间仍可能有局部限流,建议在业务低峰期操作预留缓冲。二是扩容后成本明显上升,大促结束后未及时缩容,导致该月日志服务费用比上月多出约 60%。后来改用定时脚本在大促结束后自动合并 Shard,成本才回落到正常水平。
另一个常见场景是数据消费端积压。某金融客户写入已经正常,但投递到下游分析系统的延迟持续走高,检查发现消费组的 Shard 租约数为 2,远小于 Shard 总数 16,并行度严重不足。将消费组 Shard 租约数提升至与 Shard 数量匹配,同时增加消费端 CPU 资源后,投递延迟从 30 分钟降至 2 分钟以内。
2. 最佳实践总结
将上述案例中的措施归纳成五条可复用的操作规范:
- 扩缩容要成体系:Shard 分裂不是孤立操作,需要同步评估客户端写入参数和消费端并行度。建议将三者纳入同一份变更方案,避免出现“写入不超限了,消费又积压了”的连锁问题。
- 容量规划要基于峰值,而非均值:日常平均流量 40 MB/s、峰值 280 MB/s 的业务,如果按均值配置 Shard,超限是必然结果。建议以峰值流量的 1.2~1.3 倍作为 Shard 配置基线,并保留快速扩容的自动化手段。
- 客户端参数调优是隐性红利:在 Shard 配额不变的情况下,仅通过调整 Producer 的批量大小和发送线程数,就能将有效吞吐提升数倍。每次调整后应观察一周的限流率与重试率,确认参数在业务周期内稳定。
- 分区键设计决定流量分布:用业务主键(用户 ID、订单 ID)作为分区键,写入分布最均匀;避免使用时间戳、地域 ID 等单调或低基数维度做分区键。若无法避免,至少确保单一分区键的写入量不超过单 Shard 配额。
- 监控要能回答“接下来怎样”:不只监控当前的超限次数,还要监控 Shard 写入热力分布、客户端重试率、消费组延迟的变化趋势。建议设置分级阈值:接近配额 70% 时告警,连续 5 分钟超过 85% 时触发自动扩容流程。
对于一个长期稳定运行的系统,这些实践应该固化为日常运维操作,而非每次超限后的应急响应。
3. 常见问题 FAQ
Q:开启自动分裂后还需要手动扩 Shard 吗?
需要。自动分裂的触发条件有延迟,流量突刺瞬间大概率先被限流,分裂完成后的负载均衡也需要时间。自动分裂更适合作为兜底手段,主动的容量规划仍应以手动扩缩容为主。
Q:分裂后写入仍然超限,可能是什么原因?
首先确认单 Shard 写入是否出现热点。如果数据没有使用分区键,默认随机哈希在 Shard 数量足够时分布是均匀的;若业务中某个 Key 写入量极大(如单个 IP 的日志),则无论如何分裂,该 Key 所在的 Shard 都会持续超限,需要从业务侧拆分路由 Key。其次检查 Producer 的 maxRetries 和退避策略,如果重试过于激进,可能在服务端尚未恢复时反复撞击配额。
Q:如何判断 Shard 数量需要缩减?
观察连续 7 天(包含完整业务周期)的 Shard 写入吞吐与请求次数,如果峰值利用率长期低于 30%,且未来没有可预见的业务增长,就可以考虑合并。但需要注意,合并 Shard 是一次性操作,与分裂不同,需要确认 Logstore 的写入和读取链路都处于稳定状态时执行。缩减时建议每次合并操作减少不超过总量的 25%,并观察 24 小时后再继续操作,防止业务突增时容量不足。
Q:写入端已经用了 Producer,还超限怎么办?
检查以下三个参数是否与实际流量匹配:lingerMillis 是否过短导致批量未满就发送;内存缓冲是否过小导致 Producer 内部频繁阻塞;发送线程数是否在多核机器上未充分利用 CPU。另外,确认服务端返回的限流错误码是请求次数超限还是流量超限,两者的调优方向不同(前者靠增大批量,后者靠增加 Shard 或压缩数据)。推荐在客户端启用内部 Metrics 输出,定位到具体是哪个维度打满配额。
Q:优化 Shard 和写入参数后,消费端还需要做什么?
需要。很多场景下写入优化完成,消费端又成了新的瓶颈。根据实际经验,投递延迟升高大多是消费并行度不足所致。建议将消费组的 Shard 租约数设置为与 Shard 总数级联调整,并在消费端增加延迟监控,将消费延迟控制在分钟级以内。数据从写入到可查询的链路都通畅了,才算完整的超限治理。
