clock clarification for LWWRegister, #18434
* it's safe to use from Cluster Singleton
This commit is contained in:
parent
6fea2f3526
commit
8ac24dfcfe
4 changed files with 36 additions and 14 deletions
|
|
@ -31,6 +31,13 @@ object LWWMap {
|
||||||
* use a timestamp value based on something else, for example an increasing version number
|
* use a timestamp value based on something else, for example an increasing version number
|
||||||
* from a database record that is used for optimistic concurrency control.
|
* from a database record that is used for optimistic concurrency control.
|
||||||
*
|
*
|
||||||
|
* The `defaultClock` is using max value of `System.currentTimeMillis()` and `currentTimestamp + 1`.
|
||||||
|
* This means that the timestamp is increased for changes on the same node that occurs within
|
||||||
|
* the same millisecond. It also means that it is safe to use the `LWWMap` without
|
||||||
|
* synchronized clocks when there is only one active writer, e.g. a Cluster Singleton. Such a
|
||||||
|
* single writer should then first read current value with `ReadMajority` (or more) before
|
||||||
|
* changing and writing the value with `WriteMajority` (or more).
|
||||||
|
*
|
||||||
* For first-write-wins semantics you can use the [[LWWRegister#reverseClock]] instead of the
|
* For first-write-wins semantics you can use the [[LWWRegister#reverseClock]] instead of the
|
||||||
* [[LWWRegister#defaultClock]]
|
* [[LWWRegister#defaultClock]]
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,13 @@ object LWWRegister {
|
||||||
* use a timestamp value based on something else, for example an increasing version number
|
* use a timestamp value based on something else, for example an increasing version number
|
||||||
* from a database record that is used for optimistic concurrency control.
|
* from a database record that is used for optimistic concurrency control.
|
||||||
*
|
*
|
||||||
|
* The `defaultClock` is using max value of `System.currentTimeMillis()` and `currentTimestamp + 1`.
|
||||||
|
* This means that the timestamp is increased for changes on the same node that occurs within
|
||||||
|
* the same millisecond. It also means that it is safe to use the `LWWRegister` without
|
||||||
|
* synchronized clocks when there is only one active writer, e.g. a Cluster Singleton. Such a
|
||||||
|
* single writer should then first read current value with `ReadMajority` (or more) before
|
||||||
|
* changing and writing the value with `WriteMajority` (or more).
|
||||||
|
*
|
||||||
* For first-write-wins semantics you can use the [[LWWRegister#reverseClock]] instead of the
|
* For first-write-wins semantics you can use the [[LWWRegister#reverseClock]] instead of the
|
||||||
* [[LWWRegister#defaultClock]]
|
* [[LWWRegister#defaultClock]]
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -337,13 +337,6 @@ values.
|
||||||
|
|
||||||
.. includecode:: code/docs/ddata/DistributedDataDocTest.java#ormultimap
|
.. includecode:: code/docs/ddata/DistributedDataDocTest.java#ormultimap
|
||||||
|
|
||||||
Note that ``LWWRegister`` and therefore ``LWWMap`` relies on synchronized clocks and should only be used
|
|
||||||
when the choice of value is not important for concurrent updates occurring within the clock skew.
|
|
||||||
|
|
||||||
Instead of using timestamps based on ``System.currentTimeMillis()`` time it is possible to
|
|
||||||
use a timestamp value based on something else, for example an increasing version number
|
|
||||||
from a database record that is used for optimistic concurrency control.
|
|
||||||
|
|
||||||
When a data entry is changed the full state of that entry is replicated to other nodes, i.e.
|
When a data entry is changed the full state of that entry is replicated to other nodes, i.e.
|
||||||
when you update a map the whole map is replicated. Therefore, instead of using one ``ORMap``
|
when you update a map the whole map is replicated. Therefore, instead of using one ``ORMap``
|
||||||
with 1000 elements it is more efficient to split that up in 10 top level ``ORMap`` entries
|
with 1000 elements it is more efficient to split that up in 10 top level ``ORMap`` entries
|
||||||
|
|
@ -352,6 +345,10 @@ trade-off that different entries may not be replicated at the same time and you
|
||||||
inconsistencies between related entries. Separate top level entries cannot be updated atomically
|
inconsistencies between related entries. Separate top level entries cannot be updated atomically
|
||||||
together.
|
together.
|
||||||
|
|
||||||
|
Note that ``LWWRegister`` and therefore ``LWWMap`` relies on synchronized clocks and should only be used
|
||||||
|
when the choice of value is not important for concurrent updates occurring within the clock skew. Read more
|
||||||
|
in the below section about ``LWWRegister``.
|
||||||
|
|
||||||
Flags and Registers
|
Flags and Registers
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
@ -380,6 +377,13 @@ from a database record that is used for optimistic concurrency control.
|
||||||
For first-write-wins semantics you can use the ``LWWRegister#reverseClock`` instead of the
|
For first-write-wins semantics you can use the ``LWWRegister#reverseClock`` instead of the
|
||||||
``LWWRegister#defaultClock``.
|
``LWWRegister#defaultClock``.
|
||||||
|
|
||||||
|
The ``defaultClock`` is using max value of ``System.currentTimeMillis()`` and ``currentTimestamp + 1``.
|
||||||
|
This means that the timestamp is increased for changes on the same node that occurs within
|
||||||
|
the same millisecond. It also means that it is safe to use the ``LWWRegister`` without
|
||||||
|
synchronized clocks when there is only one active writer, e.g. a Cluster Singleton. Such a
|
||||||
|
single writer should then first read current value with ``ReadMajority`` (or more) before
|
||||||
|
changing and writing the value with ``WriteMajority`` (or more).
|
||||||
|
|
||||||
Custom Data Type
|
Custom Data Type
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -337,13 +337,6 @@ values.
|
||||||
|
|
||||||
.. includecode:: code/docs/ddata/DistributedDataDocSpec.scala#ormultimap
|
.. includecode:: code/docs/ddata/DistributedDataDocSpec.scala#ormultimap
|
||||||
|
|
||||||
Note that ``LWWRegister`` and therefore ``LWWMap`` relies on synchronized clocks and should only be used
|
|
||||||
when the choice of value is not important for concurrent updates occurring within the clock skew.
|
|
||||||
|
|
||||||
Instead of using timestamps based on ``System.currentTimeMillis()`` time it is possible to
|
|
||||||
use a timestamp value based on something else, for example an increasing version number
|
|
||||||
from a database record that is used for optimistic concurrency control.
|
|
||||||
|
|
||||||
When a data entry is changed the full state of that entry is replicated to other nodes, i.e.
|
When a data entry is changed the full state of that entry is replicated to other nodes, i.e.
|
||||||
when you update a map the whole map is replicated. Therefore, instead of using one ``ORMap``
|
when you update a map the whole map is replicated. Therefore, instead of using one ``ORMap``
|
||||||
with 1000 elements it is more efficient to split that up in 10 top level ``ORMap`` entries
|
with 1000 elements it is more efficient to split that up in 10 top level ``ORMap`` entries
|
||||||
|
|
@ -352,6 +345,10 @@ trade-off that different entries may not be replicated at the same time and you
|
||||||
inconsistencies between related entries. Separate top level entries cannot be updated atomically
|
inconsistencies between related entries. Separate top level entries cannot be updated atomically
|
||||||
together.
|
together.
|
||||||
|
|
||||||
|
Note that ``LWWRegister`` and therefore ``LWWMap`` relies on synchronized clocks and should only be used
|
||||||
|
when the choice of value is not important for concurrent updates occurring within the clock skew. Read more
|
||||||
|
in the below section about ``LWWRegister``.
|
||||||
|
|
||||||
Flags and Registers
|
Flags and Registers
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
@ -380,6 +377,13 @@ from a database record that is used for optimistic concurrency control.
|
||||||
For first-write-wins semantics you can use the ``LWWRegister#reverseClock`` instead of the
|
For first-write-wins semantics you can use the ``LWWRegister#reverseClock`` instead of the
|
||||||
``LWWRegister#defaultClock``.
|
``LWWRegister#defaultClock``.
|
||||||
|
|
||||||
|
The ``defaultClock`` is using max value of ``System.currentTimeMillis()`` and ``currentTimestamp + 1``.
|
||||||
|
This means that the timestamp is increased for changes on the same node that occurs within
|
||||||
|
the same millisecond. It also means that it is safe to use the ``LWWRegister`` without
|
||||||
|
synchronized clocks when there is only one active writer, e.g. a Cluster Singleton. Such a
|
||||||
|
single writer should then first read current value with ``ReadMajority`` (or more) before
|
||||||
|
changing and writing the value with ``WriteMajority`` (or more).
|
||||||
|
|
||||||
Custom Data Type
|
Custom Data Type
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue