【问题标题】:Querying a list of Actors in Azure Service Fabric查询 Azure Service Fabric 中的 Actor 列表
【发布时间】:2016-09-19 15:27:43
【问题描述】:

我目前为系统中的每个用户都有一个 ReliableActor。这个演员被恰当地命名为用户,为了这个问题,有一个位置属性。按位置查询用户的推荐方法是什么?

我目前的想法是创建一个包含 ReliableDictionary 的 ReliableService。字典中的数据将是用户数据的投影。如果我这样做了,那么我需要:

  1. 查询字典。在 GA 之后,这似乎是 recommended approach
  2. 保持字典同步。也许通过Pub/SubIActorEvents

另一种选择是在 Service Fabric 之外拥有一个持久存储,例如数据库。这感觉不对,因为它违背了使用 Service Fabric 的一些理想。如果我这样做了,我会假设与上述类似,但使用的是无状态服务?

非常感谢。

【问题讨论】:

  • 如果你需要数据是最新的,你可以考虑一个可靠的字典——如果你只需要一个快照来进行历史查询,你可以看看像 CQRS 这样的策略(它使用数据库,但它不是事实的来源,它只是定期更新——基本上是为了允许历史查询)。

标签: azure-service-fabric


【解决方案1】:

我个人正在探索将 Actors 用作我的实体的主要数据存储(即:事实来源)。添加、更新或删除 Actor 时,我使用 MassTransit 发布事件。然后,我让 Reliable Statefull Services 订阅了这些事件。服务接收事件并更新其内部的 IReliableDictionary。然后可以查询服务以查找客户端所需的实体。每个服务只保留执行查询所需的实体数据。

我也在探索使用 EventStore 来发布事件。这样,如果将来我决定需要以新方式查询实体,我可以创建一个新服务并将所有事件重播给它。

这些 Pub/Sub 方法确实意味着查询服务只是最终一致,但在分布式系统中,这似乎是常态。

【讨论】:

    【解决方案2】:

    虽然标准推荐肯定是 Vaclav 的回应,但如果查询是例外,那么 Actors 仍然是合适的。对我来说,它们是否合适是由访问它们的正常方式定义的,如果是按键(可能是用户记录),那么 Actors 工作得很好。

    可以对 Actor 进行迭代,但这是一项相当繁重的任务,所以就像我说的那样,只有在例外情况下才合适。以下代码将构建一组 Actor 引用,然后您遍历该集合以获取 Actor,然后可以在您构建的集合上使用 Linq 或类似的。

    ContinuationToken continuationToken = null;
    var actorServiceProxy = ActorServiceProxy.Create("fabric:/MyActorApp/MyActorService", partitionKey);
    var queriedActorCount = 0;
    do
    {
        var queryResult = actorServiceProxy.GetActorsAsync(continuationToken, cancellationToken).GetAwaiter().GetResult();
        queriedActorCount += queryResult.Items.Count();
       continuationToken = queryResult.ContinuationToken;
    } while (continuationToken != null);
    

    TLDR:查询参与者并不总是可取的,但如果需要,可以实现。上面的代码将帮助您入门。

    【讨论】:

    • 非常感谢,这绝对得到了所有演员。正如您所警告的那样,这很昂贵。我的案子通常会被执行,所以虽然这不符合要求,但它引导我走向了更好的方向。干杯。
    • 我通常不推荐这样做的原因是,这个查询只能获取演员 ID。然后,您必须向每个参与者发出单独的网络请求以检查其状态。因此,如果你有大量的演员——如果你使用演员,通常你会这样做——那么这将变得非常不切实际。
    • 如果演员以某种方式进行分区——比如逻辑上——如果你有某种方式来缩小范围(即某种索引)会更有意义。 -- 可能按父级划分它们,等等。 -- 做这样的事情可以优化一个足够可搜索的查询;您甚至可以将执行查询的工作交给另一个参与者(取决于您如何设置)。 -- 但这可能需要做很多工作 -- 那时你基本上是在针对系统工作......
    【解决方案3】:

    如果您发现自己需要通过某些数据属性(例如 User.Location)查询数据集,那么可靠集合是正确的答案。 Reliable Actors 不应该以这种方式被查询。

    在您的情况下,用户可能只是 Reliable Dictionary 中的一行。

    【讨论】:

    • 谢谢。 Service Fabric 的 11 月文档中有一个图表,显示了用户参与者与愿望清单参与者的交互。服务的目标似乎更广泛,例如气象服务。因此,离散对象似乎可以成为 Actor 的良好候选者。根据您的回答,我将来需要查询的任何内容似乎都应该在 ReliableDictionary 中(或从无状态服务访问)。这对我来说很有意义。但现在我想知道如何使独立服务之间的 ReliableDictionaries 保持同步。这几乎是一个完整的 pub/sub 循环。
    猜你喜欢
    • 2017-07-19
    • 2017-07-14
    • 2016-11-08
    • 2018-09-16
    • 2016-10-31
    • 2016-03-11
    • 2018-01-11
    • 2015-11-01
    • 2019-11-30
    相关资源
    最近更新 更多