618來臨之際,為了應對一些突發流量,購買了兩台乙個月的ecs用來臨時對部分專案擴容。其中乙個專案有用到雪花演算法來生成id,這個還是挺ok的。
不過發現要在配置檔案中手動配置機器碼!!配置的時候還要先知道目前配置了那些,這樣才可以避免重複。
經過了解,除了會有單機單例項的情況,還會有單機多例項的情況。
這個要人工配置,是徒增工作量的,有點讓人難以接受。
針對這個,老黃就做了一點調整,讓這個機器碼自動生成。
關於雪花演算法,大部分文章都可以看到這個圖。這個圖很好的詮釋了雪花演算法生成id的幾個重要組成部分,這裡也不展開具體介紹了。
時間戳,工作機器id,序列號這些位數是可以根據自己的業務場景來進來調整的。
10bit工作機器id,其實就是上面說到的機器碼,雪花演算法內部並沒有做任何處理,而是交由業務方自己定義,所以業務方需要自己保證這個的唯一性。
大部分情況,會把它分為5bit資料中心標識和5bit機器id。這樣的話可以支援32個資料中心和32個機器id。
換句話說就是,乙個業務可以在乙個資料中心部署32個例項,最多部署的32個資料中心。正常來說,大部分專案,都不會需要部署這麼多例項。。。
考慮到內網的ip段基本上是固定的,同乙個應用基本上也會在連續的ip上面部署。
所以這裡老黃最後採用的是本地ip位址取餘做為機器id,機器的hostname取餘做為預設的資料中心id。
下面來看看具體的實現。
自動獲取機器id和資料中心id。
/// /// 獲取機器id
///
///
private int getworkerid()}}
}console.writeline($"ip = ");
var val = ipaddress.getaddressbytes().sum(x => x);
// 取餘
workerid = val % (int)maxworkerid;
}catch
return workerid;
}/// /// 獲取資料中心id
///
///
private int getdatacenterid()
"); var val = system.text.encoding.utf8.getbytes(hostname).sum(x => x);
// 取餘
return val % (int)maxdatacenterid;
}
生成器的建構函式
public idgenerator(long datacenterid = -1)
if (datacenterid > maxdatacenterid || datacenterid < 0)
// 先檢驗再賦值
workerid = getworkerid();
datacenterid = datacenterid;
console.writeline($"w = ");
console.writeline($"d = ");
}
這裡的資料中心可以讓使用方自己定義,預設-1的話,會根據hostname去生成乙個。
這裡給乙個自定義的可選標識,主要還是考慮到了單機多例項,即乙個ip上面部署多個例項。
雖然這個時候還是要考慮人工配置,不過已經從多機變成單機了,也算是一點簡化。畢竟大部分情況下也不會建議在同乙個機器部署多個一樣的專案。
預設情況下的使用,idgenerator物件要全域性唯一,做成單例即可。
idgenerator generator = new idgenerator();
parallel.for(0, 20, x =>
);console.writeline("hello world!");
system.threading.thread.sleep(1000 * 60);
下面執行多個容器來模擬。
可以看到機器id和資料中心id都是沒有重複的。
在執行一次。
也是同樣的。
目前這種做法在應用例項少,機器數量少的情況下是基本可以滿足使用要求的了。老黃公司目前也就不到30臺伺服器,所以怎麼都是夠用的。
但是依靠ip和hostname,隨著例項或機器的數量增多,沒有辦法保證它們取餘算出來的一定是唯一的。
在這種情況下就需要考慮引用第三方儲存(redis或資料庫)來保證這個的唯一性了。
snowflakedemo
雪花演算法使用教程
首先建立工具類randomidutil 隨機數 public class randomidutil if machineid max machine num machineid 0 this datacenterid datacenterid this machineid machineid 產生下...
《演算法競賽高階指南》 雪花雪花雪花
有n片雪花,每片雪花由六個角組成,每個角都有長度。第i片雪花六個角的長度從某個角開始順時針依次記為ai,1,ai,2,ai,6。因為雪花的形狀是封閉的環形,所以從任何乙個角開始順時針或逆時針往後記錄長度,得到的六元組都代表形狀相同的雪花。例如ai,1,ai,2,ai,6和ai,2,ai,3,ai,6...
《演算法 雪花演算法》
一 概述 snowflake 演算法 是 twitter 開源的分布式 id 生成演算法。應用場景 高效能的產生不重複id,支援集群的橫向擴充套件。二 原理 其核心思想就是 使用乙個 64 bit 的 long 型的數字作為全域性唯一 id。在分布式系統中的應用十分廣泛,且id 引入了時間戳,基本上...