Class/Object

akka.cluster.ddata

Replicator

Related Docs: object Replicator | package ddata

Permalink

final class Replicator extends Actor with ActorLogging

A replicated in-memory data store supporting low latency and high availability requirements.

The Replicator actor takes care of direct replication and gossip based dissemination of Conflict Free Replicated Data Types (CRDTs) to replicas in the the cluster. The data types must be convergent CRDTs and implement ReplicatedData, i.e. they provide a monotonic merge function and the state changes always converge.

You can use your own custom ReplicatedData or DeltaReplicatedData types, and several types are provided by this package, such as:

For good introduction to the CRDT subject watch the The Final Causal Frontier and Eventually Consistent Data Structures talk by Sean Cribbs and and the talk by Mark Shapiro and read the excellent paper A comprehensive study of Convergent and Commutative Replicated Data Types by Mark Shapiro et. al.

The Replicator actor must be started on each node in the cluster, or group of nodes tagged with a specific role. It communicates with other Replicator instances with the same path (without address) that are running on other nodes . For convenience it can be used with the DistributedData extension but it can also be started as an ordinary actor using the Replicator.props. If it is started as an ordinary actor it is important that it is given the same name, started on same path, on all nodes.

Delta State Replicated Data Types is supported. delta-CRDT is a way to reduce the need for sending the full state for updates. For example adding element 'c' and 'd' to set {'a', 'b'} would result in sending the delta {'c', 'd'} and merge that with the state on the receiving side, resulting in set {'a', 'b', 'c', 'd'}.

The protocol for replicating the deltas supports causal consistency if the data type is marked with RequiresCausalDeliveryOfDeltas. Otherwise it is only eventually consistent. Without causal consistency it means that if elements 'c' and 'd' are added in two separate Update operations these deltas may occasionally be propagated to nodes in different order than the causal order of the updates. For this example it can result in that set {'a', 'b', 'd'} can be seen before element 'c' is seen. Eventually it will be {'a', 'b', 'c', 'd'}.

Update

To modify and replicate a ReplicatedData value you send a Replicator.Update message to the local Replicator. The current data value for the key of the Update is passed as parameter to the modify function of the Update. The function is supposed to return the new value of the data, which will then be replicated according to the given consistency level.

The modify function is called by the Replicator actor and must therefore be a pure function that only uses the data parameter and stable fields from enclosing scope. It must for example not access sender() reference of an enclosing actor.

Update is intended to only be sent from an actor running in same local ActorSystem as the Replicator, because the modify function is typically not serializable.

You supply a write consistency level which has the following meaning:

As reply of the Update a Replicator.UpdateSuccess is sent to the sender of the Update if the value was successfully replicated according to the supplied consistency level within the supplied timeout. Otherwise a Replicator.UpdateFailure subclass is sent back. Note that a Replicator.UpdateTimeout reply does not mean that the update completely failed or was rolled back. It may still have been replicated to some nodes, and will eventually be replicated to all nodes with the gossip protocol.

You will always see your own writes. For example if you send two Update messages changing the value of the same key, the modify function of the second message will see the change that was performed by the first Update message.

In the Update message you can pass an optional request context, which the Replicator does not care about, but is included in the reply messages. This is a convenient way to pass contextual information (e.g. original sender) without having to use ask or local correlation data structures.

Get

To retrieve the current value of a data you send Replicator.Get message to the Replicator. You supply a consistency level which has the following meaning:

As reply of the Get a Replicator.GetSuccess is sent to the sender of the Get if the value was successfully retrieved according to the supplied consistency level within the supplied timeout. Otherwise a Replicator.GetFailure is sent. If the key does not exist the reply will be Replicator.NotFound.

You will always read your own writes. For example if you send a Update message followed by a Get of the same key the Get will retrieve the change that was performed by the preceding Update message. However, the order of the reply messages are not defined, i.e. in the previous example you may receive the GetSuccess before the UpdateSuccess.

In the Get message you can pass an optional request context in the same way as for the Update message, described above. For example the original sender can be passed and replied to after receiving and transforming GetSuccess.

Subscribe

