Akka, Redis, Async and Actor Modeling

1,235 views
Skip to first unread message

Nathan Stults

unread,
May 1, 2012, 7:46:39 PM5/1/12
to akka...@googlegroups.com
Hello,

I am writing an Akka server that uses Redis for persistence. The scala-redis library is a blocking library, and I know Akka actors are generally supposed to do async IO.

I studied the Redis durable mailbox code (and emulated it) but I wonder if that code is too specialized for me to use for general purpose database access and I was hoping there were some best practices around this.

What I have now (following the durable mailbox example) is that for a particular Repository (like UserRepository) in my system I will have a single actor that reads and writes data for that entity. So each entity will be represented by a RepositoryActor that owns an instance of an appropriate Repository which does the actual DB communication.

The way I have it written each Repository gets its own RedisClientPool, but I'm not doing anything with futures to keep the Redis calls from blocking so I think it is wrong. Also, I feel like I should probably model each Repository actor behind a router so that load can be distributed among a set of workers, but again I'm not certain how (or if) to share the client pool with the workers, or if the client pool should be shared with all workers of all repository actors via some (ActorSystem scoped) singleton, or just how to utilize the client pool to avoid blocking whatever reactor loop Akka uses.

Is anyone aware of any code on Github that might demonstrate a reasonable pattern for modeling sane database access via Akka Actors with a blocking driver like scala-redis?

Any guidance would be greatly appreciated.

Thank you very much for your time,

Nathan

(here are some of my classes, FWIW)
Base redis repository:

An implementation:

A "Repository" Actor Impl:

How I am creating the Repository Actor (one per type of Repository)

Debasish Ghosh

unread,
May 2, 2012, 3:39:39 AM5/2/12
to akka...@googlegroups.com
Hi Nathan -

Try  https://github.com/derekjw/fyrie-redis by Derek .. uses Akka as well .. it may also do what u r trying to do :)

regards.


--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/UdO4EEWGRu0J.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Debasish Ghosh
http://manning.com/ghosh

Twttr: @debasishg
Blog: http://debasishg.blogspot.com
Code: http://github.com/debasishg

Nathan Stults

unread,
May 2, 2012, 10:45:08 AM5/2/12
to akka...@googlegroups.com, dgh...@acm.org
Thanks Debasish. That uses a pretty old version of Akka, so I'm not sure it will be compatible with 2.0.

All I'm trying to do is understand the canonical way to address persistence in Akka :) So it sounds like the answer is "use an async driver" :) Oddly enough there aren't a wealth of those for Redis I have found for Scala / Java. 

This particular area feels (to me personally) like a blindspot in the Akka documentation / learning curve. I have had a very difficult time finding any useful guidance or examples of how to do persistence correctly.

Your scala-redis library has a nice tutorial in the README on using futures to operate in an async environment, but they are Scala futures and I'm not sure how to translate that example properly into Akka or how or what kind of executor makes sense in this environment or how it should be wired up to an Akka ExecutionContext or dispatcher.

