[erlang-questions] Does erlang:now() guarantee that subsequent calls to this BIF returns continuously increasing values even in erlang cluster?

Fred Hebert <>
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