Now that we have a basic understanding of Akka Cluster Sharding in my previous blog. Let’s have a look at how we are going to implement this and what are the things that we need to keep in our mind while doing that.
To shard a specific type of actor we use the cluster sharding akka extension, and we call it as start, we can see that in our example here,
val shards = ClusterSharding(myActorSystem).start( “shardedActors”, MyShardedActor.props(), ClusterShardingSettings(myActorSystem), idExtractor, shardIdExtractor )
Firstly, we have Cluster Sharding where we pass it the actor system and on this we call start. ClusterSharding.start is called on each node that will be hosting shards. If for some reason we have a node that will not host shards, then we would not call ClusterSharding.start on that node. This creates a shard region on that node. Now in order to do this we need to provide several things:
- We have to provide a name for the type of actors that will be sharded. In the example above, we have named it as shardedActors.
- We need to provide the Props factory for the actor that will be sharted.
- We need the cluster sharding settings. These can be customized, but for now we’re just using the default.
- Then we provide an entity ID extractor.
- And then we provide a shard ID extractor.
The role of the above block of code is to provide an actor ref which is the reference for the local shard region. And so now we can send messages through that actor. The next question which comes to our mind is how do we send a message ?
Well, for sending messages all we have to do is take the actor ref that we got from above which is a shard region actor ref and we send it whatever message we’re expecting.
shards ! MyMessage(entityId, someMessage)
So in this case we are sending a message using the case class MyMessage. Here the messages are first sent to the entities, through the local shard region. We can send the messages just like we would with any other actor. So we need to treat this just like another actor. In times when it receives a message, it’s going to use the entity ID extractor and the shard ID extractor that we have defined, and it will use those to determine the destination shard and entity for that message and then direct them as appropriate.
Shard Region Lookup
Now sometimes we may want to look up an existing shard region. So for example, we may have defined the shard region somewhere else and we don’t want to call start again because it’s already been started. But we still want to access that shard region so that we can send messages.
val shards = ClusterSharding(myActorSystem).shardRegion(“shardedActors”)
So in that case we can use ClusterSharding, passing in the actor system. We need to specify the shard region, and then give the name that was given when we started that shard region, and it will look up the local shard region, so that we can then send messages. This allows us to reference an existing shard region without having to recreate it.
There may be cases where we would want to send messages to shards but we may not want that node to host shards itself. In that case we can use start proxy, instead of start.
val shards = ClusterSharding(myActorSystem).startProxy( “shardedActors”, none, //Role idExtractor, shardIdExtractor )
Now the way this works is we still need to provide:
- A name for the actors.
- Then we also provide a role, in this case we’ve said none. What the role does is that it says only search for sharded actors on nodes that are identified with this role. By saying none, we are saying look on all nodes and don’t pay attention to a specific role. But if you have roles in your system then we can specify that here.
- We also then specify the ID extractor and the shard ID extractor. So that we know how to direct messages and locate the shards appropriately.
Now the proxy will not create a shard region and will therefore not host any entities, but you get back an actor ref that can still be used to send messages to the entities in the same manner as we would to a shard region.
That’s all for this blog.