[erlang-questions] Does erlang:now() guarantee that subsequent calls to this BIF returns continuously increasing values even in erlang cluster?
Fred Hebert
mononcqc@REDACTED
Mon Apr 20 14:54:20 CEST 2015
On 04/20, Daniel wrote:
>I am looking for a global sequence generator in erlang cluster.
>
>I think erlang:now() is promising, because it is fast enough and “also guarantees that subsequent calls to this BIF returns continuously increasing values”. But I am not quite sure whether this guarantee also works for erlang cluster which have several nodes running on different servers?
>
>I have read Time and time correction in Erlang
>(http://www.erlang.org/doc/apps/erts/time_correction.html), but still
>have no conclusion.
>
There is a very important thing. You did mention *in a cluster*. What
you are asking for, a "global sequence" requires putting every call you
have into a well-known order where any value can be compared to any
value and sorted properly. This is known as a "total order", and
requires synchronization.
This means that doing this requires your nodes to discuss together, and
in concert either:
a) elect a leader to create the sequence values
b) come to an agreement for the sequence of values
These are very broad lines (the theoretical aspect of it gets mixed in
with a lot of fancy consistency model in distributed systems talk).
You will want this [generally costly] mechanism when:
- You need an absolute order in the sequence of your events
- You are ready to see potential unavailability when all the nodes in
the system cannot agree on how to allocate the numbers.
There is no way around it. On the other hand, there are some alternative
options: you could decide to have only *some* events ordered. This means
that for some values you could definitely say which comes before or
after the other, but not for all of them. This is called a 'partial
order'.
It's what would happen if I generated logs on two different nodes and
kept the node identifier in the log. When that happens, I know that logs
from A are in the right order (I trust their timestamp), but I cannot
know if node A's 2015/04/20T12:59:23+00:00 comes before node B's
2015/04/20T12:59:23+00:00: their respective clocks might be off,
drifting, or their resolution too low for me to decide.
So therefore, when sorting logs for these two systems, I can decide
whether one came before or after the others from the same node (as long
as I used a monotonic clock like erlang:now() to generate the values),
but cannot reliably sort logs across nodes.
The best answer I can personally give you here is not to tell you how to
properly generate these numbers, but rather to ask right back about what
it is you're trying to accomplish, and why do you believe you need these
numbers for?
If there's a way to get away without the continuously increasing values
at a global level, this will be much simpler operationally than trying
to maintain healthy clusters that synchronize and block on every ID you
want to generate.
More information about the erlang-questions
mailing list