You may also register interest in change notifications by sending Replicator.Subscribe message to the Replicator. It will send Replicator.Changed messages to the registered subscriber when the data for the subscribed key is updated. Subscribers will be notified periodically with the configured notify-subscribers-interval, and it is also possible to send an explicit Replicator.FlushChanges message to the Replicator to notify the subscribers immediately.

The subscriber is automatically removed if the subscriber is terminated. A subscriber can also be deregistered with the Replicator.Unsubscribe message.

Delete

A data entry can be deleted by sending a Replicator.Delete message to the local local Replicator. As reply of the Delete a Replicator.DeleteSuccess is sent to the sender of the Delete if the value was successfully deleted according to the supplied consistency level within the supplied timeout. Otherwise a Replicator.ReplicationDeleteFailure is sent. Note that ReplicationDeleteFailure does not mean that the delete completely failed or was rolled back. It may still have been replicated to some nodes, and may eventually be replicated to all nodes.

A deleted key cannot be reused again, but it is still recommended to delete unused data entries because that reduces the replication overhead when new nodes join the cluster. Subsequent Delete, Update and Get requests will be replied with Replicator.DataDeleted. Subscribers will receive Replicator.Deleted.

In the Delete message you can pass an optional request context in the same way as for the Update message, described above. For example the original sender can be passed and replied to after receiving and transforming DeleteSuccess.

CRDT Garbage

One thing that can be problematic with CRDTs is that some data types accumulate history (garbage). For example a GCounter keeps track of one counter per node. If a GCounter has been updated from one node it will associate the identifier of that node forever. That can become a problem for long running systems with many cluster nodes being added and removed. To solve this problem the Replicator performs pruning of data associated with nodes that have been removed from the cluster. Data types that need pruning have to implement RemovedNodePruning. The pruning consists of several steps:

Source
Replicator.scala
Linear Supertypes
Type Hierarchy
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Replicator
  2. ActorLogging
  3. Actor
  4. AnyRef
  5. Any
Implicitly
  1. by any2stringadd
  2. by StringFormat
  3. by Ensuring
  4. by ArrowAssoc
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Instance Constructors

  1. new Replicator(settings: ReplicatorSettings)

    Permalink

