2
votes

Take a simple example: I have a service that has 1,000,000 users and each user has some profile information. I want to manage CRUD operations on this profile information using actors.

In Project Orleans, my understanding is that I would have one grain per user, so 1,000,000 virtual grains of the same actor type (that would only be created if used), and each grain would manage the profile information of a single user stored in its state. As my users grow, so do the number of grains.

In Service Fabric, if I'm interpreting the documentation right, it would work slightly differently. I would have a stateful actor type that managed CRUD operations on all users, and for scalability I would partition the actor, giving each partition responsibility for a subset of user data. Given the partition options, I can't see an obvious way to implement it the same fine-grained way as Project Orleans.

I really like the approach in Project Orleans. The actor is just handling data for a single user, and scalability is obvious (more users equals more grains). The memory model is also simple: a single actor gets hydrated on demand with it's small quantity of state.

It seems the Service Fabric implementation would be slightly more complicated. Each actor is dealing with a set of users, and for scalability I have to decide in advance how many partitions I should make as this can't be modified later. As for the memory model, the amount of data managed by each actor grows as the number of users grows.

So my question is: Is my understanding correct that actors in Service Fabric are simply more coarse grained than Project Orleans?

Update

Thanks for the answers. In my mistake was thinking that a partition contained a single actor instance that would contain and manage the state for all actor IDs within the partition. This is totally wrong. Michiel points out that a partition contains a number of actor instances, one per actor ID. Therefore the actors could be implemented in the same way as in Project Orleans. This makes far more sense now, thanks.

2

2 Answers

7
votes

An ActorType is actually hosted in a Service. That service is partitioned. Each partition will hold a number of instances of your ActorType (according to the ranges and partition count that you specify).

Using the API you can get hold of an Actor instance (you do not have to explicitly create one):

var actor = ActorProxy.Create<IActorType>(new ActorId("some id"), "fabric:/application");

In Orleans, your grains are spread out over silo's without bundling them in partitions. So Orleans can move a single instance to a different Silo if it wants to. In Service Fabric this is all done on the partition level. So all instances in a partition are moved together.

2
votes

I don't know much about Project Orleans but I think you may have confused the notion of an actor and an actor type within Service Fabric.

An actor is an instance of an actor type - the relationship is similar to a classes and objects in object oriented languages.

In your case you'd have a single actor type for users e.g. UserActor but then you'd have many actor instances of that type. Those actor instances are the ones that hold state and are partitioned and distributed.