Akka Consistent Hashing Router

597 views
Skip to first unread message

Sendhil Kumar M

unread,
Mar 19, 2014, 5:35:53 PM3/19/14
to akka...@googlegroups.com
I have implemented two CHR where one Router has 20 routees of Actor B and another CHR router with 5 routees and both these Routers uses the Same hashMapper which uses part of the incoming message to build it.
 
Input message:
1
2
3
4
5
 
Actor A calls CHR of Actor B
routee 1 of Actor B gets 1 and 2
routee 2 of Actor B gets 3 and 4
routee 3 of Actor B gets 5  
 
 
Now Actor B calls Actor C's CHR using the hash mapper returing the same key.
 
Expected result:
routee 1 of Actor B gets 1 and 2
routee 2 of Actor B gets 3 and 4
routee 3 of Actor B gets 5  
 
But i am seeing this.
routee 1 of Actor B gets 1 and 3
routee 2 of Actor B gets 2 and 5
routee 3 of Actor B gets 4  
 
 
I see th CHR is consistently passing the messages with the same key into same actor with a set of routees of same actors. But i am not seeing the same messages going to one routee of another actor with another CHR. The messages are going to different routees for the same hash key.
 
 
Can someone please explain how the consistent hashing router is implemented? What are the factors it uses to build the hashing and how it routes?
 
 
 

Patrik Nordwall

unread,
Mar 20, 2014, 3:14:03 AM3/20/14
to akka...@googlegroups.com
What version of Akka are you using? How do you create the CHR?
/Patrik


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.



--

Patrik Nordwall
Typesafe Reactive apps on the JVM
Twitter: @patriknw

Sendhil Kumar M

unread,
Mar 20, 2014, 8:24:46 AM3/20/14
to akka...@googlegroups.com
I am using akka 2.3.0 and this is how i am creating the CHR.
 

So my req is that which ever message went to a routee of TestConnActor they should all be consolidated as list in the Aggregator actor.

 

So if message 1 and 2 made it to TestConnActor  routee1 and message 3 and 4 made it to TestConnActor routee2 then when the messages 1 and 2 should reach the same routee of the Aggregator actor. Please suggest me if its doable with CHR.

 

TestHashMapper  just uses one of the incoming message's id and returns that as hash key.

TestHashMapper hashMapper =

new TestHashMapper();

actorSystem().actorOf(Props.create(TestConnActor.

class).withRouter(new ConsistentHashingRouter( new Integer(3)).withHashMapper(hashMapper)), "TestQuant" );

actorSystem().actorOf(Props.create(TestEventAggregator.

class).withRouter(new ConsistentHashingRouter( new Integer(3)).withHashMapper(hashMapper)), "TestAgg" );

actorSystem().actorOf(Props.create(TestBulkActor.

class).withRouter(new ConsistentHashingRouter( new Integer(3)).withHashMapper(hashMapper)), "TestBulk" );

ActorRef single = actorSystem().actorOf(

new RoundRobinPool(3).props(Props.create(TestSingleActor.class)), "TestSingle");

 

 

 

 

~

Patrik Nordwall

unread,
Mar 20, 2014, 8:52:44 AM3/20/14
to akka...@googlegroups.com
On Thu, Mar 20, 2014 at 1:24 PM, Sendhil Kumar M <send...@gmail.com> wrote:
I am using akka 2.3.0 and this is how i am creating the CHR.
 

So my req is that which ever message went to a routee of TestConnActor they should all be consolidated as list in the Aggregator actor.

 

So if message 1 and 2 made it to TestConnActor  routee1 and message 3 and 4 made it to TestConnActor routee2 then when the messages 1 and 2 should reach the same routee of the Aggregator actor. Please suggest me if its doable with CHR.

but TestQuant and TestAgg don't have any routees in common. Both of them create 3 separate routees each.

You are using a deprecated API. This is now named ConsistentHashingPool. I think you might be looking for ConsistentHashingGroup. The differences between Pool and Group are described in the documentation: http://doc.akka.io/docs/akka/2.3.0/java/routing.html

Take a look at that and let me know if things still are unclear.

/Patrik

Sendhil Kumar M

unread,
Mar 20, 2014, 10:37:43 AM3/20/14
to akka...@googlegroups.com
 
I corrected the deprecated version. Thanks for your help. But still i see the same behavior.
 
So yes i have three Routers set up with 3 different routee sets and my objective to route all the messages with same hashKey to single instance of TestAdaptorActor.
So i was trying to build a list with the second Actor with Router using the same key, thinking the list will be built based on the hashkey and so which ever message went to one instance of TestAdaptorActor will be added in list.
 
But i found something different.
 
First router guarantees the fact for hashKey it always went to one AdaptorActor. But the messages which were processed by AdaptorActor were not added in the same list as Aggregater's routees are different.
 
