SlideShare a Scribd company logo
WITH AKKA-CLUSTERSANE SHARDING
MichaĿ PĿachta
CLUSTERING IS HARD
★ no up-front design
★ load-balance
everything!
★ TIP: design it into
your application!
MEMBERSHIP SERVICE
AKKA-CLUSTER
★ fault-tolerant
★ decentralized
★ peer-to-peer
★ gossip protocols
★ failure detection
PERSIST & RECOVER
AKKA-PERSISTENCE
★ persist internal state of
an actor
★ recover after crash
★ recover after cluster
migration
THE SHOESORTER CASE
MESSAGES
case class Junction(id: Int)

case class Container(id: Int)

case class Conveyor(id: Int)

case class WhereShouldIGo(junction: Junction
container: Container)

case class Go(targetConveyor: Conveyor)
SortingDecider
★ simple actor
★ event-sourced
★ one per junction
★ is asked about container faith
★ limited time to respond
SortingDecider
class SortingDecider extends PersistentActor with ActorLogging {

def receiveCommand: Receive = {

case WhereShouldIGo(junction, container) => {

val targetConveyor = makeDecision(container)

log.info(s"Container ${container.id}
on junction ${junction.id}
directed to ${targetConveyor}")

sender ! Go(targetConveyor)

}

}



def makeDecision(container: Container) = ???
override def receiveRecover: Receive = ???

override def persistenceId: String = ???
}
DecidersGuardian
★ supervising actor for SortingDeciders
★ pipes queries to proper child
★ pipes answers to sender
DecidersGuardian
class DecidersGuardian extends Actor {

implicit val timeout = Timeout(5 seconds)



def receive = {

case msg @ WhereShouldIGo(junction, _) =>

val sortingDecider = getOrCreateChild("J" + junction.id, 

SortingDecider.props)

val futureAnswer = (sortingDecider ? msg).mapTo[Go]

futureAnswer.pipeTo(sender())

}



def getChild(name: String): Option[ActorRef] = context.child(name)



def getOrCreateChild(name: String, props: Props): ActorRef = {

getChild(name) getOrElse context.actorOf(props, name)

}

}

RestInterface
★ Spray-based web service
★ receives ActorRef on creation
★ sends him questions
RestInterface
class RestInterface(exposedPort: Int, decider: ActorRef)
extends Actor with HttpService {

val routes: Route = handleExceptions(exceptionHandler) {

handleRejections(rejectionHandler) {

get {

path("decisions" / IntNumber / IntNumber) { (junctionId,
containerId) =>

complete {

decider

.ask(WhereShouldIGo(

Junction(junctionId), 

Container(containerId)))

.mapTo[Go]

}

}

}

}

}

}

SingleNodeApp
object SingleNodeApp extends App {

val config = ConfigFactory.load()



val system = ActorSystem(config getString "application.name")

sys.addShutdownHook(system.shutdown())



val decidersGuardian = system.actorOf(DecidersGuardian.props)

system.actorOf(

RestInterface.props(

config getInt "application.exposed-port", 

decidersGuardian), 

name = "restInterfaceService")

}
LET’S RUN IT
> http http://localhost:8080/decisions/2/1
HTTP/1.1 200 OK
Content-Length: 33
Content-Type: application/json; charset=UTF-8
Date: Tue, 21 Apr 2015 13:50:08 GMT
Server: spray-can/1.3.2
{
"targetConveyor": "CVR_2_1"
}
15:49:47,715 INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
15:49:48,544 INFO spray.can.server.HttpListener - Bound to /0.0.0.0:8080
15:50:08,403 INFO
c.m.shoesorter.SortingDecider - [single-node akka://shoesorter/user/$a/J2}]
Container 1 on junction 2 directed to CVR_2_1
RestInterface
DecidersGuardian
SortingDecider
SortingDecider
SortingDecider
Journal
SINGLE-NODE SOLUTION
★ non-blocking
★ concurrent
★ scaling up works
★ what about scaling
out?
Node 1
RestInterface
Router
v vSortingDecider
Node 2
Journal
v vSortingDecider
SCALABILITY AS
AFTERTHOUGHT
★ Akka still helps
★ migrations are
held gracefully
★ centralized routing
★ journal contention
SHARDING
AKKA-CLUSTER
★ distribution of actors
★ interact using logical id
★ fine-grained shard
resolution
★ less contention
A SHARD?
★ group of entries
★ entry = sharded
actor
★ managed together
A SHARD ACTOR?
★ creates entries
★ supervises entries
★ not used directly
by us
A SHARD REGION
ACTOR?
★ supervises shards
★ one per node
★ has entry identifier
★ has shard
identifier
Node 1
RestInterface
v vSortingDecider
Node 2
Sharded Journal
v vSortingDecider
ShardRegion ShardRegion
Shard Shard
SortingDecider
class SortingDecider extends PersistentActor with ActorLogging {

def receiveCommand: Receive = {

case WhereShouldIGo(junction, container) => {

val targetConveyor = makeDecision(container)

log.info(s"Container ${container.id}
on junction ${junction.id}
directed to ${targetConveyor}")

sender ! Go(targetConveyor)

}

}



def makeDecision(container: Container) = ???
override def receiveRecover: Receive = ???

override def persistenceId: String = ???
}
NO CHANGE HERE
DecidersGuardian
class DecidersGuardian extends Actor {

implicit val timeout = Timeout(5 seconds)



def receive = {

case msg @ WhereShouldIGo(junction, _) =>

val sortingDecider = getOrCreateChild("J" + junction.id, 

SortingDecider.props)

val futureAnswer = (sortingDecider ? msg).mapTo[Go]

futureAnswer.pipeTo(sender())

}



def getChild(name: String): Option[ActorRef] = context.child(name)



def getOrCreateChild(name: String, props: Props): ActorRef = {

getChild(name) getOrElse context.actorOf(props, name)

}

}

NOT NEEDED
RestInterface
class RestInterface(exposedPort: Int, decider: ActorRef)
extends Actor with HttpService {

val routes: Route = handleExceptions(exceptionHandler) {

handleRejections(rejectionHandler) {

get {

path("decisions" / IntNumber / IntNumber) { (junctionId,
containerId) =>

complete {

decider

.ask(WhereShouldIGo(

Junction(junctionId), 

Container(containerId)))

.mapTo[Go]

}

}

}

}

}

}

NO CHANGE
ShardedApp
object ShardedApp extends App {

Seq(2551, 2552) foreach { port =>

val config = ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port).

withFallback(defaultConfig)



val system = ActorSystem(config getString "clustering.cluster.name", config)



ClusterSharding(system).start(

typeName = SortingDecider.shardName,

entryProps = Some(SortingDecider.props),

idExtractor = SortingDecider.idExtractor,

shardResolver = SortingDecider.shardResolver)



if(port == 2551) {

val decider = ClusterSharding(system).shardRegion(SortingDecider.shardName)

system.actorOf(

RestInterface.props(

defaultConfig getInt "application.exposed-port", 

decider), 

name = "restInterfaceService")

}

}

}

SortingDecider
object SortingDecider {

val props = Props[SortingDecider]



val idExtractor: ShardRegion.IdExtractor = {

case m: WhereShouldIGo => (m.junction.id.toString, m)

}



val shardResolver: ShardRegion.ShardResolver = msg => msg match {

case WhereShouldIGo(junction, _) => (junction.id % 2).toString

}



val shardName = "sortingDecider"

}
LET’S RUN IT
> http http://localhost:8080/decisions/2/1
HTTP/1.1 200 OK
{
"targetConveyor": "CVR_2_2"
}
> http http://localhost:8080/decisions/1/4
{
"targetConveyor": "CVR_1_2"
}
[shoesorter-cluster@127.0.0.1:2551 akka://shoesorter-cluster/user/sharding/
sortingDecider/2}] Container 1 on junction 2 directed to CVR_2_2
[shoesorter-cluster@127.0.0.1:2552 akka://shoesorter-cluster/user/sharding/
sortingDecider/1}] Container 4 on junction 1 directed to CVR_1_2
SHARD
COORDINATOR
★ cluster singleton
★ ShardRegions ask
him about Shard
location
★ pluggable
allocation strategy
★ shard locations are
persisted
ALLOCATION
STRATEGY
★ can be plugged in
to Shard
Coordinator
★ is used during
rebalancing of
shards
SHARD/NODE RATIO?
★ at least 1
★ rule of thumb: 10
★ more = too much
pressure on
coordinator
NEXT MEETUPS
★ clustering with
Docker
★ routing hacking
★ suggestions?
WITH AKKA-CLUSTERSANE SHARDING
MichaĿ PĿachta
Thank you

