举一个简单的例子:我有一个服务有 1,000,000 个用户,每个用户都有一些个人资料信息。我想使用参与者管理此配置文件信息的 CRUD 操作。
在 Project Orleans 中,我的理解是每个用户我会有一个 grain,因此 1,000,000 个相同 actor 类型的虚拟 grain(只有在使用时才会创建),每个 grain 将管理存储在其状态中的单个用户的个人资料信息。随着我的用户的增长,grains 的数量也在增长。
在 Service Fabric 中,如果我对文档的解释正确,它的工作方式会略有不同。我将有一个有状态的 actor 类型来管理 所有 用户的 CRUD 操作,并且为了可扩展性,我将对 actor 进行分区,让每个分区负责用户数据的一个子集。鉴于 partition options ,我看不到一种明显的方法来以与 Project Orleans 相同的细粒度方式来实现它。
我非常喜欢 Project Orleans 中的方法。 actor 只是为单个用户处理数据,可扩展性是显而易见的(更多用户等于更多 grains)。内存模型也很简单:单个 actor 通过少量状态按需补充水分。
似乎 Service Fabric 实现会稍微复杂一些。每个参与者都在处理一组用户,为了可伸缩性,我必须提前决定我应该制作多少个分区,因为以后无法修改。至于内存模型,每个参与者管理的数据量随着用户数量的增长而增长。
所以我的问题是:我的理解是否正确,Service Fabric 中的参与者只是比 Project Orleans 更粗粒度?
更新
感谢您的回答。我的错误是认为分区包含单个参与者实例,该实例将包含和管理分区内所有参与者 ID 的状态。这是完全错误的。 Michiel 指出一个分区包含许多参与者实例,每个参与者 ID 一个。因此,可以采用与 Orleans 项目相同的方式来实现参与者。现在这更有意义了,谢谢。
请您参考如下方法:
ActorType 实际上托管在服务中。该服务是分区的。每个分区将包含您的 ActorType 的多个实例(根据您指定的范围和分区计数)。
使用 API,您可以获得一个 Actor 实例(您不必显式创建一个):
var actor = ActorProxy.Create<IActorType>(new ActorId("some id"), "fabric:/application");
在奥尔良,您的 Cereal 散布在筒仓中,而没有将它们捆绑在隔板中。因此,Orleans 可以根据需要将单个实例移动到不同的 Silo。在 Service Fabric 中,这一切都在分区级别完成。因此分区中的所有实例都一起移动。