Type Members

  1. type Receive = PartialFunction[Any, Unit]

    Permalink
    Definition Classes
    Actor

Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. def +(other: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to any2stringadd[Replicator] performed by method any2stringadd in scala.Predef.
    Definition Classes
    any2stringadd
  4. def ->[B](y: B): (Replicator, B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to ArrowAssoc[Replicator] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc
    Annotations
    @inline()
  5. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  6. var allReachableClockTime: Long

    Permalink
  7. def aroundPostRestart(reason: Throwable): Unit

    Permalink
    Attributes
    protected[akka]
    Definition Classes
    Actor
    Annotations
    @InternalApi()
  8. def aroundPostStop(): Unit

    Permalink
    Attributes
    protected[akka]
    Definition Classes
    Actor
    Annotations
    @InternalApi()
  9. def aroundPreRestart(reason: Throwable, message: Option[Any]): Unit

    Permalink
    Attributes
    protected[akka]
    Definition Classes
    Actor
    Annotations
    @InternalApi()
  10. def aroundPreStart(): Unit

    Permalink
    Attributes
    protected[akka]
    Definition Classes
    Actor
    Annotations
    @InternalApi()
  11. def aroundReceive(rcv: actor.Actor.Receive, msg: Any): Unit

    Permalink
    Attributes
    protected[akka]
    Definition Classes
    Replicator → Actor
  12. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  13. var changed: Set[KeyId]

    Permalink
  14. val clockTask: Cancellable

    Permalink
  15. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  16. val cluster: Cluster

    Permalink
  17. def collectRemovedNodes(): Unit

    Permalink
  18. implicit val context: ActorContext

    Permalink
    Definition Classes
    Actor
  19. var dataEntries: Map[KeyId, (DataEnvelope, Digest)]

    Permalink
  20. def deleteObsoletePruningPerformed(): Unit

    Permalink
  21. val deltaPropagationSelector: DeltaPropagationSelector { val gossipIntervalDivisor: Int }

    Permalink
  22. val deltaPropagationTask: Option[Cancellable]

    Permalink
  23. def digest(envelope: DataEnvelope): Digest

    Permalink
  24. val durable: Set[KeyId]

    Permalink
  25. val durableStore: ActorRef

    Permalink
  26. val durableWildcards: Set[String]

    Permalink
  27. def ensuring(cond: (Replicator) ⇒ Boolean, msg: ⇒ Any): Replicator

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to Ensuring[Replicator] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  28. def ensuring(cond: (Replicator) ⇒ Boolean): Replicator

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to Ensuring[Replicator] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  29. def ensuring(cond: Boolean, msg: ⇒ Any): Replicator

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to Ensuring[Replicator] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  30. def ensuring(cond: Boolean): Replicator

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to Ensuring[Replicator] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  31. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  32. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  33. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  34. def formatted(fmtstr: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to StringFormat[Replicator] performed by method StringFormat in scala.Predef.
    Definition Classes
    StringFormat
    Annotations
    @inline()
  35. var fullStateGossipEnabled: Boolean

    Permalink
  36. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  37. def getData(key: KeyId): Option[DataEnvelope]

    Permalink
  38. def getDeltaSeqNr(key: KeyId, fromNode: UniqueAddress): Long

    Permalink
  39. def getDigest(key: KeyId): Digest

    Permalink
  40. val gossipTask: Cancellable

    Permalink
  41. def gossipTo(address: Address): Unit

    Permalink
  42. val hasDurableKeys: Boolean

    Permalink
  43. def hasSubscriber(subscriber: ActorRef): Boolean

    Permalink
  44. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  45. def initRemovedNodePruning(): Unit

    Permalink
  46. def isDurable(key: KeyId): Boolean

    Permalink
  47. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  48. def isLeader: Boolean

    Permalink
  49. def isLocalGet(readConsistency: ReadConsistency): Boolean

    Permalink
  50. def isLocalSender(): Boolean

    Permalink
  51. def isLocalUpdate(writeConsistency: WriteConsistency): Boolean

    Permalink
  52. def isNodeRemoved(node: UniqueAddress, keys: Iterable[KeyId]): Boolean

    Permalink
  53. var leader: TreeSet[Member]

    Permalink
  54. val load: Receive

    Permalink
  55. def log: LoggingAdapter

    Permalink
    Definition Classes
    ActorLogging
  56. def matchingRole(m: Member): Boolean

    Permalink
  57. val maxPruningDisseminationNanos: Long

    Permalink
  58. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  59. val newSubscribers: HashMap[KeyId, Set[ActorRef]] with MultiMap[KeyId, ActorRef]

    Permalink
  60. var nodes: Set[Address]

    Permalink
  61. val normalReceive: Receive

    Permalink
  62. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  63. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  64. val notifyTask: Cancellable

    Permalink
  65. def performRemovedNodePruning(): Unit

    Permalink
  66. def postRestart(reason: Throwable): Unit

    Permalink
    Definition Classes
    Actor
    Annotations
    @throws( classOf[java.lang.Exception] )
  67. def postStop(): Unit

    Permalink
    Definition Classes
    Replicator → Actor
  68. def preRestart(reason: Throwable, message: Option[Any]): Unit

    Permalink
    Definition Classes
    Actor
    Annotations
    @throws( classOf[java.lang.Exception] )
  69. def preStart(): Unit

    Permalink
    Definition Classes
    Replicator → Actor
  70. var previousClockTime: Long

    Permalink
  71. val pruningTask: Option[Cancellable]

    Permalink
  72. def receive: actor.Actor.Receive

    Permalink
    Definition Classes
    Replicator → Actor
  73. def receiveClockTick(): Unit

    Permalink
  74. def receiveDelete(key: KeyR, consistency: WriteConsistency, req: Option[Any]): Unit

    Permalink
  75. def receiveDeltaPropagation(fromNode: UniqueAddress, reply: Boolean, deltas: Map[KeyId, Delta]): Unit

    Permalink
  76. def receiveDeltaPropagationTick(): Unit

    Permalink
  77. def receiveFlushChanges(): Unit

    Permalink
  78. def receiveGet(key: KeyR, consistency: ReadConsistency, req: Option[Any]): Unit

    Permalink
  79. def receiveGetKeyIds(): Unit

    Permalink
  80. def receiveGetReplicaCount(): Unit

    Permalink
  81. def receiveGossip(updatedData: Map[KeyId, DataEnvelope], sendBack: Boolean): Unit

    Permalink
  82. def receiveGossipTick(): Unit

    Permalink
  83. def receiveMemberRemoved(m: Member): Unit

    Permalink
  84. def receiveMemberUp(m: Member): Unit

    Permalink
  85. def receiveOtherMemberEvent(m: Member): Unit

    Permalink
  86. def receiveReachable(m: Member): Unit

    Permalink
  87. def receiveRead(key: KeyId): Unit

    Permalink
  88. def receiveReadRepair(key: KeyId, writeEnvelope: DataEnvelope): Unit

    Permalink
  89. def receiveRemovedNodePruningTick(): Unit

    Permalink
  90. def receiveStatus(otherDigests: Map[KeyId, Digest], chunk: Int, totChunks: Int): Unit

    Permalink
  91. def receiveSubscribe(key: KeyR, subscriber: ActorRef): Unit

    Permalink
  92. def receiveTerminated(ref: ActorRef): Unit

    Permalink
  93. def receiveUnreachable(m: Member): Unit

    Permalink
  94. def receiveUnsubscribe(key: KeyR, subscriber: ActorRef): Unit

    Permalink
  95. def receiveUpdate(key: KeyR, modify: (Option[ReplicatedData]) ⇒ ReplicatedData, writeConsistency: WriteConsistency, req: Option[Any]): Unit

    Permalink
  96. def receiveWeaklyUpMemberUp(m: Member): Unit

    Permalink
  97. def receiveWrite(key: KeyId, envelope: DataEnvelope): Unit

    Permalink
  98. var removedNodes: Map[UniqueAddress, Long]

    Permalink
  99. def replica(address: Address): ActorSelection

    Permalink
  100. var replyTo: ActorRef

    Permalink
  101. def selectRandomNode(addresses: IndexedSeq[Address]): Option[Address]

    Permalink
  102. implicit final val self: ActorRef

    Permalink
    Definition Classes
    Actor
  103. val selfAddress: Address

    Permalink
  104. val selfUniqueAddress: UniqueAddress

    Permalink
  105. final def sender(): ActorRef

    Permalink
    Definition Classes
    Actor
  106. val serializer: Serializer

    Permalink
  107. def setData(key: KeyId, envelope: DataEnvelope): DataEnvelope

    Permalink
  108. var statusCount: Long

    Permalink
  109. var statusTotChunks: Int

    Permalink
  110. val subscribers: HashMap[KeyId, Set[ActorRef]] with MultiMap[KeyId, ActorRef]

    Permalink
  111. var subscriptionKeys: Map[KeyId, KeyR]

    Permalink
  112. val supervisorStrategy: OneForOneStrategy

    Permalink
    Definition Classes
    Replicator → Actor
  113. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  114. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  115. def unhandled(message: Any): Unit

    Permalink
    Definition Classes
    Actor
  116. var unreachable: Set[Address]

    Permalink
  117. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  118. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  119. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  120. var weaklyUpNodes: Set[Address]

    Permalink
  121. def write(key: KeyId, writeEnvelope: DataEnvelope): Option[DataEnvelope]

    Permalink
  122. def writeAndStore(key: KeyId, writeEnvelope: DataEnvelope, reply: Boolean): Unit

    Permalink
  123. def [B](y: B): (Replicator, B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Replicator to ArrowAssoc[Replicator] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc

Inherited from ActorLogging

Inherited from Actor

Inherited from AnyRef

Inherited from Any

Inherited by implicit conversion any2stringadd from Replicator to any2stringadd[Replicator]

Inherited by implicit conversion StringFormat from Replicator to StringFormat[Replicator]

Inherited by implicit conversion Ensuring from Replicator to Ensuring[Replicator]

Inherited by implicit conversion ArrowAssoc from Replicator to ArrowAssoc[Replicator]

Ungrouped