milvus/docs/design_docs/dataservice_recovery_design.md
sunby 6dba0fd9cf
Add dataservice recover design docs (#5212)
This document includes changes about dataservice and new features 
to support the recovery after it crashed.

Signed-off-by: sunby <bingyi.sun@zilliz.com>
2021-05-18 11:20:26 +00:00

3.0 KiB
Raw Blame History

timetick 相关改动

Datanode发送timetick msg需要有channel的信息DataService根据channel来检查segment是否可以seal和flush

服务发现

DataService启动时检查是否有新的或重启过的DataNode如果有重启过的重新注册channel并seek到上次记录的位置

通过watch机制监听DataNode的状态如果DataNode下线其注册的channel重新分配到其他node并seek到上次的位置重新分配不一定现在做

如果监听到DataNode重新上线向其注册channel并seek到上次记录的位置

如果监听到有新的DataNode注册记录其状态后续向其注册channel或进行load balanceload balance不一定现在做

DataNode如果由于网络原因与etcd断开应该重启服务发现DataService会去重新注册channelDataNode不能重复监听相同channel

需要记录的信息

  1. cluster信息包括Datanode的节点及其上面的channel
  2. segment 分配信息最后一次分配的过期时间segment的上限等
  3. stats 和 segment flush channel最后位置
  4. DataNode向DataService发送channel的最后位置

重启恢复流程

  1. 内存状态恢复:

    1. 基本组件启动meta etcd等
    2. 恢复segment allocator和cluster状态
  2. 与DataNode节点交互

    1. 启动stats/segment flush channel并seek到上次记录的位置
    2. 启动timetick channel
  3. 与Master交互

    1. 启动时不需要和Master交互Collection信息为空需要用到时向Master请求并缓存
    2. 启动new segment channel
  4. 启动服务发现

目前channel注册是segment allocation驱动的每次请求segment时检查其channel有没有被注册没有则将其注册到DataNode并保存到本地。这里有个问题如果channel注册成功DataService挂掉了那么在重启后DataService并不知道已经注册成功来一个新的请求还是会去注册而且可能注册到不同的DataNode上面。类似Transaction的情况需要有一套机制保证原子性在多节点写入目前不太好解决。可以用以下步骤临时解决

  1. 在etcd上记录分配方法entry状态是未完成
  2. 向DataNode注册
  3. 在etcd上将entry标记为完成

重启时/分配时如果发现有未完成的entry重新向DataNode注册需要DataNode保证幂等性。

这样保证了一个channel只向一个DataNode注册如果DataNode挂掉或者与etcd断开如果需要重新分配到其他DataNode这些entry也跟着变。

DataService模块中有些策略是可能频繁改变的比如channel对DataNode的分配策略可以是随机/顺序/平均/根据collection分散等等策略比如检测到DataNode创建和下线可能会不处理/balance/将下线节点的channel转移到其他节点等。比如segment allocation可能会根据文件大小/条数等来确定是否关闭。实现应该把这些策略相关抽出来,方便以后修改。