More Related Content

What's hot

CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.js
Forrest Norvell
 
Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions
Terral R Jordan
 
First glance at Akka 2.0
First glance at Akka 2.0First glance at Akka 2.0
First glance at Akka 2.0
Vasil Remeniuk
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Innovation and Security in Ruby on Rails
Innovation and Security in Ruby on RailsInnovation and Security in Ruby on Rails
Innovation and Security in Ruby on Railstielefeld
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
Lightbend
 
Akka persistence webinar
Akka persistence webinarAkka persistence webinar
Akka persistence webinarpatriknw
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
Troy Miles
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecordscalaconfjp
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
Manuel Bernhardt
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of Akka
Johan Andrén
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJiayun Zhou
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
Alex Eftimie
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
Idan Gazit
 
Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishy
Igor Napierala
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
FITC
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
Johan Andrén
 

What's hot (20)

CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.js
 
Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions
 
Scala active record
Scala active recordScala active record
Scala active record
 
First glance at Akka 2.0
First glance at Akka 2.0First glance at Akka 2.0
First glance at Akka 2.0
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Innovation and Security in Ruby on Rails
Innovation and Security in Ruby on RailsInnovation and Security in Ruby on Rails
Innovation and Security in Ruby on Rails
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Akka persistence webinar
Akka persistence webinarAkka persistence webinar
Akka persistence webinar
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of Akka
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
 
