2012-04-05 36 views
7

文檔中說,Erlang在節點/ VM重啓之間是否唯一?

make_ref() -> ref() 

返回一個幾乎唯一的參考。

返回的引用將在約2 調用後重新發生;因此它在實踐中足夠獨特。

但我的眼睛告訴我,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的參考文獻是?如果標籤在mq或db中持久存在並且可能由不同的VM會話生成,它們是否適合用作獨特的「標籤」生成器?

我知道UUID可以用於此。衆所周知,pids()是可重複使用的,可重用的,如果序列化,然後從持久存儲中加載,則絕不是唯一的。

問題是,什麼是refs() - 更像UUID或更像pids()? refs()在節點之間是唯一的嗎?重新啓動之間?有關於此主題的任何官方信息?

回答

7

與節點名稱相關的引用不意味着隨機性,而只是唯一性。正如你已經注意到的,它們是以循環方式創建的。 另外,您對事實的引用僅在節點的生命週期中才是唯一的。一旦你重新啓動虛擬機,可以重複引用。

作爲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) 
([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> 

注意如何在這種情況下,W用於參考是0在本地節點6793位於遠程節點。

5

在任何分佈式系統中,爲了能夠生成唯一標識符,您必須依賴具有永久存儲的中央原子ID生成器,或者確保在任何時間點正確配置羣集。第二種情況的例子如下。

在分佈式Erlang集羣{node(), now()}可以被認爲是唯一的。如果您可以確保您的時鐘配置合理,並且不會啓動具有相同名稱的兩個節點,則可以嘗試使用{node(), now(), make_ref()},這可能會使得碰撞可能性可以忽略不計。