7

ドキュメントによると

make_ref() -> ref()  

ほぼ一意の参照を返します。

返された参照は、約282回の呼び出し後に再び発生します。したがって、それは実用的な目的のために十分にユニークです。

しかし、私の目は、VMの再起動の間に同じ参照を簡単に取得できることを教えてくれます。

[~] 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>

では、ErlangのRefはどれほどユニークですか?タグがmqまたはdbで永続的であり、さまざまなVMセッションによって生成される可能性がある場合に、一意の「タグ」ジェネレーターとして使用するのに適していますか。

これにはUUIDを使用できることを知っています。pids()は繰り返し可能で再利用可能であり、シリアル化して永続ストレージからロードした場合、決して一意ではないこともよく知られています。

問題は、refs()とは何ですか?UUIDのようなものですか、それともpids()のようなものですか?refs()はノード間で一意ですか?再起動の合間に?このトピックに関する公式情報はありますか?

4

2 に答える 2

6

ノードの名前に関連する参照は、ランダム性を意味するのではなく、一意性を意味します。すでにお気づきのように、それらは循環的な方法で作成されます。また、参照はノードの存続期間に対してのみ一意であるという事実についても正しいです。VMを再起動すると、参照を繰り返すことができます。

PIDの場合と同様に、印刷された参照#Ref<W.X.Y.Z>には、最初の要素(W)としてノード番号に関する情報が含まれます。

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)
(right@mars)1> register(right, self()).
true
(right@mars)2> receive M -> M end.
#Ref<6793.0.0.41>
(right@mars)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)
(left@mars)1> {right, 'right@mars'} ! make_ref().
#Ref<0.0.0.41>
(left@mars)2> 

この場合、W参照用が0ローカルノード、6793リモートノードにあることに注意してください。

于 2012-04-05T14:20:07.373 に答える
5

分散システムでは、一意の識別子を生成できるようにするには、永続ストレージを備えた中央のアトミックIDジェネレーターに依存するか、任意の時点でクラスターが適切に構成されていることを確認する必要があります。2番目のケースの例を次に示します。

分散Erlangクラスター{node(), now()}では一意と見なすことができます。クロックが適切に構成されていることを確認でき、同じ名前の2つのノードを開始しない場合は、を使用してみてください{node(), now(), make_ref()}。これにより、衝突の可能性が無視できるようになります。

于 2012-04-05T14:20:30.307 に答える