一、理解服务端(Grain、Silo)与客户端分布、通信交互

1.1、物理节点与 Grain 层次架构图

1.2、Grain 分布与通信细节图

二、一致性哈希(UniformHash)

哈希值是uint类型,取值范围为 0 到 4,294,967,295(即 2^32 - 1)。
IdSpan提供了比较、哈希和字符串转换方法,用于GrainId和GrainType的哈希值,Grain 均匀分配到不同 Silo 节点。

有两种算法XxHash32、JenkinsHash,XxHash32性能优于JenkinsHash。

2.1、XxHash32

概述:XxHash 是由 Yann Collet 开发的高性能非加密哈希算法,旨在提供比传统哈希(如 CRC32、MD5)更快的计算速度和更好的抗碰撞性。其中,XxHash32 是针对 32 位平台优化的版本,输出 32 位哈希值,常用于数据校验、哈希表构建、数据分桶等场景。

基于现代 CPU 特性优化(如 SIMD 指令),处理速度可达 5-10 GB/s(取决于硬件),适合高频调用的 Grain 路由场景。

应用场景:Grain 路由与负载均衡、流处理系统(Stream)。

2.1.1、Grain 路由与负载均衡

GrainId\GrainType\IdSpan三者关系:

GrainId=>GrainType+IdSpan;GrainType=>IdSpan

IdSpan的哈希值计算用XxHash32(非加密哈希算法):计算速度和更好的抗碰撞性。 XxHash32是一种生成 32 位哈希值的算法,其结果恰好可以用 C# 的uint类型取值范围。

为了跨平台数据(不同硬件架构、操作系统环境)一致性, XxHash32 哈希结果时考虑大小端(Endianness)问题;否则 同一Grain在不同节点上计算的哈希值不同,无法路由到正确的 Silo节点。

具体代码:

public static unsafe uint ComputeHash(ReadOnlySpan<byte> data)
{
    uint hash;
    XxHash32.TryHash(data, new Span<byte>((byte*)&hash, sizeof(uint)), out _);
    return BitConverter.IsLittleEndian ? hash : BinaryPrimitives.ReverseEndianness(hash);
}

2.1.2、流处理系统(Stream)

2.2、JenkinsHash

纯软件实现,采用逐字节处理,无法利用硬件并行性。早期版本的 Orleans 使用 JenkinsHash 作为默认算法,向后兼容性仍保留。

应用场景:成员表管理(MembershipTableManager)、系统目标路由(SystemTarget)

2.2.1、成员表管理(MembershipTableManager)

Silo 地址哈希。

Gossip 协议中的状态同步。

2.2.2、系统目标路由(SystemTarget)

内部组件寻址:为系统内部组件(如 MembershipSystemTargetGatewaySystemTarget)生成唯一 Grain ID。

系统消息路由:将系统消息(如心跳、负载信息)路由至正确的目标 Silo。

三、哈希环

3.1、物理 Silo 、虚拟节点、哈希环之间交互图

物理 Silo:SiloAddress 

虚拟节点:VirtualBucketsRingProvider

哈希环:IRingRange

3.2、虚拟节点哈希值计算,以及如何划分哈希环

虚拟节点哈希值计算:是根据其对的Silo地址(SiloAddress)哈希+虚拟节点索引计算的哈希值。

如:新Silo加入时,根据每个Silo虚拟节点数量的配置(numBucketsPerSilo),计算它所有虚拟节点的哈希值,如:

3.3、虚拟节点:VirtualBucketsRingProvider

它负责管理当前Silo节点(SiloAddress)的虚拟节点对应哈希环范围,同时包含集群中所有虚拟节点和Silo关系。

Silo增加和移除:

监控指标:

一致性哈希环(IConsistentRingProvider)还有一个实现方式是ConsistentRingProvider:它直接使用 Silo 地址进行哈希,适用于对负载均衡要求不高、Silo 数量较少的场景,或者对性能要求较高,不希望引入过多虚拟桶带来的额外开销的场景。根据配置启用不同实现。

3.4、哈希环:IRingRange

涉及接口\类:IRingRange\IRingRangeInternal\ISingleRange、SingleRange\GeneralMultiRange。

  • IRingRange 是最基础的接口,定义了检查值是否在范围内的方法。
  • IRingRangeInternal 继承自 IRingRange,并增加了计算范围百分比的方法。
  • ISingleRange 继承自 IRingRange,定义了单一连续范围的起始和结束边界。
  • SingleRange 类实现了 IRingRangeInternal 和 ISingleRange 接口,是单一连续范围的具体实现。
  • GeneralMultiRange 类实现了 IRingRangeInternal 接口,用于表示多个连续范围的集合。

RangeFactory工厂类,创建SingleRange或者GeneralMultiRange。GeneralMultiRange创建时,如果多个范围中有相邻虚拟节点会合并,与VirtualBucketsRingProvider中移除Silo后重新计算哈希环相对应。

 

3.5、物理 Silo:SiloAddress 

用于封装 Silo(Orleans 集群中的节点)的地址信息。

Endpoint:类型为 IPEndPoint,表示 Silo 的网络端点,包含 IP 地址和端口号。

Generation:类型为 int,表示 Silo 的生成号,用于区分不同版本或重启后的 Silo。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