来自 #139 的架构级评审建议。不阻塞合入,仅供参考是否有更好的架构解法。
💡 [建议 · 性能] maxScanResults=10000 硬编码,大范围扫撑爆单次响应 service/fsm.go:178
问题根因:maxScanResults 是包级常量(10000),作为截断上限防止 OOM。但未考虑单条 value 的大小:若每条 value 为 1MB,10000 条命中将产生 10GB 响应缓冲区,远超过上限的设计意图。截断发生在结果收集之后、序列化之前,内存已经爆了。
为什么低级解法不够:加一个总字节数上限(而非仅条目上限)是常见解法,但仍是事后截断——内存先爆。
架构级方案:改用字节预算 + 流式回传:在收集结果时同时累加 totalBytes,当超过 maxResponseBytes(如 64MB)时截断。或更根本地:改为流式编解码(边扫描边序列化边发 TCP),不保留全量结果在内存中。对于边缘设备,建议引入字节级预算而非条目级预算。
代价/收益:流式方案需改变当前收集→序列化→发送的同步模型,重构代价较大。字节预算方案只需在 KVServer.Scan 中增加一个 totalBytes 计数器 + 一个包级常量,改动小、收益明确。
💡 [建议 · 性能] maxScanResults=10000 硬编码,大范围扫撑爆单次响应
service/fsm.go:178问题根因:
maxScanResults是包级常量(10000),作为截断上限防止 OOM。但未考虑单条 value 的大小:若每条 value 为 1MB,10000 条命中将产生 10GB 响应缓冲区,远超过上限的设计意图。截断发生在结果收集之后、序列化之前,内存已经爆了。为什么低级解法不够:加一个总字节数上限(而非仅条目上限)是常见解法,但仍是事后截断——内存先爆。
架构级方案:改用字节预算 + 流式回传:在收集结果时同时累加
totalBytes,当超过maxResponseBytes(如 64MB)时截断。或更根本地:改为流式编解码(边扫描边序列化边发 TCP),不保留全量结果在内存中。对于边缘设备,建议引入字节级预算而非条目级预算。代价/收益:流式方案需改变当前收集→序列化→发送的同步模型,重构代价较大。字节预算方案只需在
KVServer.Scan中增加一个totalBytes计数器 + 一个包级常量,改动小、收益明确。