一、雪花ID簡介
雪花ID是Twitter開源的分散式ID生成演算法,採用信息耗盡式演算法,生成的id不會重複,可以根據時間戳、機器id、序列號等信息生成64位的長整型ID。雪花ID是一個非常流行的分散式ID生成演算法,其底層依賴於一個64位的long型變數,可以通過位運算等方式將long型變數表示成字元串形式的ID號,以此實現唯一ID的生成。
二、雪花ID組成部分
雪花ID組成的64位就是一個long型的數字,從二進位的角度來看,這個數字上有五部分構成:
- 1.首位是符號位(1bit),生成的ID恆為正數,所以這個位的值始終是0。
- 2.接下來的41位是時間戳, 表示生成的時間戳(毫秒級)。
- 3.然後是5位數據中心標識ID和5位進程標識ID,表示在兩部分信息中的機器ID標識,15位的機器編號支持的節點數達到32768個機器節點。
- 4.緊接著是10位序列號,表示同一機器同一毫秒內生成的不同ID序號,同時支持單機每毫秒的ID數達到1024個。
通過這樣的方式組裝成一個64位的long型變數。
三、雪花ID生成的可靠性
雪花ID是滿足以下需求的:
- 1.全局唯一,時間戳(包括序列號)相同的id不會重複。
- 2.趨勢遞增,因為採用時間戳作為生成信息,所以生成的ID越來越大。
- 3.信息安全,序列號佔了10位,理論上每個時間戳里的序列號最大可以達到1024,如果超過了這個限制,程序會自旋等待下一個毫秒再生成ID。
- 4.高可用,如果發生時鐘回撥,可以通過程序自旋等待後續時鐘進行補償。
四、雪花ID生成步驟
為了更好地理解雪花ID生成規則,我們可以將其步驟總結如下:
- 1.時間戳部分
- 2.數據中心、機器標識部分
- 3.序列號部分
long timestamp = System.currentTimeMillis();
時間戳部分採用當前時間毫秒級別的時間戳,佔用41位。
long datacenterId = 1L;
long machineId = 2L;
數據中心和機器標識這兩部分都是採用配置的方式來實現,佔用10位。
long sequence = 0L;
long lastTimestamp = -1L;
while (true) {
long nowTimestamp = System.currentTimeMillis();
if (nowTimestamp < lastTimestamp) {
throw new RuntimeException("雪花ID系統時鐘回退異常,請及時處理!");
}
if (nowTimestamp == lastTimestamp) {
sequence = (sequence + 1) & maxSequence;
if (sequence == 0) {
nowTimestamp = waitNextMillisecond(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = nowTimestamp;
return ((nowTimestamp - twepoch) << timestampShift) |
(datacenterId << datacenterIdShift) |
(machineId << machineIdShift) | sequence;
}
序列號部分採用循環累加的方式實現,可實現每毫秒1024個不同的序列號,佔用10位。
五、雪花ID生成總結
雪花ID是一種很好的分散式ID生成演算法,其基於時間戳、機器ID、序列號等信息生成唯一的64位ID。同時,其在可靠性、趨勢遞增、信息安全以及高可用等方面表現出了極佳的效果,並且也有著較為簡潔易懂的生成規則。我們在實際項目中常常會使用到這種方式來生成唯一ID,哈哈,不過要注意時鐘回撥問題哦~
原創文章,作者:EFPN,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/150178.html