Jasmine BDD for Javascript
Jasmine BDD for JavascriptJasmine BDD for Javascript
Jasmine BDD for Javascript
 
Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishy
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
 

Viewers also liked

Akka Cluster in Production
Akka Cluster in ProductionAkka Cluster in Production
Akka Cluster in Production
bilyushonak
 
Resilient Applications with Akka Persistence - Scaladays 2014
Resilient Applications with Akka Persistence - Scaladays 2014Resilient Applications with Akka Persistence - Scaladays 2014
Resilient Applications with Akka Persistence - Scaladays 2014
Björn Antonsson
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
Konstantin Tsykulenko
 
Building applications with akka.net
Building applications with akka.netBuilding applications with akka.net
Building applications with akka.net
Anthony Brown
 
Akka.net versus microsoft orleans
Akka.net versus microsoft orleansAkka.net versus microsoft orleans
Akka.net versus microsoft orleans
Bill Tulloch
 
Akka cluster overview at 010dev
Akka cluster overview at 010devAkka cluster overview at 010dev
Akka cluster overview at 010devRoland Kuhn
 
CQRS Evolved - CQRS + Akka.NET
CQRS Evolved - CQRS + Akka.NETCQRS Evolved - CQRS + Akka.NET
CQRS Evolved - CQRS + Akka.NET
David Hoerster
 
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
Jonas Bonér
 
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data AnalysisApache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
DataWorks Summit/Hadoop Summit
 
Actor model in F# and Akka.NET
Actor model in F# and Akka.NETActor model in F# and Akka.NET
Actor model in F# and Akka.NET
Riccardo Terrell
 
Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#
Riccardo Terrell
 

Viewers also liked (11)

Akka Cluster in Production
Akka Cluster in ProductionAkka Cluster in Production
Akka Cluster in Production
 
Resilient Applications with Akka Persistence - Scaladays 2014
Resilient Applications with Akka Persistence - Scaladays 2014Resilient Applications with Akka Persistence - Scaladays 2014
Resilient Applications with Akka Persistence - Scaladays 2014
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
 
Building applications with akka.net
Building applications with akka.netBuilding applications with akka.net
Building applications with akka.net
 
Akka.net versus microsoft orleans
Akka.net versus microsoft orleansAkka.net versus microsoft orleans
Akka.net versus microsoft orleans
 
Akka cluster overview at 010dev
Akka cluster overview at 010devAkka cluster overview at 010dev
Akka cluster overview at 010dev
 
