Advanced Akka For Architects

38

Transcript of Advanced Akka For Architects

Page 1: Advanced Akka For Architects
Page 2: Advanced Akka For Architects

Akka Multi-Data Center Clustering

Cluster Singletons

Cluster Sharding

Persistence

Page 3: Advanced Akka For Architects

Akka Single Node

Page 4: Advanced Akka For Architects

Akka Cluster

Single Data Center

Page 5: Advanced Akka For Architects

Akka Cluster

Single Data Center

Split Brain

Unresponsive Member

Page 6: Advanced Akka For Architects

Speed of light 300 km/ms, 186 mi/ms Small circle radius 3,000 km, 1,860 mi ~ 10 ms SOL distance

Page 7: Advanced Akka For Architects

Single Akka Cluster

Multi Data Center

Page 8: Advanced Akka For Architects

Multiple Akka Clusters

Multi Data Center

Page 9: Advanced Akka For Architects

Multiple Akka Clusters

Multi Data Center

akka.cluster { # Change this to real hostname for production seed-nodes = ["akka.tcp://ClusterSystem@host1:2552", "akka.tcp://ClusterSystem@host2:2552"]

# Change this to the Akka data center this node belongs to multi-data-center.self-data-center = DC-A}akka.persistence { snapshot-store.plugin = "cassandra-snapshot-store"

multi-data-center { all-data-centers = ["DC-A", “DC-B", “DC-C”] }}

Page 10: Advanced Akka For Architects

Multiple Akka Clusters

Clusters within Clusters

Page 11: Advanced Akka For Architects

Multiple Akka Clusters

Clusters within Clusters

Network Partition

Page 12: Advanced Akka For Architects

Multiple Akka Clusters

Clusters within Clusters

Node Failure

Page 13: Advanced Akka For Architects

Cluster Events

Within Data Center MemberJoined

MemberUp MemberExited

MemberRemoved UnreachableMember

ReachableMember

Cross Data Center UnreachableMember

ReachableMember

Page 14: Advanced Akka For Architects

Multiple Akka Clusters

Physical or Logical “Data Centers”

Clusters within Clusters

Microservice

Microservice Micros

ervic

e

Page 15: Advanced Akka For Architects

Cluster Singleton

One per Data Center

Page 16: Advanced Akka For Architects

Cluster Sharding

One per Data Center

Page 17: Advanced Akka For Architects

Cluster Sharding

Shard Region Proxy

Page 18: Advanced Akka For Architects

Cluster Sharding

ShardRegion Proxy

val counterProxyDcB: ActorRef = ClusterSharding(system).startProxy( typeName = "Counter", role = None, dataCenter = Some(“C"), extractEntityId = extractEntityId, extractShardId = extractShardId)

Page 19: Advanced Akka For Architects

Akka Persistence

One per Data Center

Page 20: Advanced Akka For Architects

Multi Data Center Persistence

Commercial Add-on

Page 21: Advanced Akka For Architects

Multi-DC Persistence

Replicated Entities

Page 22: Advanced Akka For Architects

Multi-DC Persistence

Concurrent Writes

Page 23: Advanced Akka For Architects

import akka.persistence.multidc.scaladsl.ReplicatedEntity

final class Post1 extends ReplicatedEntity[BlogCommand, BlogEvent, BlogState] {

override def initialState: BlogState = BlogState.empty

override def commandHandler: CommandHandler = CommandHandler { (ctx, state, cmd) => ??? }

override def eventHandler(state: BlogState, event: BlogEvent): BlogState = ???}

Page 24: Advanced Akka For Architects

import akka.persistence.multidc.javadsl.CommandHandler;import akka.persistence.multidc.javadsl.EventHandler;import akka.persistence.multidc.javadsl.ReplicatedEntity;

final class Post1 extends ReplicatedEntity<BlogCommand, BlogEvent, BlogState> {

@Override public BlogState initialState() { return BlogState.EMPTY; }

@Override public CommandHandler<BlogCommand, BlogEvent, BlogState> commandHandler() { throw new RuntimeException("Not implemented yet"); }

@Override public EventHandler<BlogEvent, BlogState> eventHandler() { throw new RuntimeException("Not implemented yet"); }}

Page 25: Advanced Akka For Architects

import akka.persistence.multidc.javadsl.CommandHandler;import akka.persistence.multidc.javadsl.EventHandler;import akka.persistence.multidc.javadsl.ReplicatedEntity;

final class Post1 extends ReplicatedEntity<BlogCommand, BlogEvent, BlogState> {

@Override public BlogState initialState() { return BlogState.EMPTY; }

@Override public CommandHandler<BlogCommand, BlogEvent, BlogState> commandHandler() { throw new RuntimeException("Not implemented yet"); }

@Override public EventHandler<BlogEvent, BlogState> eventHandler() { throw new RuntimeException("Not implemented yet"); }}

Page 26: Advanced Akka For Architects

public CommandHandler<BlogCommand, BlogEvent, BlogState> commandHandler() { return commandHandlerBuilder(BlogCommand.class) .matchCommand(AddPost.class, (ctx, state, cmd) -> { final PostAdded evt = new PostAdded(cmd.postId, cmd.content, state.contentTimestamp.increase(currentTimeMillis(), getSelfDc())); return Effect().persist(evt).andThen((state2) -> // After persist is done additional side effects can be performed ctx.getSender().tell(new AddPostDone(cmd.postId), getSelf()) ); })

public EventHandler<BlogEvent, BlogState> eventHandler() { return eventHandlerBuilder(BlogEvent.class) .matchEvent(PostAdded.class, (state, postAdded) -> { if (postAdded.timestamp.isAfter(state.contentTimestamp)) { return state.withContent(postAdded.content, postAdded.timestamp); } else { return state; } })

Page 27: Advanced Akka For Architects

Multi-DC Persistence

Replication and handling of events

Page 28: Advanced Akka For Architects

Multi-DC Persistence - Last writer wins

Page 29: Advanced Akka For Architects

// eventHandler is used both when persisting new events, replaying// events, and consuming replicated events.override def eventHandler(state: BlogState, event: BlogEvent): BlogState = { event match { case PostAdded(postId, content, timestamp) => if (timestamp.isAfter(state.contentTimestamp)) state.withContent(content, timestamp) else state

case BodyChanged(_, newContent, timestamp) => if (timestamp.isAfter(state.contentTimestamp)) state.withContent(newContent, timestamp) else state

case Published(_) => state.copy(published = true) }}

Page 30: Advanced Akka For Architects

// the returned event handler is used both when persisting new events, replaying// events, and consuming replicated events.@Overridepublic EventHandler<BlogEvent, BlogState> eventHandler() { return eventHandlerBuilder(BlogEvent.class) .matchEvent(PostAdded.class, (state, postAdded) -> { if (postAdded.timestamp.isAfter(state.contentTimestamp)) { return state.withContent(postAdded.content, postAdded.timestamp); } else { return state; } }) .matchEvent(BodyChanged.class, (state, bodyChanged) -> { if (bodyChanged.timestamp.isAfter(state.contentTimestamp)) { return state.withContent(bodyChanged.content, bodyChanged.timestamp); } else { return state; } }) .matchEvent(Published.class, (state, publish) -> state.publish()) .matchAny((state, otherEvent) -> state);}

Page 31: Advanced Akka For Architects

override def eventTrigger( ctx: EventTriggerContext, state: State, event: Event): Effect[Event, State] = { event match { case StepStarted(nr) => authority ! RequestApproval(nr) ctx.actorContext.timers.startPeriodicTimer(ResendTick, ResendTick, resendInterval) Effect.none case StepApproved(_, _) => if (!state.denied && selfDc == "DC-A" && state.isCurrentStepApproved && state.currentStep < maxSteps) { // approved by all, continue with next step log.info("Step {} approved by all, continue", state.currentStep) Effect.persist(StepStarted(state.currentStep + 1)) } else Effect.none case _ => Effect.none } }

Page 32: Advanced Akka For Architects

@Override public Effect<Event, State> eventTrigger(EventTriggerContext ctx, State state, Event event) { if (event instanceof StepStarted) { StepStarted stepStarted = (StepStarted) event; authority.tell(new RequestApproval(stepStarted.stepNr), ctx.actorContext().getSelf()); ctx.actorContext().getTimers().startPeriodicTimer(ResendTick.INSTANCE, ResendTick.INSTANCE, resendInterval); return Effect().none(); } else if (event instanceof StepApproved) { StepApproved stepApproved = (StepApproved) event; if (!state.denied && getSelfDc().equals("DC-A") && state.isCurrentStepApproved() && state.currentStep < maxSteps) { // approved by all, continue with next step log().info("Step {} approved by all, continue", state.currentStep); return Effect().persist(new StepStarted(state.currentStep + 1)); } else return Effect().none();

} else { return Effect().none(); } }

Page 33: Advanced Akka For Architects

Akka Multi-Data Center Clustering

In summary

Page 34: Advanced Akka For Architects

Want to learn more about Akka Multi Data Center?

Cluster across multiple data centers - http://bit.ly/2iY8qLO

Multi-DC Persistence (Akka Commercial Addons) - http://bit.ly/2zSN9GC

Page 35: Advanced Akka For Architects

Get your team hooked on Akka with this comprehensive introduction by Hugh McKee: “Akka Revealed”

GO TO VIDEO & SLIDES

Next Steps - Introduce Your Team To Akka

Page 36: Advanced Akka For Architects

Learn why Akka is so ideal for distributed systems with a free copy of Hugh McKee’s O’Reilly eBook: Designing Reactive Systems: The Role of Actors in Distributed Architecture

GET A COPY

Next Steps - Learn The “Why” Of Akka Actors

Page 37: Advanced Akka For Architects

Are you a serious enterprise looking to run Akka and other Lightbend technologies in production? Let us know when it’s time for a chat!

CONTACT US

Next Steps - Enterprise Add-Ons & Support

Page 38: Advanced Akka For Architects