Grain 目录实现

概述和体系结构

粒度目录 Orleans 是键值存储区,其中密钥是粒度标识符,值是指向活动接收器(可能)承载粒度的活动接收器的注册入口。

虽然 Orleans 提供默认的内存中分布式目录实现(如本文所述),但 grain 目录系统设计为可插式。 可以通过实现 IGrainDirectory 接口并将其注册到 silo 的服务集合中来创建自己的目录实现。 这允许使用不同存储后端或一致性模型的自定义目录实现,以便更好地满足特定的应用程序要求。 由于引入了新的强一致性目录,因此不需要外部目录实现,但 API 仍保持向后兼容性和灵活性。 可以按谷物类型配置谷物目录。

为了优化性能,Orleans 在每个独立单元中本地缓存目录查找。 这意味着,仅当本地缓存条目缺失或无效时,才可能需要远程目录读取。 此缓存机制可减少与粒度位置查找关联的网络开销和延迟。

最初,Orleans 实现了一个最终一致的目录,该目录的结构为分布式哈希表。 在 v9.0 中,这被基于两阶段虚拟同步方法的强一致目录取代。 它还作为分布式哈希表进行结构化,但通过虚拟节点提供改进的负载均衡。 本文介绍后一种较新的粒度目录实现。

分布式谷物目录

Orleans 内的分布式粒目录提供很强的一致性、负载均衡、高性能和容错能力。 实现遵循基于 虚拟同步方法的两阶段设计, 与垂直 Paxos 相似。

目录分区有两种操作模式:

  1. 正常作:分区在本地处理请求,而无需与其他主机协调。
  2. 查看更改:主机相互协调,以转移目录范围的所有权。

该目录利用 Orleans的强一致性集群成员系统,其中被称为“视图”的配置具有单调递增的版本号。 随着 silo 加入和离开群集,会创建连续视图,从而导致范围所有权的更改。

所有目录操作包括视图协调:

  • 请求包含调用方的视图编号。
  • 响应中包含分区的视图编号。
  • 视图编号不匹配会触发同步。
  • 请求在视图变更时自动重试。

这可确保目录分区的正确所有者处理所有请求。

分区策略

目录使用一致的哈希环进行分区,并将范围分配给集群中的活动节点。 对粒标识符进行哈希处理,以查找哈希值对应部分的环形区域所属筒仓。

每个活动 silo 都拥有预先配置的范围数量,默认为每个 silo 30 个范围。 这类似于 Amazon DynamoApache Cassandra 所使用的方案,其中为每个物理节点(主机)创建多个“虚拟节点”(范围)。

分区的大小取决于分区的哈希与下一个分区的哈希之间的距离。 在视图更改期间,范围可以在多个孤岛之间拆分。 这增加了视图更改过程的复杂性,因为每个分区必须可能与其他多个分区协调。

查看更改过程

目录分区(在 GrainDirectoryPartition中实现)使用版本化范围锁,以防止在视图更改期间对范围进行无效访问。 范围锁是在视图更改期间创建的,并在视图更改完成后释放。 这些锁类似于虚拟同步方法中使用的“楔子”。

发生视图更改时,分区可以增长或收缩:

  • 如果有新的仓式结构加入群集,则现有分区可能会缩小以腾出空间。
  • 如果某个节点退出集群,剩余的分区可能会扩展以接管遗留的区段。

目录注册必须在请求被处理之前从旧所有者转移到新所有者。 传输过程遵循以下步骤:

  1. 先前的所有者封闭了范围,并创建了其目录条目的快照。
  2. 新所有者请求并应用快照。
  3. 新所有者开始为范围的请求提供服务。
  4. 之前的所有者收到通知并删除快照。

恢复过程

当主机崩溃而不正确移交其目录分区时,后续分区所有者必须执行恢复。 这涉及:

  1. 查询群集中所有活动 silo 的 grain 注册信息。
  2. 重新生成受影响范围的目录状态。
  3. 确保没有重复的 grain 激活发生。

群集成员身份迅速更改时,恢复也是必要的。 虽然群集成员身份保证了单调性,但 silo 可能会错过中间成员身份视图。 在这种情况下:

  • 快照传输已被放弃。
  • 执行恢复,而不是正常分区到分区的交接。
  • 尽管缺少中间状态,但系统仍保持一致性。

群集成员身份的未来改进可能会通过确保所有孤岛查看所有视图来减少或消除这些方案。