CQRS Evolved - CQRS + Akka.NET
CQRS Evolved - CQRS + Akka.NETCQRS Evolved - CQRS + Akka.NET
CQRS Evolved - CQRS + Akka.NET
 
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Ac...
 
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data AnalysisApache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
Apache Zeppelin + Livy: Bringing Multi Tenancy to Interactive Data Analysis
 
Actor model in F# and Akka.NET
Actor model in F# and Akka.NETActor model in F# and Akka.NET
Actor model in F# and Akka.NET
 
Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#Actor Clustering with Docker Containers and Akka.Net in F#
Actor Clustering with Docker Containers and Akka.Net in F#
 

Similar to Sane Sharding with Akka Cluster

Making Swift even safer
Making Swift even saferMaking Swift even safer
Making Swift even safer
Denis Fileev
 
Akka tips
Akka tipsAkka tips
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
Astrails
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
allanh0526
 
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
Henrik Engström
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
Chris Richardson
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
Andrzej Ludwikowski
 
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
Docker, Inc.
 
Lego: A brick system build by scala
Lego: A brick system build by scalaLego: A brick system build by scala
Lego: A brick system build by scalalunfu zhong
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Writing JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptxWriting JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptx
Ed Charbeneau
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
Paco de la Cruz
 
Event sourcing in the functional world (22 07-2021)
Event sourcing in the functional world (22 07-2021)Event sourcing in the functional world (22 07-2021)
Event sourcing in the functional world (22 07-2021)
Vitaly Brusentsev
 
Reactive Summit 2017
Reactive Summit 2017Reactive Summit 2017
Reactive Summit 2017
janm399
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-es
MongoDB
 
Resiliency & Security_Ballerina Day CMB 2018
Resiliency & Security_Ballerina Day CMB 2018  Resiliency & Security_Ballerina Day CMB 2018
Resiliency & Security_Ballerina Day CMB 2018
Ballerina
 
Codestrong 2012 breakout session hacking titanium
Codestrong 2012 breakout session   hacking titaniumCodestrong 2012 breakout session   hacking titanium
Codestrong 2012 breakout session hacking titaniumAxway Appcelerator
 

Similar to Sane Sharding with Akka Cluster (20)

Making Swift even safer
Making Swift even saferMaking Swift even safer
Making Swift even safer
 
Akka tips
Akka tipsAkka tips
Akka tips
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
 
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
 
Akka patterns
Akka patternsAkka patterns
Akka patterns
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
 
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
 
Lego: A brick system build by scala
Lego: A brick system build by scalaLego: A brick system build by scala
Lego: A brick system build by scala
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Writing JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptxWriting JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptx
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
Event sourcing in the functional world (22 07-2021)
Event sourcing in the functional world (22 07-2021)Event sourcing in the functional world (22 07-2021)
Event sourcing in the functional world (22 07-2021)
 
Reactive Summit 2017
Reactive Summit 2017Reactive Summit 2017
Reactive Summit 2017
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-es
 
dSS API by example
dSS API by exampledSS API by example
dSS API by example
 
Resiliency & Security_Ballerina Day CMB 2018
Resiliency & Security_Ballerina Day CMB 2018  Resiliency & Security_Ballerina Day CMB 2018
Resiliency & Security_Ballerina Day CMB 2018
 
Codestrong 2012 breakout session hacking titanium
Codestrong 2012 breakout session   hacking titaniumCodestrong 2012 breakout session   hacking titanium
Codestrong 2012 breakout session hacking titanium
 

Recently uploaded

Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 

Recently uploaded (20)

Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 

