L64 / Azure Storage · Storage Internals / System Design

Microsoft Storage:Metadata 与 Data 分离后,怎样保证读写与恢复

以不可变数据块和原子发布清单构造读写路径,解释孤儿块、旧版本、故障恢复与持久ACK。

题目重点:以不可变数据块和原子发布清单构造读写路径,解释孤儿块、旧版本、故障恢复与持久ACK。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练对象存储模型:data为不可变chunk,metadata为object_id、generation、chunk manifest与状态;更新创建新generation。
  • 同一对象发布清单原子,多个对象不提供跨对象事务;ACK后的持久性故障域必须事先明确。
  • metadata的强一致发布与data副本就绪是不同阶段,不能用‘都复制了’省略失败窗口。

解题路线

  1. 写路径先创建upload id,传块并核checksum,达到规定数据副本/故障域条件后提交manifest。metadata用条件generation更新,发布之后才ACK。chunk成功但manifest未提交是未发布写,读取不应看见半文件。
  2. 读路径读取已发布manifest及generation,然后从data节点取相应不可变块并核checksum;缓存manifest带版本,缓存旧manifest读取完整旧版与读到半新半旧不同,明确允许多旧。
  3. 更新与删除使用新generation/tombstone。并发客户端通过if-match约束,避免旧写覆盖新写;未ACK操作可能已发布,重试必须按upload/op id查结果,不能新建第二对象。
  4. 故障恢复分别对metadata日志/快照与data块进行校验和复制修复。返回成功的写若丢metadata或数据任一层就不可读,持久性预算必须覆盖两层依赖;不能只谈块副本数。
  5. 垃圾回收清理未发布孤儿块和不再引用旧generation,用宽限期、活跃upload标记及引用/快照协议防止删仍被读或上传的块。GC崩溃可重试,先标记候选再安全删除。
  6. 性能取舍测manifest查询延迟、块吞吐、小对象元数据占比、写放大与恢复带宽;跨域复制提高耐久但增加ACK延迟。热点manifest可缓存,条件写与授权仍需权威路径。

手动走一遍

训练例上传两块c1/c2,c1成功后客户端断线;对象未发布,读旧generation或404,不读c1半文件。重连用同upload id续传c2并提交manifest。如果commit已成功但ACK丢失,查询upload结果返回同generation;GC不能在恢复窗口删除c1。

规模与取舍

大对象O(数据字节)传输,manifestO(chunk数);小对象可能主要受metadata操作与复制往返支配。恢复与GC按未同步/候选字节计成本,不能用O(1)API查找掩盖实际I/O。

易错点与追问

容易失分的边界

  • 块上传完便ACK,metadata仍未持久发布。
  • cache把不同generation块混读。
  • GC见无manifest就立即删除尚在上传的块。
  • 只备份data忽略metadata恢复。

继续深挖

  • manifest已发布但一个data副本丢块,怎样选回源/修复?
  • 同一对象两个并发upload哪个能提交?
  • 删除后旧版本读者还能访问多久?
  • 小对象高QPS下metadata怎样分片与缓存?
✓已复制微信号!