Concurrency, Scalability <br />& Fault-tolerance 2.0 with Actors & STM<br />by Mario Fusco<br />mario.fusco@gmail.com<br /...
Which are the biggestchallengesin contemporary software development?<br />
Deal with overloadedsystems<br />
Do concurrencyeffectively<br />
Design, develop and deployapplicationsthat scale well<br />
The native Java concurrency model<br />Based on:<br />Threads<br />Semaphores<br />Synchronization<br />Locks<br />They ar...
Actors: a different model of concurrency<br /><ul><li>Implements Message-Passing Concurrency
Share NOTHING
Isolated lightweight processes
Communicates through messages
Asynchronous and non-blocking
Each actor has a mailbox (message queue)
A single thread can managemany (thousands of) actors</li></li></ul><li>People are bad at parallel thinking<br />With actor...
What is Akka?<br /><ul><li>An actor based concurrency framework
Written in Scala, butalsoworking in Java
Nowrealeasing 1.0 after 2 years of development (currentlyRC4 available)
Better performances and throughput and smallermemoryfootprint (650 bytes) than native scala actors
Open source (Apache2)</li></li></ul><li>Untyped Actors<br />public class MyUntypedActorextends UntypedActor {<br />   publ...
Sending message to UntypedActors<br />There are 3 different ways to send a message to an actor:<br />Fire-and-forget ( !  ...
Typed Actors<br />public class CounterImplextends TypedActorimplements Counter {<br />    private int counter = 0;<br />  ...
“Let it crash” <br />fault-tolerance <br />through <br />supervisor hierarchies<br />
You can’t avoid failures: shit happens<br />
What’swrong in trying to preventerrors?<br />Java and other languages and frameworks (not designed with concurrency in min...
Fail fast & build self-repairing systems<br />
Supervisedactors<br /><ul><li>Actors provide a clean way of getting error notification and do something about it
Supervised actors also allow you to create sets (hierarchies) of actors where you can be sure that either all are dead or ...
That encourages non-defensive programming: don’t try to prevent things from go wrong, because they will. Failures are a na...
A supervisor is responsible for starting, stopping and monitoring its child processes. It can act with 2 fault handling st...
Declarative supervised actors configuration<br />Supervisor supervisor = new Supervisor(<br />  new SupervisorConfig(<br /...
Upcoming SlideShare
Loading in …5
×

Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM

9,395
-1

Published on

4 Comments
23 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,395
On Slideshare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
Downloads
197
Comments
4
Likes
23
Embeds 0
No embeds

No notes for slide

Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM

  1. 1. Concurrency, Scalability <br />& Fault-tolerance 2.0 with Actors & STM<br />by Mario Fusco<br />mario.fusco@gmail.com<br />twitter: @mariofusco<br />
  2. 2. Which are the biggestchallengesin contemporary software development?<br />
  3. 3. Deal with overloadedsystems<br />
  4. 4. Do concurrencyeffectively<br />
  5. 5. Design, develop and deployapplicationsthat scale well<br />
  6. 6. The native Java concurrency model<br />Based on:<br />Threads<br />Semaphores<br />Synchronization<br />Locks<br />They are sometimes plain evil …<br />… and sometimes a necessary pain …<br />… but always the wrong default<br />
  7. 7. Actors: a different model of concurrency<br /><ul><li>Implements Message-Passing Concurrency
  8. 8. Share NOTHING
  9. 9. Isolated lightweight processes
  10. 10. Communicates through messages
  11. 11. Asynchronous and non-blocking
  12. 12. Each actor has a mailbox (message queue)
  13. 13. A single thread can managemany (thousands of) actors</li></li></ul><li>People are bad at parallel thinking<br />With actors is easier to reason about and easier to avoid: <br />Race conditions, Deadlocks, Starvation and Live locks<br />
  14. 14. What is Akka?<br /><ul><li>An actor based concurrency framework
  15. 15. Written in Scala, butalsoworking in Java
  16. 16. Nowrealeasing 1.0 after 2 years of development (currentlyRC4 available)
  17. 17. Better performances and throughput and smallermemoryfootprint (650 bytes) than native scala actors
  18. 18. Open source (Apache2)</li></li></ul><li>Untyped Actors<br />public class MyUntypedActorextends UntypedActor {<br /> public void onReceive(Object message) throws Exception {<br /> if (message instanceofString) {<br /> String msg = (String)message;<br />System.out.println("Received message: " + msg);<br /> }<br /> }<br />}<br />UntypedActorRef actor = UntypedActor.actorOf(MyUntypedActor.class);<br />actor.start();<br />// --- Do some work here ---<br />actor.stop();<br />
  19. 19. Sending message to UntypedActors<br />There are 3 different ways to send a message to an actor:<br />Fire-and-forget ( ! In Scala )<br />actor.sendOneWay(msg);<br />Uses a Future under the hood, blocking the sender Actor until eithera reply is received or the Future times out ( !! In Scala )<br />Object res1 = actor.sendRequestReply(msg);<br />Object res2 = actor.sendRequestReply(msg, 1000); // timeout<br />Explicitly returns a Future ( !!! In Scala )<br />Future future= actor.sendRequestReplyFuture(msg);<br />IMPORTANT: Messages can be any kind of object but have to be immutable. <br />Akkacan’t enforce immutability (yet) so this has to be by convention<br />
  20. 20. Typed Actors<br />public class CounterImplextends TypedActorimplements Counter {<br /> private int counter = 0;<br /> public void count() {<br /> counter++;<br />System.out.println(counter);<br /> }<br /> public intgetCountNr() {<br />returncounter;<br /> }<br />}<br />Counter counter= (Counter)TypedActor<br /> .newInstance(Counter.class, CounterImpl.class, 1000);<br />counter.count(); // Fire-and-forget<br />intcount = counter.getCountNr(); // uses Future under the hood<br />
  21. 21. “Let it crash” <br />fault-tolerance <br />through <br />supervisor hierarchies<br />
  22. 22. You can’t avoid failures: shit happens<br />
  23. 23. What’swrong in trying to preventerrors?<br />Java and other languages and frameworks (not designed with concurrency in mind) signal faults/errors with exceptions<br />Throwing an exception in concurrent code will just simply blow up the thread that currently executes the code that threw it:<br />There is no way to find out that things went wrong, apart from inspecting the stack trace<br />There is nothing you can do to recover from the problem and bring back your system to a normal functioning<br />
  24. 24. Fail fast & build self-repairing systems<br />
  25. 25. Supervisedactors<br /><ul><li>Actors provide a clean way of getting error notification and do something about it
  26. 26. Supervised actors also allow you to create sets (hierarchies) of actors where you can be sure that either all are dead or none are dead
  27. 27. That encourages non-defensive programming: don’t try to prevent things from go wrong, because they will. Failures are a natural state in the life-cycle of your app: crash early and let someone else (that sees the whole picture), deal with it
  28. 28. A supervisor is responsible for starting, stopping and monitoring its child processes. It can act with 2 fault handling strategies:</li></ul>One-For-One<br />or All-For-One<br />
  29. 29. Declarative supervised actors configuration<br />Supervisor supervisor = new Supervisor(<br /> new SupervisorConfig(<br /> new AllForOneStrategy( // or OneForOneStrategy<br /> new Class[]{Exception.class}, // Exceptions to handle<br /> 3, // maximum number of restart retries<br /> 5000), // within time in millis<br /> new Supervise[] {<br /> new Supervise(<br />UntypedActor.actorOf(MyActor1.class),<br /> permanent()), // the actor will always be restarted<br /> new Supervise(<br />UntypedActor.actorOf(MyActor2.class),<br /> temporary()) // the actor won’t be shut down normally<br />}));<br />// You can also link and unlink actors from a supervisor<br />supervisor.link(actor1);<br />supervisor.unlink(actor1);<br />
  30. 30. Remote actors<br /><ul><li>Akka provides remote actors in a completely transparent way both in regards to sending messages, error handling and supervision
  31. 31. Uses a very efficient and scalable I/O implementation built upon JBossNetty and Google Protocol Buffers
  32. 32. Can be secured with a cookie authentication mechanism
  33. 33. Can be bothTyped and Untyped
  34. 34. Twotypes of remote actors:
  35. 35. server-managed: run on the machine thatcreateditwhile client can lookup and obtain a proxy
  36. 36. client managed: makethemrunning on a different machine while the localone just hold a proxy to sendthemmessages</li></li></ul><li>Server-managed<br />Client-managed<br />Typed<br />Bean actor = <br />TypedActor.newInstance(<br />Bean.class, BeanImpl.class, <br /> timeout); <br />Actors.remote()<br />.start("localhost", 9999)<br /> .registerTypedActor(<br /> “my-service", actor<br /> );<br />Bean remoteActor = <br /> (Bean)TypedActor<br /> .newRemoteInstance(<br />Bean.class, BeanImpl.class, <br /> timeout, "192.68.23.69", 9999<br /> );<br />Untyped<br />class MyActor<br /> extends UntypedActor {}<br />Actors.remote()<br /> .actorOf(MyActor.class, <br /> "192.68.23.69", 9999<br /> );<br />class MyActor<br /> extends UntypedActor {}<br />Actors.remote()<br /> .start("localhost", 9999)<br /> .register(“my-service", <br />actorOf(MyActor.class)<br /> );<br />
  37. 37. Software Transactional Memory<br />An STM turns the Java heap into a transactional data set with begin/commit/rollback semantics. Very much like a regular database. <br />It implements the first three letters in ACID; ACI: <br /><ul><li>Atomic: all or none of the changes made during a transaction get applied
  38. 38. Consistent: a transaction gets a consistent of reality
  39. 39. Isolated: changes made by concurrent execution transactions are not visible to each other</li></ul>Akka’s STM implements the concept already present in Clojure’s STM<br />The STM is based on Transactional References (referred to as Refs). Refs: <br /><ul><li>are memory cells, holding an (arbitrary) immutable value
  40. 40. implement CAS (Compare-And-Swap) semantics
  41. 41. are managed and enforced by the STM for coordinated changes across many Refs
  42. 42. are implemented using the excellent Multiverse STM (http://multiverse.codehaus.org)</li></li></ul><li>Why we need an STM?<br />public class Container {<br /> private int value; <br /> private final ReadWriteLock lock = new ReentrantReadWriteLock();<br /> public intgetValue() { <br />lock.readLock().lock(); <br /> try { <br /> return value; <br /> } finally { <br />lock.readLock.unlock(); <br /> } <br /> }   <br /> public void setValue(int value) { <br />lock.writeLock().lock(); <br /> try { <br />this.value= value; <br /> } finally { <br />lock.writeLock.unlock(); <br /> } <br /> } <br />}<br />What’swrong with it?<br /><ul><li>Ad-hoc and hardlyreusablelogic
  43. 43. Unnecessarycomplexity
  44. 44. Lockslimitconcurrency and thenthroughput</li></li></ul><li>How does Akka STM work?<br />// Create a Ref with an initial value (also possible without)<br />final Ref<Integer> ref = new Ref<Integer>(0); <br />  <br />public int counter() {<br />// A transaction is delimited using an Atomic anonymous inner class<br /> return new Atomic<Integer>() { <br /> public Integer atomically() { <br />intinc = ref.get() + 1; // Accessing the value of the Ref<br />ref.set(inc); // Changing the value of the Ref<br /> return inc; <br /> } <br /> }.execute(); <br />}<br /><ul><li>A transaction is automatically retried when it runs into some read or write conflict
  45. 45. In this case an (exponential) delay isused to preventfurthercontentions
  46. 46. Thereshouldn’t be side-effects inside the transaction to avoid to repeatthem</li></li></ul><li>Transactional Datastructures<br />final TransactionalMap<String, User> users = <br /> new TransactionalMap<String, User>();  <br />// fill users map (in a transaction)<br />new Atomic() { <br /> public Object atomically() { <br />users.put("bill", new User("bill")); <br />users.put("mary", new User("mary")); <br />users.put("john", new User("john")); <br /> return null; <br /> } <br />}.execute();   <br />// access users map (in a transaction)<br />User user = new Atomic<User>() { <br /> public User atomically() { <br /> return users.get("bill").get(); <br /> } <br />}.execute();<br />
  47. 47. Persistent Datastructures<br />Copyright Rich Hickey 2009<br />
  48. 48. Coordinating Actors with STM<br />public class Counter extends UntypedActor {<br /> private Ref<Integer> count = new Ref(0);<br /> private void increment() { count.set(count.get() + 1); }<br /> public void onReceive(Object incoming) throws Exception {<br /> if (incoming instanceof Coordinated) {<br /> Coordinated coordinated = (Coordinated) incoming;<br /> Object message = coordinated.getMessage();<br /> if (message instanceof Increment) {<br /> Increment increment = (Increment) message;<br /> if (increment.hasFriend()) {<br />increment.getFriend()<br /> .sendOneWay(coordinated.coordinate(new Increment()));<br /> }<br />coordinated.atomic(new Atomically() {<br /> public void atomically() {<br /> increment();<br /> }<br /> });<br />}}}}<br />
  49. 49. Actors + STM = Transactors<br />public class Counter extends UntypedTransactor {<br /> Ref<Integer> count = new Ref<Integer>(0);<br /> @Override public Set<SendTo> coordinate(Object message) {<br /> if (message instanceof Increment) {<br /> Increment increment = (Increment) message;<br /> if (increment.hasFriend())<br /> return include(increment.getFriend(), new Increment());<br /> }<br /> return nobody();<br /> }<br /> public void atomically(Object message) {<br /> if (message instanceof Increment) {<br />count.set(count.get() + 1);<br /> }<br /> }<br />}<br />
  50. 50. Other Akka goodies<br /><ul><li>Implements Advanced Message Queuing Protocol (AMPQ) based on the RabbitMQ
  51. 51. Integration with Apache Camel
  52. 52. PersistencemodulesupportingmanyNoSQL DB like: Cassandra, MongoDB, Riak, Redis, Terrastore, CouchDB, Voldemort, Hbase
  53. 53. Integration betweenAkkaSTM and JTA (Java Transaction API)
  54. 54. OSGisupport
  55. 55. Integration with Spring allowing to defineTyped Actors as Spring managed bean
  56. 56. Integration with Lift Web Framework and Play! Framework</li></li></ul><li>Thanks a lot!<br />Happy Java (or Scala) hing<br />by Mario Fusco<br />mario.fusco@gmail.com<br />twitter: @mariofusco<br />

×