So does it mean that if the the routee's actors are different then messages wont go to the same routee instance even if i use Consistent HashMapping with the same mapper and key?
Please let me know. If this is not possible i have to change my actors to do accordingly. Your suggestions will help. Thanks again.
 
 

TestHashMapper hashMapper =

new TestHashMapper();

actorSystem().actorOf(Props.create(TestAdaptorActor.

class).withRouter(new ConsistentHashingPool( new Integer(3)).withHashMapper(hashMapper)), "TestQuant" );

TestHashMapper hashMapper1 =

new TestHashMapper();

actorSystem().actorOf(Props.create(TestEventAggregator.

class).withRouter(new ConsistentHashingPool( new Integer(3)).withHashMapper(hashMapper1)), "TestAgg" );

TestHashMapper hashMapper2 =

new TestHashMapper();

actorSystem().actorOf(Props.create(TestBulkActor.

class).withRouter(new ConsistentHashingPool( new Integer(3)).withHashMapper(hashMapper2)), "TestBulk" );

ActorRef single = actorSystem().actorOf(

new RoundRobinPool(3).props(Props.create(TestSingleActor.class)), "TestSingle");

for(int i =1; i<=12;i++)

{

single.tell(Integer.valueOf(i) , single);

}

Sendhil Kumar M

unread,
Mar 20, 2014, 11:01:48 AM3/20/14
to akka...@googlegroups.com
 
 
I read the ConsistenHashingGroup details. Let me try that and get back to you. By the way yesterday's presentation for Akka Persistence was good. Looking forward to read it in java version.Thanks for your help.

Sendhil Kumar M

unread,
Mar 20, 2014, 11:09:42 AM3/20/14
to akka...@googlegroups.com

I read the article on ConsistentHashingGroup but is it possible for me to have different types of routees(Actors) in the group? If so how do i specify which type of actor should get message. Please let me know.

√iktor Ҡlang

unread,
Mar 20, 2014, 11:18:36 AM3/20/14
to Akka User List
Sounds like you don't want consistent hashing: http://en.wikipedia.org/wiki/Consistent_hashing
Cheers,

———————
Viktor Klang
Chief Architect - Typesafe

Twitter: @viktorklang

Sendhil Kumar M

unread,
Mar 20, 2014, 11:22:27 AM3/20/14
to akka...@googlegroups.com
Thanks for your suggestion. So if i have two different actors with CHR and there is no guarantee that the messages  will be routed to same routee within the CHR's. If thats the case then i got to change my approach. Consistent hasing routing will work only for the same type of actors is it? Please let me know.

Patrik Nordwall

unread,
Mar 20, 2014, 11:56:35 AM3/20/14
to akka...@googlegroups.com
On Thu, Mar 20, 2014 at 4:22 PM, Sendhil Kumar M <send...@gmail.com> wrote:
Thanks for your suggestion. So if i have two different actors with CHR and there is no guarantee that the messages  will be routed to same routee within the CHR's. If thats the case then i got to change my approach. Consistent hasing routing will work only for the same type of actors is it? Please let me know.

No that is not the problem. You can have different types of actors as routees in a Group. The nodes in the hash ring will be keyed on the "paths" of the routees.

Try this:

ActorRef a = system.actorOf(Props.create(A.class), "a");
ActorRef b = system.actorOf(Props.create(B.class), "b");
ActorRef c = system.actorOf(Props.create(C.class), "c");

List<String> paths = Arrays.asList("/user/a", "/user/b", "/user/b");
ActorRef r1 = system.actorOf(new ConsistentHashingGroup(paths).withHashMapper(hashMapper).props(), "r1");
ActorRef r2 = system.actorOf(new ConsistentHashingGroup(paths).withHashMapper(hashMapper).props(), "r2");

With the above setup you can send messages to r1 or r2 and messages with same hashKey should end up in same destination (a, b, c).

/Patrik

Sendhil Kumar M

unread,
Mar 21, 2014, 7:02:01 AM3/21/14
to akka...@googlegroups.com
 
Thanks for your help. I changed my design a little bit to add CHR only in one actor. My constraint was that when event i process a message in one actor it has to go to the same actor instance since the underlying service is caching by connections. :(.
 
So i process individual messages that would call an actor (which is fine with CHR since they were always routed to one actor). Once the individual actors are done enriching the message then there is an aggregator to bundle these messages and sends to a bulk processor. THe bulk processor also calls the actor to make a webservice call. And i wanted the bulk processor to have a list of messages that were processed by the service actor so it could go to the same connection and they would have the data cached. This is where i had problems. The list built by the aggregator didnt have the messages that were processed by the same service actor instance and hence it will impact the bulk processors performance.
 
Thanks and appreciate all your help and suggestions.
Reply all
Reply to author
Forward
0 new messages