Anyway, I did find an async Redis library for Java called Lettuce (https://github.com/wg/lettuce) that looks reasonably active and supports Redis 2.6 commands. I will re-write my internal repository API to be async and see how it works.

In the mean time though if anyone knows of any samples, blog posts, open source projects or any other material that could demonstrate or describe a best-practices (or even just acceptable-practices) model for structuring the persistent portion of ones Akka application, using either async or blocking DB drivers, I would be very grateful. I am quite certain I can make something work, I am just not so confident that it will be correct.
regards.

To unsubscribe from this group, send email to akka-user+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

Derek Williams

unread,
May 2, 2012, 11:02:16 AM5/2/12
to akka...@googlegroups.com
On Wed, May 2, 2012 at 8:45 AM, Nathan Stults <plasti...@gmail.com> wrote:
Thanks Debasish. That uses a pretty old version of Akka, so I'm not sure it will be compatible with 2.0.

The version in master uses an Akka 2.0 snapshot, there is a pull request I believe to update it to 2.0 as well, but I haven't had any time since Akka 2 was released to update it.

--
Derek Williams

Debasish Ghosh

unread,
May 2, 2012, 10:54:55 AM5/2/12
to Nathan Stults, akka...@googlegroups.com
Not sure what kind of blindspot u r referring to .. I used Redis and Akka 2.0 in a prototype project at https://github.com/debasishg/cqrs-akka ..

√iktor Ҡlang

unread,
May 2, 2012, 10:53:41 AM5/2/12
to akka...@googlegroups.com
Hi Nathan!

On Wed, May 2, 2012 at 4:45 PM, Nathan Stults <plasti...@gmail.com> wrote:
Thanks Debasish. That uses a pretty old version of Akka, so I'm not sure it will be compatible with 2.0.

All I'm trying to do is understand the canonical way to address persistence in Akka :) So it sounds like the answer is "use an async driver" :) Oddly enough there aren't a wealth of those for Redis I have found for Scala / Java. 

This particular area feels (to me personally) like a blindspot in the Akka documentation / learning curve. I have had a very difficult time finding any useful guidance or examples of how to do persistence correctly.

I honestly don't see the problem. Just store/load data from your storage engine of choice.
Could you explain what the blindspot appears to be?

Cheers,
 
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/_0Im7GPDJjEJ.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

krishnen

unread,
May 2, 2012, 12:52:57 PM5/2/12
to akka...@googlegroups.com
Hi Nathan,

I use the scala-redis library as well. (Big Thumbs up to Debasish btw).
I share the same concern as you since it is a  blocking client, i find myself wondering if i should always make client operations to the Redis db via Futures.
Could someone enlighten use on the best practice?

Krishnen

Jason Mason

unread,
May 2, 2012, 1:12:53 PM5/2/12
to akka...@googlegroups.com
I can't speak for Nathan but I think he might be referring to the same inquiry I had:

This is very much a recurring theme here in the Akka discussions. The documentation makes some strong & specific recommendations (great!) regarding blocking inside actors but doesn't offer much in the way of samples or specific implementation information for *very* common use cases such as persistence or network IO.... especially for Java. Situations that I'd venture to say almost everyone looking at Akka will encounter in a real world project. 

I think adding this kind of information to the Akka documentation corpus will really speed adoption of Akka amongst a wider audience. 

Nathan Stults

unread,
May 2, 2012, 1:22:46 PM5/2/12
to akka...@googlegroups.com
I think the blind spot is in my understanding, and not the Akka documentation, I apologize for making that characterization, I really should know better by now.

I think I am just communicating very very poorly, and too verbosely. 

The main gap in my understanding is that I am viewing Akka like other evented environments (like Event Machine or Node), and assuming that any blocking call in any actor will stall the event loop and damage overall concurrency. I feel, based on the responses I've seen here so far, that my understanding of Akka is oversimplified and that this is not actually the case.

Looking at Debasish's example project linked above, he has an actor that is responsible for talking to Redis using the blocking scala-redis client. Other actors will communicate asynchronously with this actor (through an API), and it alone will talk to the DB in a blocking way. Is this all that is required to use a blocking driver in an optimal way in Akka? It also looks like a pinned-dispatcher is being used, or meant to be used - maybe that is the secret sauce? 

I guess it all boils down to just looking for a formula for using a blocking library in an idiomatic way that won't break stuff. :)

Thanks for your time,

Nathan
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

andy

unread,
May 2, 2012, 2:29:10 PM5/2/12
to akka...@googlegroups.com
Here is the compromise I have arrived at.

If you are using a blocking driver library then you will have blocking somewhere, thats just the way it is. Here are my rules for blocking. 

No actors will block based on the results of other actors, as this can lead to thread starvation deadlocks. If an actor needs do something like repository.getMyEntity( entityId ) and it is a blocking call then so be it as long as the actor is not a bottle neck. My approach when I have an bottle neck actor, by which I mean something like a router with a single instance that processes lots of messages, I spawn a temporary "request handling" actor in the router to handle the blocking call and forward the request to the request handling actor from the router. So far this approach has been easy for the new devs to grasp and it has not led to the dreaded deadlock from thread starvation.

Just by following general best practices with Akka you will get better concurrency and performance in your code even if you have some blocking calls. Generally if you get too fancy too quickly trying to make everything non-blocking you will screw yourself up.

Make it work, then make it clean, then make it fast.

All the best,
Andy 

Nathan Stults

unread,
May 2, 2012, 2:40:00 PM5/2/12
to akka...@googlegroups.com
Great approach. I was under the incorrect impression that any actor blocking anywhere blocked everybody everywhere, as happens in a single threaded event loop. Those rules are easy to understand and remember, thank you.

Viktor Klang

unread,
May 2, 2012, 2:42:12 PM5/2/12
to akka...@googlegroups.com
Hi Nathan,

Akka is not single threaded. At least unless you've configured it to be so.

It is important that Akka is NOT a framework. It doesn't frame you.
Akka is a set of tools to make concurrency easier & simpler.

Cheers,


To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/qMSqZwb04T4J.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.

Nathan Stults

unread,
May 3, 2012, 1:52:14 PM5/3/12
to akka...@googlegroups.com
Yes. It took me 24 hours but it finally all clicked. My mental model of Akka was wrong on a number of levels, and thinking of it as a kind of framework was one of them. My assumptions about the default threading/concurrency model was another. The critical part I was mentally glossing over for some reason was http://doc.akka.io/docs/akka/2.0.1/scala/dispatchers.html.

Hopefully over time the community will flesh out the "Recipes" section of the documentation with some examples and articles to help people like me over the hump.

Thanks all for the help,

Nathan

Akka Team

unread,
May 3, 2012, 3:00:41 PM5/3/12
to akka...@googlegroups.com
Great!

Happy hAkking!

Cheers,


To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/B-Czdg7kN60J.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Akka Team
Typesafe - The software stack for applications that scale
Blog: letitcrash.com
Twitter: @akkateam

Reply all
Reply to author
Forward
0 new messages