LocalGrainDirectory详解

LocalGrainDirectory 详解

LocalGrainDirectory是Orleans分布式系统中负责本地Grain目录管理的核心组件,它实现了分布式哈希表(DHT)风格的Grain定位服务。

类图

LocalGrainDirectory
-ILogger log
-SiloAddress? seed
-ISiloStatusOracle siloStatusOracle
-IInternalGrainFactory grainFactory
-object writeLock
-IServiceProvider _serviceProvider
-DirectoryMembership directoryMembership
-bool Running
-Catalog? _catalog
+SiloAddress MyAddress
+IGrainDirectoryCache DirectoryCache
+LocalGrainDirectoryPartition DirectoryPartition
+RemoteGrainDirectory RemoteGrainDirectory
+RemoteGrainDirectory CacheValidator
+GrainDirectoryHandoffManager HandoffManager
+Start() : void
+StopAsync() : Task
+SiloStatusChangeNotification(SiloAddress, SiloStatus) : void
+RegisterAsync(GrainAddress, int) : Task<AddressAndTag>
+UnregisterAsync(GrainAddress, UnregistrationCause, int) : Task
+LookupAsync(GrainId, int) : Task<AddressAndTag>
+LocalLookup(GrainId, out AddressAndTag) : bool
+CalculateGrainDirectoryPartition(GrainId)
«interface»
ILocalGrainDirectory
+Start() : void
+StopAsync() : Task
+RegisterAsync(GrainAddress, int) : Task<AddressAndTag>
+UnregisterAsync(GrainAddress, UnregistrationCause, int) : Task
+LookupAsync(GrainId, int) : Task<AddressAndTag>
+LocalLookup(GrainId, out AddressAndTag) : bool
«interface»
ISiloStatusListener
+SiloStatusChangeNotification(SiloAddress, SiloStatus) : void
«interface»
ILifecycleParticipant<ISiloLifecycle>
+Participate(ISiloLifecycle) : void
LocalGrainDirectoryPartition
+AddSingleActivation(GrainAddress, GrainAddress?) : AddressAndTag
+RemoveActivation(GrainId, ActivationId, UnregistrationCause) : void
+LookUpActivation(GrainId) : AddressAndTag
+GetItems()
«interface»
IGrainDirectoryCache
+AddOrUpdate(GrainAddress, int) : void
+LookUp(GrainId, out GrainAddress) : bool
+Remove(GrainId) : bool
+KeyValues IEnumerable~(GrainAddress, int)

协作图

ClientLocalGrainDirectoryLocalGrainDirectoryPartitionDirectoryCacheRemoteGrainDirectorySiloStatusOracleGrain注册流程RegisterAsync(grainAddress, hopCount)CalculateGrainDirectoryPartition(grainId)AddSingleActivation(address, previousAddress)AddressAndTag resultAddOrUpdate(result.Address, result.VersionTag)返回注册结果RegisterAsync(address, previousAddress, hopCount+1)AddressAndTag resultAddOrUpdate(result.Address, result.VersionTag)返回注册结果alt[当前Silo是Owner][需要转发到其他Silo]Grain查找流程LookupAsync(grainId, hopCount)LookUp(grainId, out address)返回缓存地址返回查找结果CalculateGrainDirectoryPartition(grainId)LookUpActivation(grainId)AddressAndTag result返回查找结果LookupAsync(grainId, hopCount+1)AddressAndTag resultAddOrUpdate(result.Address, result.VersionTag)返回查找结果alt[当前Silo是Owner][需要转发到其他Silo]alt[缓存命中且Silo有效][缓存未命中或无效]Silo状态变化处理SiloStatusChangeNotification(updatedSilo, status)AddServer(updatedSilo)AdjustLocalDirectory(silo, dead: false)AdjustLocalCache(silo, dead: false)RemoveServer(updatedSilo, status)AdjustLocalDirectory(silo, dead: true)AdjustLocalCache(silo, dead: true)alt[Silo变为Active状态][Silo变为Terminating状态]ClientLocalGrainDirectoryLocalGrainDirectoryPartitionDirectoryCacheRemoteGrainDirectorySiloStatusOracle

核心功能详解

1. 分布式哈希表(DHT)分区算法

LocalGrainDirectory使用一致性哈希算法来确定每个Grain的目录分区所有者:

public SiloAddress? CalculateGrainDirectoryPartition(GrainId grainId)
{
    int hash = unchecked((int)grainId.GetUniformHashCode());
    // 在排序的Silo列表中查找第一个哈希值小于等于目标哈希的Silo
    for (var index = existing.MembershipRingList.Count - 1; index >= 0; --index)
    {
        var item = existing.MembershipRingList[index];
        if (IsSiloNextInTheRing(item, hash, excludeMySelf))
        {
            return item;
        }
    }
}
2. 请求转发机制

当当前Silo不是Grain的目录所有者时,会进行请求转发:

public SiloAddress? CheckIfShouldForward(GrainId grainId, int hopCount, string operationDescription)
{
    var owner = CalculateGrainDirectoryPartition(grainId);
    if (owner is null || owner.Equals(MyAddress)) return null;
    
    if (hopCount >= HOP_LIMIT) // 跳数限制为6
        throw new OrleansException($"Hop limit reached");
        
    return owner; // 转发到目标Silo
}
3. 缓存管理

LocalGrainDirectory维护本地缓存以提高查找性能:

public bool LocalLookup(GrainId grain, out AddressAndTag result)
{
    // 首先检查缓存
    var address = GetLocalCacheData(grain);
    if (address != default)
    {
        result = new(address, 0);
        return true;
    }
    
    // 如果是本地分区,检查本地目录
    if (silo.Equals(MyAddress))
    {
        result = GetLocalDirectoryData(grain);
        return result.Address != null;
    }
    
    return false;
}
4. 集群成员变化处理

LocalGrainDirectory监听Silo状态变化并相应调整目录和缓存:

public void SiloStatusChangeNotification(SiloAddress updatedSilo, SiloStatus status)
{
    if (status.IsTerminating())
    {
        CacheValidator.WorkItemGroup.QueueAction(() => RemoveServer(updatedSilo, status));
    }
    else if (status == SiloStatus.Active)
    {
        CacheValidator.WorkItemGroup.QueueAction(() => AddServer(updatedSilo));
    }
}

关键设计特点

  1. 线程安全:使用writeLock对象确保目录操作的线程安全
  2. 容错性:支持Silo故障时的目录分区重新分配
  3. 性能优化:本地缓存减少远程查找开销
  4. 可扩展性:支持动态集群成员变化
  5. 一致性:确保目录信息在集群中的一致性

LocalGrainDirectory是Orleans分布式系统的核心组件,它通过分布式哈希表算法实现了高效的Grain定位服务,为整个系统的可扩展性和可靠性提供了基础支撑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helloworddm

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值