来自 #262 的架构级评审建议。不阻塞合入,仅供参考是否有更好的架构解法。
💡 [建议 · schema] MemTable 名不副实,实为整个 LSM 引擎 service/fsm.go:55
问题根因:PR 删除 Engine 后,KVServer 直接持有 *storage.MemTable,但 MemTable 自身持有 sst *SSTable 并负责 getFromSSTables/FlushToSSTable/CompactSSTable——它实际上承载了完整 LSM 引擎职责(内存表 + 磁盘层 + 归并),仅名字仍叫「内存表」。这个架构气味是 PR 自己注意到却未处理的——删除 Engine 是把「MemTable 事实上已是引擎」从一层封装里暴露了出来。
为什么低级解法不够:重命名(如改为 LSMEngine / Storage)能掩盖症状,但没有理清「内存表」与「引擎」既是不同抽象层级、又在当前实现里被强行耦合起来的矛盾。若未来需要独立的只读 memtable 或独立的 compaction 调度,当前耦合会阻塞改动。
架构级方案:拆分类型边界:将 SSTable 访问、元数据管理、compaction 调度从 MemTable 中提取到独立的引擎类型(如 LSMTree / Storage),MemTable 只保留 active/dirty 双表与吞吐;KVServer 依赖引擎接口而非具体 memtable。与删除 Engine 的方向一致,只是更进一步把「真实抽象」从实现中显式化。
代价/收益:代价:需对当前所有 Flush/Compaction 调用链做一次类型重构,测试与压测的构造点需同步调整;收益:消除「名字与职责不符」的误导,为将来独立的引擎扩展(如分层写缓冲、独立 compaction 队列)留出干净的接口边界。
💡 [建议 · schema] MemTable 名不副实,实为整个 LSM 引擎
service/fsm.go:55问题根因:PR 删除 Engine 后,
KVServer直接持有*storage.MemTable,但MemTable自身持有sst *SSTable并负责getFromSSTables/FlushToSSTable/CompactSSTable——它实际上承载了完整 LSM 引擎职责(内存表 + 磁盘层 + 归并),仅名字仍叫「内存表」。这个架构气味是 PR 自己注意到却未处理的——删除 Engine 是把「MemTable 事实上已是引擎」从一层封装里暴露了出来。为什么低级解法不够:重命名(如改为 LSMEngine / Storage)能掩盖症状,但没有理清「内存表」与「引擎」既是不同抽象层级、又在当前实现里被强行耦合起来的矛盾。若未来需要独立的只读 memtable 或独立的 compaction 调度,当前耦合会阻塞改动。
架构级方案:拆分类型边界:将
SSTable访问、元数据管理、compaction 调度从MemTable中提取到独立的引擎类型(如LSMTree/Storage),MemTable只保留 active/dirty 双表与吞吐;KVServer依赖引擎接口而非具体 memtable。与删除 Engine 的方向一致,只是更进一步把「真实抽象」从实现中显式化。代价/收益:代价:需对当前所有 Flush/Compaction 调用链做一次类型重构,测试与压测的构造点需同步调整;收益:消除「名字与职责不符」的误导,为将来独立的引擎扩展(如分层写缓冲、独立 compaction 队列)留出干净的接口边界。