Sane Sharding with Akka Cluster

  • 2. CLUSTERING IS HARD ★ no up-front design ★ load-balance everything! ★ TIP: design it into your application!
  • 3. MEMBERSHIP SERVICE AKKA-CLUSTER ★ fault-tolerant ★ decentralized ★ peer-to-peer ★ gossip protocols ★ failure detection
  • 4. PERSIST & RECOVER AKKA-PERSISTENCE ★ persist internal state of an actor ★ recover after crash ★ recover after cluster migration
  • 6. MESSAGES case class Junction(id: Int)
 case class Container(id: Int)
 case class Conveyor(id: Int)
 case class WhereShouldIGo(junction: Junction container: Container)
 case class Go(targetConveyor: Conveyor)
  • 7. SortingDecider ★ simple actor ★ event-sourced ★ one per junction ★ is asked about container faith ★ limited time to respond
  • 8. SortingDecider class SortingDecider extends PersistentActor with ActorLogging {
 def receiveCommand: Receive = {
 case WhereShouldIGo(junction, container) => {
 val targetConveyor = makeDecision(container)
 log.info(s"Container ${container.id} on junction ${junction.id} directed to ${targetConveyor}")
 sender ! Go(targetConveyor)
 }
 }
 
 def makeDecision(container: Container) = ??? override def receiveRecover: Receive = ???
 override def persistenceId: String = ??? }
  • 9. DecidersGuardian ★ supervising actor for SortingDeciders ★ pipes queries to proper child ★ pipes answers to sender
  • 10. DecidersGuardian class DecidersGuardian extends Actor {
 implicit val timeout = Timeout(5 seconds)
 
 def receive = {
 case msg @ WhereShouldIGo(junction, _) =>
 val sortingDecider = getOrCreateChild("J" + junction.id, 
 SortingDecider.props)
 val futureAnswer = (sortingDecider ? msg).mapTo[Go]
 futureAnswer.pipeTo(sender())
 }
 
 def getChild(name: String): Option[ActorRef] = context.child(name)
 
 def getOrCreateChild(name: String, props: Props): ActorRef = {
 getChild(name) getOrElse context.actorOf(props, name)
 }
 }

  • 11. RestInterface ★ Spray-based web service ★ receives ActorRef on creation ★ sends him questions
  • 12. RestInterface class RestInterface(exposedPort: Int, decider: ActorRef) extends Actor with HttpService {
 val routes: Route = handleExceptions(exceptionHandler) {
 handleRejections(rejectionHandler) {
 get {
 path("decisions" / IntNumber / IntNumber) { (junctionId, containerId) =>
 complete {
 decider
 .ask(WhereShouldIGo(
 Junction(junctionId), 
 Container(containerId)))
 .mapTo[Go]
 }
 }
 }
 }
 }
 }

  • 13. SingleNodeApp object SingleNodeApp extends App {
 val config = ConfigFactory.load()
 
 val system = ActorSystem(config getString "application.name")
 sys.addShutdownHook(system.shutdown())
 
 val decidersGuardian = system.actorOf(DecidersGuardian.props)
 system.actorOf(
 RestInterface.props(
 config getInt "application.exposed-port", 
 decidersGuardian), 
 name = "restInterfaceService")
 }
  • 14. LET’S RUN IT > http http://localhost:8080/decisions/2/1 HTTP/1.1 200 OK Content-Length: 33 Content-Type: application/json; charset=UTF-8 Date: Tue, 21 Apr 2015 13:50:08 GMT Server: spray-can/1.3.2 { "targetConveyor": "CVR_2_1" } 15:49:47,715 INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started 15:49:48,544 INFO spray.can.server.HttpListener - Bound to /0.0.0.0:8080 15:50:08,403 INFO c.m.shoesorter.SortingDecider - [single-node akka://shoesorter/user/$a/J2}] Container 1 on junction 2 directed to CVR_2_1
  • 16. SINGLE-NODE SOLUTION ★ non-blocking ★ concurrent ★ scaling up works ★ what about scaling out?
  • 18. SCALABILITY AS AFTERTHOUGHT ★ Akka still helps ★ migrations are held gracefully ★ centralized routing ★ journal contention
  • 19. SHARDING AKKA-CLUSTER ★ distribution of actors ★ interact using logical id ★ fine-grained shard resolution ★ less contention
  • 20. A SHARD? ★ group of entries ★ entry = sharded actor ★ managed together
  • 21. A SHARD ACTOR? ★ creates entries ★ supervises entries ★ not used directly by us
  • 22. A SHARD REGION ACTOR? ★ supervises shards ★ one per node ★ has entry identifier ★ has shard identifier
  • 23. Node 1 RestInterface v vSortingDecider Node 2 Sharded Journal v vSortingDecider ShardRegion ShardRegion Shard Shard
  • 24. SortingDecider class SortingDecider extends PersistentActor with ActorLogging {
 def receiveCommand: Receive = {
 case WhereShouldIGo(junction, container) => {
 val targetConveyor = makeDecision(container)
 log.info(s"Container ${container.id} on junction ${junction.id} directed to ${targetConveyor}")
 sender ! Go(targetConveyor)
 }
 }
 
 def makeDecision(container: Container) = ??? override def receiveRecover: Receive = ???
 override def persistenceId: String = ??? } NO CHANGE HERE
  • 25. DecidersGuardian class DecidersGuardian extends Actor {
 implicit val timeout = Timeout(5 seconds)
 
 def receive = {
 case msg @ WhereShouldIGo(junction, _) =>
 val sortingDecider = getOrCreateChild("J" + junction.id, 
 SortingDecider.props)
 val futureAnswer = (sortingDecider ? msg).mapTo[Go]
 futureAnswer.pipeTo(sender())
 }
 
 def getChild(name: String): Option[ActorRef] = context.child(name)
 
 def getOrCreateChild(name: String, props: Props): ActorRef = {
 getChild(name) getOrElse context.actorOf(props, name)
 }
 }
 NOT NEEDED
  • 26. RestInterface class RestInterface(exposedPort: Int, decider: ActorRef) extends Actor with HttpService {
 val routes: Route = handleExceptions(exceptionHandler) {
 handleRejections(rejectionHandler) {
 get {
 path("decisions" / IntNumber / IntNumber) { (junctionId, containerId) =>
 complete {
 decider
 .ask(WhereShouldIGo(
 Junction(junctionId), 
 Container(containerId)))
 .mapTo[Go]
 }
 }
 }
 }
 }
 }
 NO CHANGE
  • 27. ShardedApp object ShardedApp extends App {
 Seq(2551, 2552) foreach { port =>
 val config = ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port).
 withFallback(defaultConfig)
 
 val system = ActorSystem(config getString "clustering.cluster.name", config)
 
 ClusterSharding(system).start(
 typeName = SortingDecider.shardName,
 entryProps = Some(SortingDecider.props),
 idExtractor = SortingDecider.idExtractor,
 shardResolver = SortingDecider.shardResolver)
 
 if(port == 2551) {
 val decider = ClusterSharding(system).shardRegion(SortingDecider.shardName)
 system.actorOf(
 RestInterface.props(
 defaultConfig getInt "application.exposed-port", 
 decider), 
 name = "restInterfaceService")
 }
 }
 }

  • 28. SortingDecider object SortingDecider {
 val props = Props[SortingDecider]
 
 val idExtractor: ShardRegion.IdExtractor = {
 case m: WhereShouldIGo => (m.junction.id.toString, m)
 }
 
 val shardResolver: ShardRegion.ShardResolver = msg => msg match {
 case WhereShouldIGo(junction, _) => (junction.id % 2).toString
 }
 
 val shardName = "sortingDecider"
 }
  • 29. LET’S RUN IT > http http://localhost:8080/decisions/2/1 HTTP/1.1 200 OK { "targetConveyor": "CVR_2_2" } > http http://localhost:8080/decisions/1/4 { "targetConveyor": "CVR_1_2" } [shoesorter-cluster@127.0.0.1:2551 akka://shoesorter-cluster/user/sharding/ sortingDecider/2}] Container 1 on junction 2 directed to CVR_2_2 [shoesorter-cluster@127.0.0.1:2552 akka://shoesorter-cluster/user/sharding/ sortingDecider/1}] Container 4 on junction 1 directed to CVR_1_2
  • 30. SHARD COORDINATOR ★ cluster singleton ★ ShardRegions ask him about Shard location ★ pluggable allocation strategy ★ shard locations are persisted
  • 31. ALLOCATION STRATEGY ★ can be plugged in to Shard Coordinator ★ is used during rebalancing of shards
  • 32. SHARD/NODE RATIO? ★ at least 1 ★ rule of thumb: 10 ★ more = too much pressure on coordinator
  • 33. NEXT MEETUPS ★ clustering with Docker ★ routing hacking ★ suggestions?