SlideShare a Scribd company logo
Implemen'ng	
  a	
  	
  
Distributed	
  Hash	
  Table	
  
with	
  Scala	
  and	
  Akka	
  
Tristan	
  Penman	
  
@tristanpenman	
  
This	
  Talk	
  in	
  a	
  nutshell	
  
1.  An	
  intro	
  to	
  DHTs,	
  the	
  Chord	
  protocol	
  and	
  its	
  
suppor'ng	
  algorithms	
  
2.  Demo	
  applica'on	
  
3.  Modeling	
  the	
  Chord	
  protocol	
  using	
  actors	
  (while	
  
following	
  Akka	
  best	
  prac'ces)	
  
4.  Akka	
  paIerns	
  (Ask	
  and	
  Pipe)	
  
5.  Closing	
  remarks	
  and	
  useful	
  resources	
  
But	
  first…	
  an	
  Akka	
  refresher	
  
•  Framework	
  for	
  building	
  concurrent,	
  
distributed,	
  and	
  resilient	
  message-­‐driven	
  
applica'ons	
  
– Based	
  on	
  asynchronous	
  message	
  passing	
  
•  Emphasises	
  actor-­‐based	
  concurrency	
  
– Model	
  individual	
  components	
  as	
  ‘Actors’	
  
– Allows	
  us	
  to	
  build	
  an	
  applica'on	
  from	
  individual	
  
components	
  that	
  respond	
  to	
  a	
  set	
  of	
  well-­‐
formaIed	
  messages	
  
An	
  intro	
  to	
  DHTs,	
  the	
  Chord	
  
protocol	
  and	
  its	
  suppor'ng	
  
algorithms	
  
Hash	
  Tables	
  in	
  one	
  slide	
  
•  A	
  hash	
  table	
  is	
  a	
  data	
  structure	
  
used	
  to	
  implement	
  an	
  
associa've	
  array	
  
•  Lookup	
  and	
  inser'on	
  
opera'ons	
  run	
  in	
  constant-­‐'me	
  
•  Each	
  element	
  of	
  the	
  array	
  is	
  a	
  
bucket	
  that	
  contains	
  one	
  or	
  
more	
  keys	
  
–  Think	
  of	
  a	
  bucket	
  as	
  owning	
  a	
  non-­‐
con'guous	
  subset	
  of	
  the	
  key-­‐
space	
  
Visual	
  representa'on	
  of	
  
a	
  hash	
  table	
  
Diagram	
  from:	
  hIp://math.hws.edu/eck/cs124/javanotes6/c10/s3.html	
  
Distributed	
  Hash	
  Tables	
  
•  What	
  do	
  you	
  do	
  when	
  you	
  can’t	
  store	
  all	
  of	
  your	
  data	
  on	
  one	
  
node?	
  (Or	
  don’t	
  want	
  to)	
  
–  Spread	
  the	
  data	
  across	
  mul'ple	
  nodes,	
  with	
  each	
  node	
  taking	
  
responsibility	
  for	
  a	
  por'on	
  of	
  the	
  key-­‐space	
  
–  Nodes	
  ==	
  buckets	
  
•  First	
  problem:	
  
–  How	
  do	
  we	
  figure	
  out	
  which	
  node	
  is	
  responsible	
  for	
  a	
  key?	
  
•  Second	
  problem:	
  
–  How	
  do	
  we	
  handle	
  changes	
  to	
  the	
  network	
  topology?	
  
–  Nodes	
  can	
  join	
  or	
  leave	
  the	
  network	
  at	
  any	
  'me	
  
The	
  Chord	
  Protocol	
  
•  Chord	
  is	
  a	
  protocol	
  and	
  set	
  of	
  
algorithms	
  for	
  implemen'ng	
  a	
  
Distributed	
  Hash	
  Table	
  
•  Key	
  features	
  are:	
  
–  Lookup	
  'me	
  is	
  logarithmic	
  in	
  the	
  
number	
  of	
  network	
  nodes	
  
–  Asynchronous	
  network	
  stabiliza'on	
  
protocol	
  
–  Consistent	
  Hashing	
  minimizes	
  
disrup'ons	
  when	
  nodes	
  join	
  or	
  
leave	
  the	
  network	
  
Final	
  paper	
  (published	
  in	
  Transac'ons	
  on	
  Networking):	
  hIps://pdos.csail.mit.edu/papers/ton:chord/paper-­‐ton.pdf	
  
Applica'on	
  Layer	
  
•  “Does	
  not	
  specify	
  applica'on	
  layer	
  behavior”	
  
– Does	
  not	
  prescribe	
  replica'on	
  techniques	
  
– Same	
  applies	
  to	
  load	
  balancing	
  of	
  requests	
  coming	
  
into	
  the	
  network	
  
– Redistribu'on	
  of	
  data	
  associated	
  with	
  keys	
  when	
  
nodes	
  leave	
  or	
  join	
  the	
  network	
  is	
  the	
  
responsibility	
  of	
  the	
  applica'on	
  
Visualizing	
  Chord	
  
•  Instead	
  of	
  an	
  array,	
  we	
  have	
  a	
  
key-­‐space	
  which	
  can	
  be	
  visualized	
  
as	
  a	
  ring	
  
•  A	
  hash	
  func'on	
  is	
  used	
  to	
  map	
  
keys	
  onto	
  loca'ons	
  on	
  the	
  ring	
  
•  Nodes	
  are	
  also	
  mapped	
  to	
  
loca'ons	
  on	
  the	
  ring	
  
–  Typically	
  determined	
  by	
  applying	
  a	
  
hash	
  func'on	
  to	
  their	
  IP	
  address	
  and	
  
port	
  number	
  
Empty	
  circles	
  represent	
  dis'nct	
  
loca'ons	
  on	
  the	
  ring.	
  Blue-­‐filled	
  
circles	
  indicate	
  that	
  nodes	
  exist	
  
at	
  those	
  loca'ons.	
  
Diagram	
  from:	
  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html	
  
Consistent	
  Hashing	
  
•  Chord	
  assigns	
  responsibility	
  for	
  segments	
  of	
  the	
  ring	
  to	
  
individual	
  nodes	
  
–  This	
  scheme	
  is	
  called	
  Consistent	
  Hashing	
  
–  Allows	
  nodes	
  to	
  be	
  added	
  or	
  removed	
  from	
  the	
  network	
  while	
  
minimizing	
  the	
  number	
  of	
  keys	
  that	
  will	
  need	
  to	
  be	
  reassigned	
  
•  We	
  can	
  figure	
  out	
  which	
  node	
  owns	
  a	
  given	
  key	
  by	
  applying	
  
the	
  hash	
  func'on,	
  then	
  choosing	
  the	
  node	
  whose	
  loca'on	
  on	
  
the	
  ring	
  is	
  equal	
  to	
  or	
  greater	
  than	
  that	
  of	
  the	
  key	
  
–  This	
  node	
  is	
  the	
  ‘successor’	
  of	
  the	
  key.	
  
Adding	
  a	
  node	
  
Diagram	
  from:	
  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html	
  
Node	
  6	
  has	
  
been	
  added	
  to	
  
the	
  network	
  
Lookup	
  and	
  Insert	
  Opera'ons	
  
•  Lookup	
  and	
  insert	
  opera'ons	
  are	
  based	
  on	
  key	
  
ownership	
  
–  When	
  we	
  want	
  to	
  find	
  a	
  key,	
  we	
  use	
  the	
  hash	
  func'on	
  
to	
  find	
  its	
  loca'on	
  on	
  the	
  ring	
  
–  Given	
  the	
  loca'on	
  of	
  a	
  key	
  on	
  the	
  ring,	
  Chord	
  allows	
  
us	
  to	
  efficiently	
  iden'fy	
  its	
  successor	
  
–  For	
  lookups,	
  we	
  ask	
  the	
  successor	
  whether	
  it	
  knows	
  
about	
  the	
  key	
  that	
  we’re	
  interested	
  in	
  
•  Applica'on-­‐layer	
  is	
  responsible	
  for	
  further	
  logic	
  
–  For	
  insert	
  opera'ons,	
  we	
  tell	
  the	
  successor	
  to	
  store	
  
the	
  given	
  key	
  
Network	
  Stabiliza'on	
  
•  Each	
  node	
  needs	
  to	
  maintain	
  
pointers	
  to	
  other	
  nodes	
  
–  Successor(s)	
  
–  Predecessor	
  
–  Finger	
  table	
  
•  Finger	
  table	
  is	
  a	
  list	
  of	
  nodes	
  at	
  
increasing	
  distances	
  from	
  the	
  
current	
  node	
  
–  E.g.	
  n,	
  n+1,	
  n+2,	
  n+4,	
  …	
  
–  Allows	
  for	
  shortcuts	
  across	
  
segments	
  of	
  the	
  network,	
  hence	
  the	
  
name	
  Chord	
  
Finger	
  tables	
  allow	
  lookup	
  
opera'ons	
  to	
  take	
  shortcuts	
  across	
  
the	
  key-­‐space	
  
Diagram	
  from:	
  hIps://en.wikipedia.org/wiki/Chord_(peer-­‐to-­‐peer)	
  
Visualizing	
  Stabiliza'on	
  
•  Node	
  3	
  joins	
  network,	
  with	
  node	
  10	
  as	
  its	
  ini'al	
  successor	
  
•  Node	
  3	
  begins	
  stabiliza'on;	
  asks	
  node	
  10	
  for	
  its	
  predecessor	
  
•  Node	
  10	
  tells	
  node	
  3	
  that	
  its	
  predecessor	
  is	
  node	
  8	
  
•  Node	
  8	
  is	
  closer	
  to	
  node	
  3,	
  and	
  becomes	
  its	
  new	
  successor	
  
•  Node	
  3	
  no'fies	
  node	
  8	
  of	
  the	
  change,	
  so	
  node	
  3	
  updates	
  its	
  predecessor	
  pointer	
  
Diagram	
  adapted	
  from:	
  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html	
  
Chord	
  algorithms	
  
•  A	
  Chord	
  network	
  can	
  be	
  thought	
  of	
  as	
  a	
  dynamic	
  distributed	
  
data	
  structure	
  
•  The	
  Chord	
  protocol	
  defines	
  eight	
  algorithms	
  that	
  are	
  used	
  to	
  
navigate	
  and	
  maintain	
  this	
  data	
  structure:	
  
–  CheckPredecessor	
  
–  ClosestPrecedingNode	
  
–  FindPredecessor	
  
–  FindSuccessor	
  
–  FixFingers	
  
–  Join	
  
–  No'fy	
  
–  Stabilize	
  
We’re	
  going	
  to	
  focus	
  	
  
on	
  Stabiliza(on	
  
A	
  quick	
  demo	
  
Code	
  available	
  at:	
  
hIps://github.com/tristanpenman/chordial	
  
Modeling	
  Chord	
  using	
  Actors	
  
(while	
  following	
  Akka	
  best	
  prac'ces)	
  
Actor	
  Model	
  
•  Computa'ons	
  defined	
  in	
  terms	
  of	
  individual	
  
components	
  that	
  respond	
  to	
  a	
  set	
  of	
  well-­‐formaIed	
  
messages	
  
•  Group	
  of	
  actors	
  is	
  an	
  Actor	
  System	
  
•  Message	
  Passing	
  is	
  asynchronous	
  
•  But	
  nodes	
  process	
  messages	
  sequen'ally	
  
What	
  (who)	
  are	
  our	
  actors?	
  
Node	
  1	
  
Node	
  2	
  
Node	
  3	
  
Node	
  4	
  
•  Nodes	
  are	
  an	
  obvious	
  
star'ng	
  place…	
  
–  Stores	
  network	
  pointers	
  
–  Supports	
  message	
  nine	
  
types,	
  along	
  with	
  the	
  
appropriate	
  response	
  
messages	
  
–  Timing	
  logic	
  for	
  
stabiliza'on…	
  
–  This	
  is	
  star(ng	
  to	
  sound	
  
really	
  complicated!	
  
Decomposi'on	
  via	
  Best	
  Prac'ces	
  
•  By	
  iden'fying	
  some	
  Best	
  Prac'ces,	
  we	
  can	
  
take	
  a	
  more	
  principled	
  approach	
  to	
  
decomposing	
  our	
  Actor	
  System	
  
•  We	
  want	
  to	
  preserve	
  three	
  key	
  proper'es:	
  
– Determinism	
  
– Immutability	
  and	
  referen'al	
  transparency	
  
– Thread-­‐safety	
  
Case	
  study:	
  Stabiliza'on	
  
•  Chord	
  requires	
  that	
  a	
  node	
  should	
  periodically	
  
perform	
  a	
  stabiliza'on	
  opera'on	
  
–  Stabiliza'on	
  ensures	
  that	
  the	
  node’s	
  successor	
  is	
  s'll	
  the	
  
next	
  closest	
  node	
  on	
  the	
  ring	
  
–  If	
  a	
  closer	
  node	
  is	
  found,	
  then	
  the	
  successor	
  pointer	
  
needs	
  to	
  be	
  updated	
  (involves	
  a	
  state	
  change)	
  
•  Let’s	
  look	
  at	
  how	
  we	
  might	
  implement	
  periodic	
  
stabiliza'on	
  using	
  Scala	
  and	
  Akka…	
  
–  Useful	
  exercise	
  to	
  explore	
  some	
  Akka	
  best	
  prac'ces	
  
Stabiliza'on…	
  The	
  Wrong	
  Way	
  
class Node(val initialSuccessor: ActorRef) extends Actor {
var successor: ActorRef = initialSuccessor
def doStabilization: Future[ActorRef] = ???
override def receive: Receive = {
case Stabilize() =>
val newSuccessorFuture = doStabilization()
newSuccessorFuture.onSuccess { newSuccessor =>
successor = newSuccessor
}
}
context.system.scheduler.schedule(3000.milliseconds,
3000.milliseconds, self, Stabilize())
}
•  Actor	
  state	
  should	
  only	
  ever	
  evolve	
  in	
  response	
  
to	
  messages	
  received	
  from	
  the	
  outside	
  
– Internal	
  scheduling	
  makes	
  an	
  actor’s	
  state	
  non-­‐
determinis'c,	
  which	
  is	
  par'cularly	
  bad	
  for	
  tes'ng	
  
– Scheduling	
  should	
  take	
  place	
  outside	
  the	
  actor	
  
class MyActor extends Actor {
var counter = 0
override def receive: Receive = {
case IncrementCounter() =>
counter += 1
}
context.system.scheduler.schedule(2.seconds, 3.seconds,
self, IncrementCounter())
}
class MyActor extends Actor {
var counter = 0
override def receive: Receive = {
case IncrementCounter() =>
counter += 1
}
}
object MyActor {
case class IncrementCounter()
}
class MyApp extends App {
val myActor =
context.actorOf(Props(classOf[MyActor]))
system.scheduler.schedule(2.seconds, 3.seconds,
myActor, IncrementCounter())
}
•  Actor	
  state	
  should	
  only	
  ever	
  be	
  mutated	
  with	
  a	
  
call	
  to	
  `context.become`	
  
– Using	
  vars	
  (or	
  vals	
  for	
  mutable	
  objects)	
  allows	
  
unintended	
  states	
  to	
  be	
  introduced	
  
– Prefer	
  immutability	
  and	
  referen'al	
  transparency	
  
class MyActor extends Actor {
val isInSet = mutable.Set.empty[String]
override def receive: Receive = {
case AddToSet(key) =>
isInSet += key
case Contains(key) =>
sender() ! isInSet(key)
}
}
class MyActor extends Actor {
def activeSet(isInSet: Set[String]): Receive = {
case Add(key) =>
context.become(activeSet(isInSet + key))
case Contains(key) =>
sender() ! isInSet(key)
}
override def receive: Receive = active(Set.empty)
}
•  Actor	
  state	
  should	
  not	
  be	
  allowed	
  to	
  leak	
  into	
  
asynchronous	
  closures	
  
– A	
  Closure	
  may	
  be	
  executed	
  on	
  another	
  thread	
  
– Akka’s	
  Context	
  class	
  is	
  not	
  thread-­‐safe,	
  which	
  
means	
  no	
  more	
  calls	
  to	
  ‘context.become’:	
  
class MyActor extends Actor {
def withConfig(config: String): Receive = ???
override def receive: Receive = {
case Initialise() =>
val myFuture = loadConfig()
myFuture.onSuccess { config =>
context.become(withConfig(config))
}
}
}
class MyActor extends Actor {
def withConfig(config: String): Receive = ???
override def receive: Receive = {
case Initialise() =>
val myFuture = loadConfig()
myFuture.onSuccess { config =>
self ! ConfigLoaded(config)
}
case ConfigLoaded(config) =>
context.become(withConfig(config))
}
}
Stabiliza'on…	
  Improved	
  
class Node(val initialSuccessor: ActorRef) extends Actor {
def doStabilization: Future[ActorRef] = ???
def active(successor: ActorRef): Receive = {
case Stabilize() =>
val newSuccessorFuture = doStabilization()
newSuccessorFuture.onSuccess { newSuccessor =>
self ! Stabilized(newSuccessor)
}
case Stabilized(newSuccessor) =>
context.become(active(newSuccessor))
}
override def receive: Receive = active(initialSuccessor)
}
Best	
  Prac'ces	
  in	
  Summary	
  
•  Here	
  are	
  the	
  three	
  Best	
  Prac'ces	
  that	
  we’ll	
  come	
  
back	
  to	
  while	
  designing	
  our	
  Actor	
  System:	
  
1.  Actor	
  state	
  should	
  only	
  ever	
  evolve	
  in	
  response	
  to	
  
messages	
  received	
  from	
  the	
  outside	
  
2.  Actor	
  state	
  should	
  only	
  ever	
  be	
  mutated	
  with	
  a	
  call	
  to	
  
`context.become`	
  
3.  Actor	
  state	
  should	
  not	
  be	
  allowed	
  to	
  leak	
  into	
  
asynchronous	
  closures	
  
Based	
  on	
  best	
  prac'ces	
  documented	
  at:	
  hIps://github.com/alexandru/scala-­‐best-­‐prac'ces	
  
How	
  can	
  we	
  decompose	
  this	
  actor?	
  
•  Li:	
  the	
  stabiliza(on	
  algorithm	
  into	
  its	
  own	
  actor	
  
•  Allows	
  us	
  to	
  achieve	
  our	
  three	
  best	
  prac'ces	
  
–  “Actor	
  state	
  should	
  only	
  ever	
  evolve	
  in	
  response	
  to	
  
messages	
  received	
  from	
  the	
  outside”	
  (determinism)	
  
–  “Actor	
  state	
  should	
  only	
  ever	
  be	
  mutated	
  with	
  a	
  call	
  to	
  
context.become”	
  (immutability	
  and	
  referen'al	
  
transparency)	
  
–  “Actor	
  state	
  should	
  not	
  be	
  allowed	
  to	
  leak	
  into	
  
asynchronous	
  closures”	
  (thread-­‐safety)	
  
Timing	
  Logic	
  
•  We	
  can	
  also	
  li:	
  the	
  (ming	
  logic	
  into	
  its	
  own	
  actor	
  
•  Once	
  again,	
  achieves	
  our	
  three	
  best	
  prac'ces	
  
–  In	
  par'cular,	
  ensures	
  that	
  the	
  Node	
  state	
  only	
  evolves	
  in	
  
response	
  to	
  messages	
  from	
  the	
  outside!	
  
Our	
  addi'onal	
  actors	
  
Node	
  1	
  
Node	
  2	
  
Node	
  3	
  
Node	
  4	
  
Node	
  
Stabiliza'on	
  
Algorithm	
  
Interface	
  
Timing	
  
Logic	
  
Applica'on	
  
Division	
  of	
  responsibili'es	
  
•  Node	
  handles	
  requests	
  
•  Node	
  stores	
  network	
  pointers:	
  
–  Successor	
  
–  Predecessor	
  (op'onal)	
  
–  Finger	
  table	
  (see	
  Chord	
  paper)	
  
•  TimingLogic	
  triggers	
  	
  
stabiliza'on	
  
•  Stabiliza'onAlgorithm	
  	
  
runs	
  asynchronous	
  	
  
	
  
Node	
  
Stabiliza'on	
  
Algorithm	
  
Interface	
  
Timing	
  
Logic	
  
Applica'on	
  
Akka	
  paIerns	
  
(Ask	
  and	
  Pipe)	
  
Stabiliza'on	
  constraints	
  
•  Only	
  one	
  stabiliza'on	
  request	
  should	
  be	
  in	
  
progress	
  at	
  any	
  given	
  'me	
  
•  Stabiliza'on	
  should	
  fail	
  if	
  the	
  algorithm	
  
exceeds	
  a	
  given	
  'meout	
  
•  When	
  stabiliza'on	
  finishes,	
  a	
  no'fica'on	
  
should	
  be	
  sent	
  to	
  the	
  TimingLogic	
  actor	
  
– so	
  that	
  it	
  can	
  adjust	
  the	
  frequency	
  of	
  stabiliza'on	
  
requests	
  based	
  on	
  'me-­‐to-­‐complete	
  or	
  failure	
  
rate	
  
Ask	
  paIern	
  
•  Ask	
  paIern	
  (import	
  akka.paIern.ask)	
  
–  Ask	
  (?)	
  instead	
  of	
  tell	
  (!)	
  
–  Returns	
  a	
  Future	
  that	
  will	
  complete	
  with	
  the	
  first	
  response	
  
from	
  the	
  target	
  actor	
  
–  Takes	
  a	
  Timeout	
  value,	
  which	
  specifies	
  how	
  long	
  to	
  wait	
  
un'l	
  the	
  Future	
  should	
  fail	
  
–  This	
  can	
  be	
  nicer	
  than	
  setReceiveTimeout	
  
	
  
•  “Stabiliza:on	
  should	
  fail	
  if	
  the	
  algorithm	
  exceeds	
  a	
  
given	
  :meout”	
  
Ask	
  paIern	
  example	
  
val nodeIdFuture = nodeRef.ask(GetId())(requestTimeout)
.mapTo[GetIdResponse]
.map {
case GetIdOk(nodeId) =>
Some(NodeInfo(nodeId, nodeRef))
}
.recover {
case ex =>
log.error(s“GetId failed: ${ex.getMessage}”)
None
}
•  Asking	
  a	
  node	
  for	
  its	
  ID:	
  
Pipe	
  paIern	
  
•  Pipe	
  paIern	
  (import	
  akka.paIern.pipe)	
  
–  Complements	
  the	
  Ask	
  paIern	
  by	
  allowing	
  the	
  result	
  of	
  a	
  
Future	
  to	
  be	
  piped	
  to	
  an	
  actor	
  
–  Augments	
  Futures	
  with	
  the	
  pipeTo	
  method	
  
•  onSuccess	
  -­‐>	
  sends	
  result	
  to	
  actor	
  
•  onFailure	
  -­‐>	
  sends	
  excep'on	
  to	
  actor,	
  as	
  an	
  
akka.actor.Status.Failure	
  
•  “When	
  stabiliza:on	
  finishes,	
  a	
  no:fica:on	
  
should	
  be	
  sent	
  to	
  the	
  TimingLogic	
  actor”	
  
	
  
Combining	
  Ask	
  and	
  Pipe	
  paIerns	
  
•  Requests	
  that	
  depend	
  on	
  the	
  output	
  of	
  an	
  
asynchronous	
  algorithm	
  will	
  create	
  (or	
  reuse)	
  an	
  
algorithm	
  actor	
  
–  Using	
  the	
  Ask	
  paIern	
  gives	
  us	
  a	
  Future	
  that	
  will	
  expire	
  
auer	
  a	
  fixed	
  amount	
  of	
  'me	
  
–  Transform	
  and	
  ‘pipe’	
  result	
  to	
  client	
  that	
  originally	
  made	
  
the	
  request	
  
–  Allows	
  async	
  request	
  handling	
  to	
  take	
  place	
  outside	
  of	
  the	
  
main	
  thread	
  
Stabiliza'on	
  Using	
  Ask	
  and	
  Pipe	
  
class Node(val initialSuccessor: ActorRef) extends Actor {
def running(nodeRef: ActorRef, algorithm: ActorRef): Receive = {
case Stabilize() =>
algorithm.ask(StabilizationStart(nodeRef))(timeout)
.mapTo[StabilizationStartResponse]
.map {
case StabilizationComplete() => StabilizeOk()
case StabilizationAlreadyRunning => StabilizeInProgress()
case StabilizationFailed(m) => StabilizeFailed(m)
}
.recover { case ex => StabilizeFailed(ex.getMessage) }
.pipeTo(sender())
}
override def receive: Receive = running(
context.actorOf(Props(classOf[Node], initialSuccessor)),
context.actorOf(Props(classOf[StabilizationAlgorithm])))
}
Bonus	
  'p:	
  Use	
  Sealed	
  Traits	
  
•  Model	
  your	
  message	
  types	
  using	
  Sealed	
  Traits	
  
–  Allows	
  the	
  Scala	
  compiler	
  to	
  validate	
  the	
  exhaus'veness	
  of	
  
paIern	
  matching	
  
algorithm.ask(StabilizationStart(nodeRef))(timeout)
.mapTo[StabilizationStartResponse]
.map {
case StabilizationComplete() => StabilizeOk()
case StabilizationAlreadyRunning => StabilizeInProgress()
case StabilizationFailed(m) => StabilizeFailed(m)
}
.recover { case ex => StabilizeFailed(ex.getMessage) }
.pipeTo(sender())
An	
  interes'ng	
  edge	
  case	
  
•  Allowing	
  concurrent	
  stabiliza'on	
  requests	
  could	
  lead	
  to	
  sub-­‐
op'mal	
  network	
  behaviour	
  
–  Maintain	
  one	
  instance	
  of	
  the	
  Stabiliza'onAlgorithm	
  actor	
  
–  While	
  running,	
  it	
  will	
  respond	
  with	
  an	
  AlreadyInProgress	
  message	
  for	
  
any	
  aIempt	
  to	
  restart	
  it	
  
•  When	
  joining	
  a	
  new	
  network,	
  algorithm	
  actors	
  are	
  terminated	
  
and	
  replaced	
  with	
  new	
  actors.	
  However,	
  messages	
  from	
  old	
  
actors	
  may	
  s'll	
  be	
  queued!	
  
•  So	
  once	
  we	
  join	
  a	
  new	
  network,	
  we	
  want	
  need	
  a	
  way	
  to	
  
ignore	
  any	
  queued	
  messages	
  that	
  may	
  alter	
  network	
  pointers	
  
–  Accep'ng	
  these	
  messages	
  could	
  lead	
  to	
  the	
  Node	
  being	
  split	
  across	
  
two	
  networks	
  
Possible	
  solu'on	
  (before	
  Join)	
  
Node	
  
(Request	
  Logic)	
  
Stabiliza'on	
  
Algorithm	
  	
  
Applica'on	
  
Timing	
  
Logic	
  
Pointers	
  
(Data	
  Model)	
  
•  Join	
  request	
  causes	
  Pointers	
  
and	
  Stabiliza'onAlgorithm	
  
actors	
  to	
  be	
  stopped	
  
•  context.stop	
  achieves	
  this	
  
using	
  a	
  message	
  send,	
  so	
  
other	
  messages	
  may	
  be	
  in	
  
their	
  queues	
  
•  New	
  Pointers	
  and	
  
Stabiliza'onAlgorithm	
  
actors	
  are	
  created	
  
•  Old	
  actors	
  are	
  effec'vely	
  
detached	
  and	
  cannot	
  alter	
  
state	
  of	
  Node	
  
Not	
  sure	
  that	
  this	
  is	
  the	
  best	
  	
  
approach…	
  
Possible	
  solu'on	
  (aDer	
  Join)	
  
Stabiliza'on	
  
Algorithm	
  
Pointers	
  
(Data	
  Model)	
  
Graveyard	
  
•  Node	
  becomes	
  a	
  proxy	
  /	
  
controller	
  for	
  Pointers	
  actor	
  
–  Maybe	
  even	
  the	
  ‘Interface’?	
  
–  Pointers	
  actor	
  becomes	
  model	
  
•  Stabiliza'onAlgorithm	
  sends	
  
update	
  messages	
  to	
  
Pointers	
  actor	
  
Node	
  
(Request	
  Logic)	
  
Stabiliza'on	
  
Algorithm	
  	
  
Applica'on	
  
Timing	
  
Logic	
  
Pointers	
  
(Data	
  Model)	
  
Not	
  sure	
  that	
  this	
  is	
  the	
  best	
  	
  
approach…	
  
Scala	
  resources	
  
•  Useful	
  resources	
  for	
  Scala	
  and	
  Akka:	
  
–  Principles	
  of	
  Reac:ve	
  Programming	
  course	
  on	
  Coursera	
  
hIps://www.coursera.org/course/reac've	
  
–  Func'onal	
  Programming	
  in	
  Scala	
  
(book	
  by	
  Chiusano	
  and	
  Runar)	
  
–  Scala	
  Best	
  Prac'ces	
  (includes	
  some	
  Akka	
  best	
  prac'ces)	
  
hIps://github.com/alexandru/scala-­‐best-­‐prac'ces	
  
	
  
Papers	
  
•  “Chord:	
  A	
  Scalable	
  Peer-­‐to-­‐peer	
  Lookup	
  Protocol	
  for	
  Internet	
  	
  
Applica'ons”	
  (IEEE	
  Transac'ons	
  on	
  Networking	
  version)	
  
hIps://pdos.csail.mit.edu/papers/ton:chord/paper-­‐ton.pdf	
  
•  “Consistent	
  Hashing	
  and	
  Random	
  Trees-­‐	
  Distributed	
  Caching	
  
Protocols	
  for	
  Relieving	
  Hot	
  Spots	
  on	
  the	
  World	
  Wide	
  Web”,	
  
hIp://www.ccs.neu.edu/home/cbw/4700/papers/akamai.pdf	
  
Libraries	
  used	
  
•  Backend:	
  
–  spray	
  (library	
  for	
  building	
  Akka-­‐based	
  web	
  services)	
  
hIps://github.com/spray/spray	
  
–  spray-­‐json	
  (JSON	
  de-­‐/serialisa'on,	
  spun	
  off	
  from	
  spray)	
  
hIps://github.com/spray/spray-­‐json	
  
–  spray-­‐websocket	
  (Stream	
  data	
  over	
  HTTP	
  -­‐	
  this	
  used	
  to	
  be	
  really	
  hard!)	
  
hIps://github.com/wandoulabs/spray-­‐websocket	
  
–  scalastyle	
  (detect	
  code	
  smells,	
  formawng	
  errors,	
  etc)	
  
hIp://www.scalastyle.org	
  
•  Frontend:	
  
–  d3.js	
  (bring	
  data	
  to	
  life	
  using	
  HTML,	
  SVG	
  and	
  CSS)	
  
hIps://github.com/mbostock/d3	
  
Thanks	
  for	
  listening	
  
	
  
Time	
  for	
  ques'ons!	
  
Email:	
  
tristan@tristanpenman.com	
  
	
  
Demo	
  code	
  available	
  at	
  
hIps://github.com/tristanpenman/chordial	
  

More Related Content

What's hot

Monitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTapMonitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTap
Padraig O'Sullivan
 
Linux
Linux Linux
Linux Linux Traffic Control
Linux Linux Traffic ControlLinux Linux Traffic Control
Linux Linux Traffic Control
SUSE Labs Taipei
 
Linux Ethernet device driver
Linux Ethernet device driverLinux Ethernet device driver
Linux Ethernet device driver
艾鍗科技
 
RISC-V Boot Process: One Step at a Time
RISC-V Boot Process: One Step at a TimeRISC-V Boot Process: One Step at a Time
RISC-V Boot Process: One Step at a Time
Atish Patra
 
Introduction to DPDK
Introduction to DPDKIntroduction to DPDK
Introduction to DPDK
Kernel TLV
 
Block I/O Layer Tracing: blktrace
Block I/O Layer Tracing: blktraceBlock I/O Layer Tracing: blktrace
Block I/O Layer Tracing: blktrace
Babak Farrokhi
 
Embedded Linux on ARM
Embedded Linux on ARMEmbedded Linux on ARM
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPFLinux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Brendan Gregg
 
Multicore Processors
Multicore ProcessorsMulticore Processors
Multicore Processors
Smruti Sarangi
 
Introduction To Linux Kernel Modules
Introduction To Linux Kernel ModulesIntroduction To Linux Kernel Modules
Introduction To Linux Kernel Modules
dibyajyotig
 
Yoctoで綺麗なkernel configを作る
Yoctoで綺麗なkernel configを作るYoctoで綺麗なkernel configを作る
Yoctoで綺麗なkernel configを作る
shimadah
 
Introduction of eBPF - 時下最夯的Linux Technology
Introduction of eBPF - 時下最夯的Linux Technology Introduction of eBPF - 時下最夯的Linux Technology
Introduction of eBPF - 時下最夯的Linux Technology
Jace Liang
 
Reflexive Access List
Reflexive Access ListReflexive Access List
Reflexive Access List
NetProtocol Xpert
 
[Container Plumbing Days 2023] Why was nerdctl made?
[Container Plumbing Days 2023] Why was nerdctl made?[Container Plumbing Days 2023] Why was nerdctl made?
[Container Plumbing Days 2023] Why was nerdctl made?
Akihiro Suda
 
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
Akihiro Suda
 
Inside Architecture of Neutron
Inside Architecture of NeutronInside Architecture of Neutron
Inside Architecture of Neutron
markmcclain
 
Introduction to CNI (Container Network Interface)
Introduction to CNI (Container Network Interface)Introduction to CNI (Container Network Interface)
Introduction to CNI (Container Network Interface)
HungWei Chiu
 
Linux scheduling and input and output
Linux scheduling and input and outputLinux scheduling and input and output
Linux scheduling and input and output
Sanidhya Chugh
 
Replacing iptables with eBPF in Kubernetes with Cilium
Replacing iptables with eBPF in Kubernetes with CiliumReplacing iptables with eBPF in Kubernetes with Cilium
Replacing iptables with eBPF in Kubernetes with Cilium
Michal Rostecki
 

What's hot (20)

Monitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTapMonitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTap
 
Linux
Linux Linux
Linux
 
Linux Linux Traffic Control
Linux Linux Traffic ControlLinux Linux Traffic Control
Linux Linux Traffic Control
 
Linux Ethernet device driver
Linux Ethernet device driverLinux Ethernet device driver
Linux Ethernet device driver
 
RISC-V Boot Process: One Step at a Time
RISC-V Boot Process: One Step at a TimeRISC-V Boot Process: One Step at a Time
RISC-V Boot Process: One Step at a Time
 
Introduction to DPDK
Introduction to DPDKIntroduction to DPDK
Introduction to DPDK
 
Block I/O Layer Tracing: blktrace
Block I/O Layer Tracing: blktraceBlock I/O Layer Tracing: blktrace
Block I/O Layer Tracing: blktrace
 
Embedded Linux on ARM
Embedded Linux on ARMEmbedded Linux on ARM
Embedded Linux on ARM
 
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPFLinux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPF
 
Multicore Processors
Multicore ProcessorsMulticore Processors
Multicore Processors
 
Introduction To Linux Kernel Modules
Introduction To Linux Kernel ModulesIntroduction To Linux Kernel Modules
Introduction To Linux Kernel Modules
 
Yoctoで綺麗なkernel configを作る
Yoctoで綺麗なkernel configを作るYoctoで綺麗なkernel configを作る
Yoctoで綺麗なkernel configを作る
 
Introduction of eBPF - 時下最夯的Linux Technology
Introduction of eBPF - 時下最夯的Linux Technology Introduction of eBPF - 時下最夯的Linux Technology
Introduction of eBPF - 時下最夯的Linux Technology
 
Reflexive Access List
Reflexive Access ListReflexive Access List
Reflexive Access List
 
[Container Plumbing Days 2023] Why was nerdctl made?
[Container Plumbing Days 2023] Why was nerdctl made?[Container Plumbing Days 2023] Why was nerdctl made?
[Container Plumbing Days 2023] Why was nerdctl made?
 
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
 
Inside Architecture of Neutron
Inside Architecture of NeutronInside Architecture of Neutron
Inside Architecture of Neutron
 
Introduction to CNI (Container Network Interface)
Introduction to CNI (Container Network Interface)Introduction to CNI (Container Network Interface)
Introduction to CNI (Container Network Interface)
 
Linux scheduling and input and output
Linux scheduling and input and outputLinux scheduling and input and output
Linux scheduling and input and output
 
Replacing iptables with eBPF in Kubernetes with Cilium
Replacing iptables with eBPF in Kubernetes with CiliumReplacing iptables with eBPF in Kubernetes with Cilium
Replacing iptables with eBPF in Kubernetes with Cilium
 

Viewers also liked

PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
Tristan Penman
 
Akka: Distributed by Design
Akka: Distributed by DesignAkka: Distributed by Design
Akka: Distributed by Design
patriknw
 
Paul presentation P2P Chord v1
Paul presentation P2P Chord v1Paul presentation P2P Chord v1
Paul presentation P2P Chord v1
Paul Yang
 
Computing on Event-sourced Graphs
Computing on Event-sourced GraphsComputing on Event-sourced Graphs
Computing on Event-sourced Graphs
Graph-TA
 
Data Consistency in Distributed Systems with Akka Distributed Data
Data Consistency in Distributed Systems with Akka Distributed DataData Consistency in Distributed Systems with Akka Distributed Data
Data Consistency in Distributed Systems with Akka Distributed Data
Dmitry Martyanov
 
Chord presentation
Chord presentationChord presentation
Chord presentation
GertThijs
 
Distributed Hash Table and Consistent Hashing
Distributed Hash Table and Consistent HashingDistributed Hash Table and Consistent Hashing
Distributed Hash Table and Consistent Hashing
CloudFundoo
 
Slides - Intro to Akka.Cluster
Slides - Intro to Akka.ClusterSlides - Intro to Akka.Cluster
Slides - Intro to Akka.Cluster
petabridge
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
Vladimir Kostyukov
 
Cassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patternsCassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patterns
Dave Gardner
 
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuriバッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
Kazuki Negoro
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
Konrad Malawski
 
Introduction to Graph Databases
Introduction to Graph DatabasesIntroduction to Graph Databases
Introduction to Graph Databases
Max De Marzi
 
Deep Dive: Amazon DynamoDB
Deep Dive: Amazon DynamoDBDeep Dive: Amazon DynamoDB
Deep Dive: Amazon DynamoDB
Amazon Web Services
 
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
 
Neo4j - 5 cool graph examples
Neo4j - 5 cool graph examplesNeo4j - 5 cool graph examples
Neo4j - 5 cool graph examples
Peter Neubauer
 
Graph database Use Cases
Graph database Use CasesGraph database Use Cases
Graph database Use Cases
Max De Marzi
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
Jonas Bonér
 
Data Modeling with Neo4j
Data Modeling with Neo4jData Modeling with Neo4j
Data Modeling with Neo4j
Neo4j
 

Viewers also liked (19)

PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
PWL Seattle #16 - Chord: A Scalable Peer-to-peer Lookup Protocol for Internet...
 
Akka: Distributed by Design
Akka: Distributed by DesignAkka: Distributed by Design
Akka: Distributed by Design
 
Paul presentation P2P Chord v1
Paul presentation P2P Chord v1Paul presentation P2P Chord v1
Paul presentation P2P Chord v1
 
Computing on Event-sourced Graphs
Computing on Event-sourced GraphsComputing on Event-sourced Graphs
Computing on Event-sourced Graphs
 
Data Consistency in Distributed Systems with Akka Distributed Data
Data Consistency in Distributed Systems with Akka Distributed DataData Consistency in Distributed Systems with Akka Distributed Data
Data Consistency in Distributed Systems with Akka Distributed Data
 
Chord presentation
Chord presentationChord presentation
Chord presentation
 
Distributed Hash Table and Consistent Hashing
Distributed Hash Table and Consistent HashingDistributed Hash Table and Consistent Hashing
Distributed Hash Table and Consistent Hashing
 
Slides - Intro to Akka.Cluster
Slides - Intro to Akka.ClusterSlides - Intro to Akka.Cluster
Slides - Intro to Akka.Cluster
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Cassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patternsCassandra concepts, patterns and anti-patterns
Cassandra concepts, patterns and anti-patterns
 
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuriバッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
バッチを Akka Streams で再実装したら100倍速くなった話 #ScalaMatsuri
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Introduction to Graph Databases
Introduction to Graph DatabasesIntroduction to Graph Databases
Introduction to Graph Databases
 
Deep Dive: Amazon DynamoDB
Deep Dive: Amazon DynamoDBDeep Dive: Amazon DynamoDB
Deep Dive: Amazon DynamoDB
 
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
 
Neo4j - 5 cool graph examples
Neo4j - 5 cool graph examplesNeo4j - 5 cool graph examples
Neo4j - 5 cool graph examples
 
Graph database Use Cases
Graph database Use CasesGraph database Use Cases
Graph database Use Cases
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
 
Data Modeling with Neo4j
Data Modeling with Neo4jData Modeling with Neo4j
Data Modeling with Neo4j
 

Similar to Implementing a Distributed Hash Table with Scala and Akka

Kademlia introduction
Kademlia introductionKademlia introduction
Kademlia introduction
Priyab Satoshi
 
Unit-3-Part-1 [Autosaved].ppt
Unit-3-Part-1 [Autosaved].pptUnit-3-Part-1 [Autosaved].ppt
Unit-3-Part-1 [Autosaved].ppt
Ramya Nellutla
 
Osi model
Osi modelOsi model
Osi model
sayyed sabir
 
Tapestry
TapestryTapestry
Tapestry
Sutha31
 
Computer networks unit iii
Computer networks    unit iiiComputer networks    unit iii
Computer networks unit iii
JAIGANESH SEKAR
 
Connecting devices
Connecting devicesConnecting devices
Connecting devices
Sudhasini Baskaran
 
Network architecure (3).pptx
Network architecure (3).pptxNetwork architecure (3).pptx
Network architecure (3).pptx
Kaythry P
 
6.1-Cassandra.ppt
6.1-Cassandra.ppt6.1-Cassandra.ppt
6.1-Cassandra.ppt
yashsharma863914
 
6.1-Cassandra.ppt
6.1-Cassandra.ppt6.1-Cassandra.ppt
6.1-Cassandra.ppt
DanBarcan2
 
Cassandra
CassandraCassandra
Cassandra
ssuserbad56d
 
Module 3 Part B - computer networks module 2 ppt
Module 3 Part B - computer networks module 2 pptModule 3 Part B - computer networks module 2 ppt
Module 3 Part B - computer networks module 2 ppt
anushaj46
 
Pwani notes-Network Essentials.pp for Internet Protocoltx
Pwani notes-Network Essentials.pp  for Internet ProtocoltxPwani notes-Network Essentials.pp  for Internet Protocoltx
Pwani notes-Network Essentials.pp for Internet Protocoltx
MosesOkumu4
 
Implementation of Spanning Tree Protocol using ns-3
Implementation of Spanning Tree Protocol using ns-3Implementation of Spanning Tree Protocol using ns-3
Implementation of Spanning Tree Protocol using ns-3
Naishil Shah
 
Networking lecture1
Networking lecture1Networking lecture1
Networking lecture1
Vasanti Dutta
 
Network layer (Unit 3) part1.pdf
Network  layer (Unit 3) part1.pdfNetwork  layer (Unit 3) part1.pdf
Network layer (Unit 3) part1.pdf
BharatiPatelPhDStude
 
Peer to peer Paradigms
Peer to peer ParadigmsPeer to peer Paradigms
Peer to peer Paradigms
hassan ahmed
 
Ppt on networking
Ppt on networkingPpt on networking
Ppt on networking
Tanmay Agarawal
 
Andrea Sini Thesis
Andrea Sini ThesisAndrea Sini Thesis
Andrea Sini Thesis
Andrea Sini, MBA
 
CS8603 DS UNIT 5.pptx
CS8603 DS UNIT 5.pptxCS8603 DS UNIT 5.pptx
CS8603 DS UNIT 5.pptx
BShanmugasundariAssi
 
Experimental Analysis Of On Demand Routing Protocol
Experimental Analysis Of On Demand Routing ProtocolExperimental Analysis Of On Demand Routing Protocol
Experimental Analysis Of On Demand Routing Protocol
smita gupta
 

Similar to Implementing a Distributed Hash Table with Scala and Akka (20)

Kademlia introduction
Kademlia introductionKademlia introduction
Kademlia introduction
 
Unit-3-Part-1 [Autosaved].ppt
Unit-3-Part-1 [Autosaved].pptUnit-3-Part-1 [Autosaved].ppt
Unit-3-Part-1 [Autosaved].ppt
 
Osi model
Osi modelOsi model
Osi model
 
Tapestry
TapestryTapestry
Tapestry
 
Computer networks unit iii
Computer networks    unit iiiComputer networks    unit iii
Computer networks unit iii
 
Connecting devices
Connecting devicesConnecting devices
Connecting devices
 
Network architecure (3).pptx
Network architecure (3).pptxNetwork architecure (3).pptx
Network architecure (3).pptx
 
6.1-Cassandra.ppt
6.1-Cassandra.ppt6.1-Cassandra.ppt
6.1-Cassandra.ppt
 
6.1-Cassandra.ppt
6.1-Cassandra.ppt6.1-Cassandra.ppt
6.1-Cassandra.ppt
 
Cassandra
CassandraCassandra
Cassandra
 
Module 3 Part B - computer networks module 2 ppt
Module 3 Part B - computer networks module 2 pptModule 3 Part B - computer networks module 2 ppt
Module 3 Part B - computer networks module 2 ppt
 
Pwani notes-Network Essentials.pp for Internet Protocoltx
Pwani notes-Network Essentials.pp  for Internet ProtocoltxPwani notes-Network Essentials.pp  for Internet Protocoltx
Pwani notes-Network Essentials.pp for Internet Protocoltx
 
Implementation of Spanning Tree Protocol using ns-3
Implementation of Spanning Tree Protocol using ns-3Implementation of Spanning Tree Protocol using ns-3
Implementation of Spanning Tree Protocol using ns-3
 
Networking lecture1
Networking lecture1Networking lecture1
Networking lecture1
 
Network layer (Unit 3) part1.pdf
Network  layer (Unit 3) part1.pdfNetwork  layer (Unit 3) part1.pdf
Network layer (Unit 3) part1.pdf
 
Peer to peer Paradigms
Peer to peer ParadigmsPeer to peer Paradigms
Peer to peer Paradigms
 
Ppt on networking
Ppt on networkingPpt on networking
Ppt on networking
 
Andrea Sini Thesis
Andrea Sini ThesisAndrea Sini Thesis
Andrea Sini Thesis
 
CS8603 DS UNIT 5.pptx
CS8603 DS UNIT 5.pptxCS8603 DS UNIT 5.pptx
CS8603 DS UNIT 5.pptx
 
Experimental Analysis Of On Demand Routing Protocol
Experimental Analysis Of On Demand Routing ProtocolExperimental Analysis Of On Demand Routing Protocol
Experimental Analysis Of On Demand Routing Protocol
 

Recently uploaded

Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
Paul Brebner
 
Building API data products on top of your real-time data infrastructure
Building API data products on top of your real-time data infrastructureBuilding API data products on top of your real-time data infrastructure
Building API data products on top of your real-time data infrastructure
confluent
 
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptxOperational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
sandeepmenon62
 
Cost-Effective Strategies For iOS App Development
Cost-Effective Strategies For iOS App DevelopmentCost-Effective Strategies For iOS App Development
Cost-Effective Strategies For iOS App Development
Softradix Technologies
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
widenerjobeyrl638
 
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdfBaha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
kalichargn70th171
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Peter Caitens
 
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptxMigration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
ervikas4
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
Luigi Fugaro
 
Going AOT: Everything you need to know about GraalVM for Java applications
Going AOT: Everything you need to know about GraalVM for Java applicationsGoing AOT: Everything you need to know about GraalVM for Java applications
Going AOT: Everything you need to know about GraalVM for Java applications
Alina Yurenko
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Paul Brebner
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
Yara Milbes
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
kalichargn70th171
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 

Recently uploaded (20)

Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
bgiolcb
bgiolcbbgiolcb
bgiolcb
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
 
Building API data products on top of your real-time data infrastructure
Building API data products on top of your real-time data infrastructureBuilding API data products on top of your real-time data infrastructure
Building API data products on top of your real-time data infrastructure
 
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptxOperational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
 
Cost-Effective Strategies For iOS App Development
Cost-Effective Strategies For iOS App DevelopmentCost-Effective Strategies For iOS App Development
Cost-Effective Strategies For iOS App Development
 
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
美洲杯赔率投注网【​网址​🎉3977·EE​🎉】
 
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdfBaha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
 
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptxMigration From CH 1.0 to CH 2.0 and  Mule 4.6 & Java 17 Upgrade.pptx
Migration From CH 1.0 to CH 2.0 and Mule 4.6 & Java 17 Upgrade.pptx
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
 
Going AOT: Everything you need to know about GraalVM for Java applications
Going AOT: Everything you need to know about GraalVM for Java applicationsGoing AOT: Everything you need to know about GraalVM for Java applications
Going AOT: Everything you need to know about GraalVM for Java applications
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 

Implementing a Distributed Hash Table with Scala and Akka

  • 1. Implemen'ng  a     Distributed  Hash  Table   with  Scala  and  Akka   Tristan  Penman   @tristanpenman  
  • 2. This  Talk  in  a  nutshell   1.  An  intro  to  DHTs,  the  Chord  protocol  and  its   suppor'ng  algorithms   2.  Demo  applica'on   3.  Modeling  the  Chord  protocol  using  actors  (while   following  Akka  best  prac'ces)   4.  Akka  paIerns  (Ask  and  Pipe)   5.  Closing  remarks  and  useful  resources  
  • 3. But  first…  an  Akka  refresher   •  Framework  for  building  concurrent,   distributed,  and  resilient  message-­‐driven   applica'ons   – Based  on  asynchronous  message  passing   •  Emphasises  actor-­‐based  concurrency   – Model  individual  components  as  ‘Actors’   – Allows  us  to  build  an  applica'on  from  individual   components  that  respond  to  a  set  of  well-­‐ formaIed  messages  
  • 4. An  intro  to  DHTs,  the  Chord   protocol  and  its  suppor'ng   algorithms  
  • 5. Hash  Tables  in  one  slide   •  A  hash  table  is  a  data  structure   used  to  implement  an   associa've  array   •  Lookup  and  inser'on   opera'ons  run  in  constant-­‐'me   •  Each  element  of  the  array  is  a   bucket  that  contains  one  or   more  keys   –  Think  of  a  bucket  as  owning  a  non-­‐ con'guous  subset  of  the  key-­‐ space   Visual  representa'on  of   a  hash  table   Diagram  from:  hIp://math.hws.edu/eck/cs124/javanotes6/c10/s3.html  
  • 6. Distributed  Hash  Tables   •  What  do  you  do  when  you  can’t  store  all  of  your  data  on  one   node?  (Or  don’t  want  to)   –  Spread  the  data  across  mul'ple  nodes,  with  each  node  taking   responsibility  for  a  por'on  of  the  key-­‐space   –  Nodes  ==  buckets   •  First  problem:   –  How  do  we  figure  out  which  node  is  responsible  for  a  key?   •  Second  problem:   –  How  do  we  handle  changes  to  the  network  topology?   –  Nodes  can  join  or  leave  the  network  at  any  'me  
  • 7. The  Chord  Protocol   •  Chord  is  a  protocol  and  set  of   algorithms  for  implemen'ng  a   Distributed  Hash  Table   •  Key  features  are:   –  Lookup  'me  is  logarithmic  in  the   number  of  network  nodes   –  Asynchronous  network  stabiliza'on   protocol   –  Consistent  Hashing  minimizes   disrup'ons  when  nodes  join  or   leave  the  network   Final  paper  (published  in  Transac'ons  on  Networking):  hIps://pdos.csail.mit.edu/papers/ton:chord/paper-­‐ton.pdf  
  • 8. Applica'on  Layer   •  “Does  not  specify  applica'on  layer  behavior”   – Does  not  prescribe  replica'on  techniques   – Same  applies  to  load  balancing  of  requests  coming   into  the  network   – Redistribu'on  of  data  associated  with  keys  when   nodes  leave  or  join  the  network  is  the   responsibility  of  the  applica'on  
  • 9. Visualizing  Chord   •  Instead  of  an  array,  we  have  a   key-­‐space  which  can  be  visualized   as  a  ring   •  A  hash  func'on  is  used  to  map   keys  onto  loca'ons  on  the  ring   •  Nodes  are  also  mapped  to   loca'ons  on  the  ring   –  Typically  determined  by  applying  a   hash  func'on  to  their  IP  address  and   port  number   Empty  circles  represent  dis'nct   loca'ons  on  the  ring.  Blue-­‐filled   circles  indicate  that  nodes  exist   at  those  loca'ons.   Diagram  from:  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html  
  • 10. Consistent  Hashing   •  Chord  assigns  responsibility  for  segments  of  the  ring  to   individual  nodes   –  This  scheme  is  called  Consistent  Hashing   –  Allows  nodes  to  be  added  or  removed  from  the  network  while   minimizing  the  number  of  keys  that  will  need  to  be  reassigned   •  We  can  figure  out  which  node  owns  a  given  key  by  applying   the  hash  func'on,  then  choosing  the  node  whose  loca'on  on   the  ring  is  equal  to  or  greater  than  that  of  the  key   –  This  node  is  the  ‘successor’  of  the  key.  
  • 11. Adding  a  node   Diagram  from:  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html   Node  6  has   been  added  to   the  network  
  • 12. Lookup  and  Insert  Opera'ons   •  Lookup  and  insert  opera'ons  are  based  on  key   ownership   –  When  we  want  to  find  a  key,  we  use  the  hash  func'on   to  find  its  loca'on  on  the  ring   –  Given  the  loca'on  of  a  key  on  the  ring,  Chord  allows   us  to  efficiently  iden'fy  its  successor   –  For  lookups,  we  ask  the  successor  whether  it  knows   about  the  key  that  we’re  interested  in   •  Applica'on-­‐layer  is  responsible  for  further  logic   –  For  insert  opera'ons,  we  tell  the  successor  to  store   the  given  key  
  • 13. Network  Stabiliza'on   •  Each  node  needs  to  maintain   pointers  to  other  nodes   –  Successor(s)   –  Predecessor   –  Finger  table   •  Finger  table  is  a  list  of  nodes  at   increasing  distances  from  the   current  node   –  E.g.  n,  n+1,  n+2,  n+4,  …   –  Allows  for  shortcuts  across   segments  of  the  network,  hence  the   name  Chord   Finger  tables  allow  lookup   opera'ons  to  take  shortcuts  across   the  key-­‐space   Diagram  from:  hIps://en.wikipedia.org/wiki/Chord_(peer-­‐to-­‐peer)  
  • 14. Visualizing  Stabiliza'on   •  Node  3  joins  network,  with  node  10  as  its  ini'al  successor   •  Node  3  begins  stabiliza'on;  asks  node  10  for  its  predecessor   •  Node  10  tells  node  3  that  its  predecessor  is  node  8   •  Node  8  is  closer  to  node  3,  and  becomes  its  new  successor   •  Node  3  no'fies  node  8  of  the  change,  so  node  3  updates  its  predecessor  pointer   Diagram  adapted  from:  hIps://www.cs.rutgers.edu/~pxk/417/notes/23-­‐lookup.html  
  • 15. Chord  algorithms   •  A  Chord  network  can  be  thought  of  as  a  dynamic  distributed   data  structure   •  The  Chord  protocol  defines  eight  algorithms  that  are  used  to   navigate  and  maintain  this  data  structure:   –  CheckPredecessor   –  ClosestPrecedingNode   –  FindPredecessor   –  FindSuccessor   –  FixFingers   –  Join   –  No'fy   –  Stabilize   We’re  going  to  focus     on  Stabiliza(on  
  • 16. A  quick  demo   Code  available  at:   hIps://github.com/tristanpenman/chordial  
  • 17. Modeling  Chord  using  Actors   (while  following  Akka  best  prac'ces)  
  • 18. Actor  Model   •  Computa'ons  defined  in  terms  of  individual   components  that  respond  to  a  set  of  well-­‐formaIed   messages   •  Group  of  actors  is  an  Actor  System   •  Message  Passing  is  asynchronous   •  But  nodes  process  messages  sequen'ally  
  • 19. What  (who)  are  our  actors?   Node  1   Node  2   Node  3   Node  4   •  Nodes  are  an  obvious   star'ng  place…   –  Stores  network  pointers   –  Supports  message  nine   types,  along  with  the   appropriate  response   messages   –  Timing  logic  for   stabiliza'on…   –  This  is  star(ng  to  sound   really  complicated!  
  • 20. Decomposi'on  via  Best  Prac'ces   •  By  iden'fying  some  Best  Prac'ces,  we  can   take  a  more  principled  approach  to   decomposing  our  Actor  System   •  We  want  to  preserve  three  key  proper'es:   – Determinism   – Immutability  and  referen'al  transparency   – Thread-­‐safety  
  • 21. Case  study:  Stabiliza'on   •  Chord  requires  that  a  node  should  periodically   perform  a  stabiliza'on  opera'on   –  Stabiliza'on  ensures  that  the  node’s  successor  is  s'll  the   next  closest  node  on  the  ring   –  If  a  closer  node  is  found,  then  the  successor  pointer   needs  to  be  updated  (involves  a  state  change)   •  Let’s  look  at  how  we  might  implement  periodic   stabiliza'on  using  Scala  and  Akka…   –  Useful  exercise  to  explore  some  Akka  best  prac'ces  
  • 22. Stabiliza'on…  The  Wrong  Way   class Node(val initialSuccessor: ActorRef) extends Actor { var successor: ActorRef = initialSuccessor def doStabilization: Future[ActorRef] = ??? override def receive: Receive = { case Stabilize() => val newSuccessorFuture = doStabilization() newSuccessorFuture.onSuccess { newSuccessor => successor = newSuccessor } } context.system.scheduler.schedule(3000.milliseconds, 3000.milliseconds, self, Stabilize()) }
  • 23. •  Actor  state  should  only  ever  evolve  in  response   to  messages  received  from  the  outside   – Internal  scheduling  makes  an  actor’s  state  non-­‐ determinis'c,  which  is  par'cularly  bad  for  tes'ng   – Scheduling  should  take  place  outside  the  actor   class MyActor extends Actor { var counter = 0 override def receive: Receive = { case IncrementCounter() => counter += 1 } context.system.scheduler.schedule(2.seconds, 3.seconds, self, IncrementCounter()) }
  • 24. class MyActor extends Actor { var counter = 0 override def receive: Receive = { case IncrementCounter() => counter += 1 } } object MyActor { case class IncrementCounter() } class MyApp extends App { val myActor = context.actorOf(Props(classOf[MyActor])) system.scheduler.schedule(2.seconds, 3.seconds, myActor, IncrementCounter()) }
  • 25. •  Actor  state  should  only  ever  be  mutated  with  a   call  to  `context.become`   – Using  vars  (or  vals  for  mutable  objects)  allows   unintended  states  to  be  introduced   – Prefer  immutability  and  referen'al  transparency   class MyActor extends Actor { val isInSet = mutable.Set.empty[String] override def receive: Receive = { case AddToSet(key) => isInSet += key case Contains(key) => sender() ! isInSet(key) } }
  • 26. class MyActor extends Actor { def activeSet(isInSet: Set[String]): Receive = { case Add(key) => context.become(activeSet(isInSet + key)) case Contains(key) => sender() ! isInSet(key) } override def receive: Receive = active(Set.empty) }
  • 27. •  Actor  state  should  not  be  allowed  to  leak  into   asynchronous  closures   – A  Closure  may  be  executed  on  another  thread   – Akka’s  Context  class  is  not  thread-­‐safe,  which   means  no  more  calls  to  ‘context.become’:   class MyActor extends Actor { def withConfig(config: String): Receive = ??? override def receive: Receive = { case Initialise() => val myFuture = loadConfig() myFuture.onSuccess { config => context.become(withConfig(config)) } } }
  • 28. class MyActor extends Actor { def withConfig(config: String): Receive = ??? override def receive: Receive = { case Initialise() => val myFuture = loadConfig() myFuture.onSuccess { config => self ! ConfigLoaded(config) } case ConfigLoaded(config) => context.become(withConfig(config)) } }
  • 29. Stabiliza'on…  Improved   class Node(val initialSuccessor: ActorRef) extends Actor { def doStabilization: Future[ActorRef] = ??? def active(successor: ActorRef): Receive = { case Stabilize() => val newSuccessorFuture = doStabilization() newSuccessorFuture.onSuccess { newSuccessor => self ! Stabilized(newSuccessor) } case Stabilized(newSuccessor) => context.become(active(newSuccessor)) } override def receive: Receive = active(initialSuccessor) }
  • 30. Best  Prac'ces  in  Summary   •  Here  are  the  three  Best  Prac'ces  that  we’ll  come   back  to  while  designing  our  Actor  System:   1.  Actor  state  should  only  ever  evolve  in  response  to   messages  received  from  the  outside   2.  Actor  state  should  only  ever  be  mutated  with  a  call  to   `context.become`   3.  Actor  state  should  not  be  allowed  to  leak  into   asynchronous  closures   Based  on  best  prac'ces  documented  at:  hIps://github.com/alexandru/scala-­‐best-­‐prac'ces  
  • 31. How  can  we  decompose  this  actor?   •  Li:  the  stabiliza(on  algorithm  into  its  own  actor   •  Allows  us  to  achieve  our  three  best  prac'ces   –  “Actor  state  should  only  ever  evolve  in  response  to   messages  received  from  the  outside”  (determinism)   –  “Actor  state  should  only  ever  be  mutated  with  a  call  to   context.become”  (immutability  and  referen'al   transparency)   –  “Actor  state  should  not  be  allowed  to  leak  into   asynchronous  closures”  (thread-­‐safety)  
  • 32. Timing  Logic   •  We  can  also  li:  the  (ming  logic  into  its  own  actor   •  Once  again,  achieves  our  three  best  prac'ces   –  In  par'cular,  ensures  that  the  Node  state  only  evolves  in   response  to  messages  from  the  outside!  
  • 33. Our  addi'onal  actors   Node  1   Node  2   Node  3   Node  4   Node   Stabiliza'on   Algorithm   Interface   Timing   Logic   Applica'on  
  • 34. Division  of  responsibili'es   •  Node  handles  requests   •  Node  stores  network  pointers:   –  Successor   –  Predecessor  (op'onal)   –  Finger  table  (see  Chord  paper)   •  TimingLogic  triggers     stabiliza'on   •  Stabiliza'onAlgorithm     runs  asynchronous       Node   Stabiliza'on   Algorithm   Interface   Timing   Logic   Applica'on  
  • 35. Akka  paIerns   (Ask  and  Pipe)  
  • 36. Stabiliza'on  constraints   •  Only  one  stabiliza'on  request  should  be  in   progress  at  any  given  'me   •  Stabiliza'on  should  fail  if  the  algorithm   exceeds  a  given  'meout   •  When  stabiliza'on  finishes,  a  no'fica'on   should  be  sent  to  the  TimingLogic  actor   – so  that  it  can  adjust  the  frequency  of  stabiliza'on   requests  based  on  'me-­‐to-­‐complete  or  failure   rate  
  • 37. Ask  paIern   •  Ask  paIern  (import  akka.paIern.ask)   –  Ask  (?)  instead  of  tell  (!)   –  Returns  a  Future  that  will  complete  with  the  first  response   from  the  target  actor   –  Takes  a  Timeout  value,  which  specifies  how  long  to  wait   un'l  the  Future  should  fail   –  This  can  be  nicer  than  setReceiveTimeout     •  “Stabiliza:on  should  fail  if  the  algorithm  exceeds  a   given  :meout”  
  • 38. Ask  paIern  example   val nodeIdFuture = nodeRef.ask(GetId())(requestTimeout) .mapTo[GetIdResponse] .map { case GetIdOk(nodeId) => Some(NodeInfo(nodeId, nodeRef)) } .recover { case ex => log.error(s“GetId failed: ${ex.getMessage}”) None } •  Asking  a  node  for  its  ID:  
  • 39. Pipe  paIern   •  Pipe  paIern  (import  akka.paIern.pipe)   –  Complements  the  Ask  paIern  by  allowing  the  result  of  a   Future  to  be  piped  to  an  actor   –  Augments  Futures  with  the  pipeTo  method   •  onSuccess  -­‐>  sends  result  to  actor   •  onFailure  -­‐>  sends  excep'on  to  actor,  as  an   akka.actor.Status.Failure   •  “When  stabiliza:on  finishes,  a  no:fica:on   should  be  sent  to  the  TimingLogic  actor”    
  • 40. Combining  Ask  and  Pipe  paIerns   •  Requests  that  depend  on  the  output  of  an   asynchronous  algorithm  will  create  (or  reuse)  an   algorithm  actor   –  Using  the  Ask  paIern  gives  us  a  Future  that  will  expire   auer  a  fixed  amount  of  'me   –  Transform  and  ‘pipe’  result  to  client  that  originally  made   the  request   –  Allows  async  request  handling  to  take  place  outside  of  the   main  thread  
  • 41. Stabiliza'on  Using  Ask  and  Pipe   class Node(val initialSuccessor: ActorRef) extends Actor { def running(nodeRef: ActorRef, algorithm: ActorRef): Receive = { case Stabilize() => algorithm.ask(StabilizationStart(nodeRef))(timeout) .mapTo[StabilizationStartResponse] .map { case StabilizationComplete() => StabilizeOk() case StabilizationAlreadyRunning => StabilizeInProgress() case StabilizationFailed(m) => StabilizeFailed(m) } .recover { case ex => StabilizeFailed(ex.getMessage) } .pipeTo(sender()) } override def receive: Receive = running( context.actorOf(Props(classOf[Node], initialSuccessor)), context.actorOf(Props(classOf[StabilizationAlgorithm]))) }
  • 42. Bonus  'p:  Use  Sealed  Traits   •  Model  your  message  types  using  Sealed  Traits   –  Allows  the  Scala  compiler  to  validate  the  exhaus'veness  of   paIern  matching   algorithm.ask(StabilizationStart(nodeRef))(timeout) .mapTo[StabilizationStartResponse] .map { case StabilizationComplete() => StabilizeOk() case StabilizationAlreadyRunning => StabilizeInProgress() case StabilizationFailed(m) => StabilizeFailed(m) } .recover { case ex => StabilizeFailed(ex.getMessage) } .pipeTo(sender())
  • 43. An  interes'ng  edge  case   •  Allowing  concurrent  stabiliza'on  requests  could  lead  to  sub-­‐ op'mal  network  behaviour   –  Maintain  one  instance  of  the  Stabiliza'onAlgorithm  actor   –  While  running,  it  will  respond  with  an  AlreadyInProgress  message  for   any  aIempt  to  restart  it   •  When  joining  a  new  network,  algorithm  actors  are  terminated   and  replaced  with  new  actors.  However,  messages  from  old   actors  may  s'll  be  queued!   •  So  once  we  join  a  new  network,  we  want  need  a  way  to   ignore  any  queued  messages  that  may  alter  network  pointers   –  Accep'ng  these  messages  could  lead  to  the  Node  being  split  across   two  networks  
  • 44. Possible  solu'on  (before  Join)   Node   (Request  Logic)   Stabiliza'on   Algorithm     Applica'on   Timing   Logic   Pointers   (Data  Model)   •  Join  request  causes  Pointers   and  Stabiliza'onAlgorithm   actors  to  be  stopped   •  context.stop  achieves  this   using  a  message  send,  so   other  messages  may  be  in   their  queues   •  New  Pointers  and   Stabiliza'onAlgorithm   actors  are  created   •  Old  actors  are  effec'vely   detached  and  cannot  alter   state  of  Node   Not  sure  that  this  is  the  best     approach…  
  • 45. Possible  solu'on  (aDer  Join)   Stabiliza'on   Algorithm   Pointers   (Data  Model)   Graveyard   •  Node  becomes  a  proxy  /   controller  for  Pointers  actor   –  Maybe  even  the  ‘Interface’?   –  Pointers  actor  becomes  model   •  Stabiliza'onAlgorithm  sends   update  messages  to   Pointers  actor   Node   (Request  Logic)   Stabiliza'on   Algorithm     Applica'on   Timing   Logic   Pointers   (Data  Model)   Not  sure  that  this  is  the  best     approach…  
  • 46. Scala  resources   •  Useful  resources  for  Scala  and  Akka:   –  Principles  of  Reac:ve  Programming  course  on  Coursera   hIps://www.coursera.org/course/reac've   –  Func'onal  Programming  in  Scala   (book  by  Chiusano  and  Runar)   –  Scala  Best  Prac'ces  (includes  some  Akka  best  prac'ces)   hIps://github.com/alexandru/scala-­‐best-­‐prac'ces    
  • 47. Papers   •  “Chord:  A  Scalable  Peer-­‐to-­‐peer  Lookup  Protocol  for  Internet     Applica'ons”  (IEEE  Transac'ons  on  Networking  version)   hIps://pdos.csail.mit.edu/papers/ton:chord/paper-­‐ton.pdf   •  “Consistent  Hashing  and  Random  Trees-­‐  Distributed  Caching   Protocols  for  Relieving  Hot  Spots  on  the  World  Wide  Web”,   hIp://www.ccs.neu.edu/home/cbw/4700/papers/akamai.pdf  
  • 48. Libraries  used   •  Backend:   –  spray  (library  for  building  Akka-­‐based  web  services)   hIps://github.com/spray/spray   –  spray-­‐json  (JSON  de-­‐/serialisa'on,  spun  off  from  spray)   hIps://github.com/spray/spray-­‐json   –  spray-­‐websocket  (Stream  data  over  HTTP  -­‐  this  used  to  be  really  hard!)   hIps://github.com/wandoulabs/spray-­‐websocket   –  scalastyle  (detect  code  smells,  formawng  errors,  etc)   hIp://www.scalastyle.org   •  Frontend:   –  d3.js  (bring  data  to  life  using  HTML,  SVG  and  CSS)   hIps://github.com/mbostock/d3  
  • 49. Thanks  for  listening     Time  for  ques'ons!   Email:   tristan@tristanpenman.com     Demo  code  available  at   hIps://github.com/tristanpenman/chordial