2012-04-05 9 views
7

Dokumentation sagt, dassSind Erlang-Referenzen zwischen Knoten/VM-Neustarts eindeutig?

make_ref() -> ref() 

eine nahezu eindeutige Referenz zurück.

Die zurückgegebene Referenz wird nach etwa 2 Aufrufen wieder auftreten; daher ist es einzigartig genug für praktische Zwecke.

Aber meine Augen sagen mir, dass zwischen VM neu gestartet ich leicht die gleiche ref bekommen konnte:

[~] erl 
Erlang R14B04 (erts-5.8.5) 
1> make_ref(). 
#Ref<0.0.0.33> 
2> make_ref(). 
#Ref<0.0.0.37> 
^C 

[~] erl 
Erlang R14B04 (erts-5.8.5) 
1> make_ref(). 
#Ref<0.0.0.33> 

So, wie einzigartig Erlang Refs sind? Sind sie geeignet, um als eindeutiger "Tag" -Generator verwendet zu werden, wenn Tags in mq oder db persistent sind und von verschiedenen VM-Sitzungen generiert werden können.

Ich weiß, dass UUIDs dafür verwendet werden könnten. Es ist auch bekannt, dass pids() wiederholbar, wiederverwendbar und keineswegs eindeutig ist, wenn sie serialisiert und dann aus dem persistenten Speicher geladen werden.

Frage ist, was sind refs() - eher wie UUIDs oder mehr wie pids()? Sind refs() eindeutig zwischen Knoten? Zwischen Neustarts? Gibt es offizielle Informationen zu diesem Thema?

Antwort

7

Referenzen, die sich auf den Namen eines Knotens beziehen, implizieren nicht Zufälligkeit, nur Eindeutigkeit. Wie Sie bereits bemerkt haben, werden sie zyklisch erstellt. Sie sind auch auf der Tatsache, dass Referenzen nur für die Lebensdauer eines Knotens einzigartig sind. Sobald Sie die VM neu starten, können Referenzen wiederholt werden.

Wie im Fall von PIDs, Referenzen gedruckt #Ref<W.X.Y.Z> enthalten - als ihr erstes Element (W) - Informationen über die Knotennummer:

erl -sname right 
Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false] 

Eshell V5.9 (abort with ^G) 
([email protected])1> register(right, self()). 
true 
([email protected])2> receive M -> M end. 
#Ref<6793.0.0.41> 
([email protected])3> 

erl -sname left 
Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false] 

Eshell V5.9 (abort with ^G) 
([email protected])1> {right, '[email protected]'} ! make_ref(). 
#Ref<0.0.0.41> 
([email protected])2> 

Beachten Sie, wie in diesem Fall die W für die Referenz ist 0 in der lokale Knoten, 6793 in der entfernten.

5

Um in einem verteilten System einen eindeutigen Bezeichner generieren zu können, müssen Sie sich entweder auf einen zentralen Atom-ID-Generator mit persistentem Speicher verlassen oder eine ordnungsgemäße Konfiguration des Clusters zu jedem beliebigen Zeitpunkt sicherstellen. Ein Beispiel für den zweiten Fall folgt.

In einem verteilten Erlang-Cluster {node(), now()} kann als einzigartig angesehen werden. Wenn Sie sicherstellen können, dass Ihre Uhr einigermaßen konfiguriert ist und Sie nicht zwei Knoten mit demselben Namen starten, können Sie versuchen, {node(), now(), make_ref()} zu verwenden, was die Möglichkeit einer Kollision vernachlässigbar machen würde.

Verwandte Themen