分布式自增ID演算法snowflake的JAVA實現

2021-08-09 10:27:48 字數 2089 閱讀 6432

分布式系統中,有一些需要使用全域性唯一id的場景,這種時候為了防止id衝突可以使用36位的uuid,但是uuid有一些缺點,首先他相對比較長,另外uuid一般是無序的。

有些時候我們希望能使用一種簡單一些的id,並且希望id能夠按照時間有序生成。

而twitter的snowflake解決了這種需求,最初twitter把儲存系統從mysql遷移到cassandra,因為cassandra沒有順序id生成機制,所以開發了這樣一套全域性唯一id生成服務。

snowflake是twitter開源的分布式id生成演算法,其核心思想是:乙個long型的id,使用其中41bit作為毫秒數,10bit作為機器編號,12bit作為毫秒內序列號。這個演算法單機每秒內理論上最多可以生成1000*(2^12),也就是400w的id,完全能滿足一般業務的需求

snowflake的結構如下(每部分用-分開):

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000

第一位為未使用,接下來的41位為毫秒級時間(41位的長度可以使用69年),然後是5位datacenterid和5位workerid(10位的長度最多支援部署1024個節點) ,最後12位是毫秒內的計數(12位的計數順序號支援每個節點每毫秒產生4096個id序號)

一共加起來剛好64位,為乙個long型。(轉換成字串長度為18)

snowflake生成的id整體上按照時間自增排序,並且整個分布式系統內不會產生id碰撞(由datacenter和workerid作區分),並且效率較高。據說:snowflake每秒能夠產生26萬個id。

原始碼 package com.cloud.utils;

public class snowflakeidworker

if (datacenterid > maxdatacenterid || datacenterid < 0)

this.workerid = workerid;

this.datacenterid = datacenterid;

}// ******************************methods****************************************==

/** * 獲得下乙個id (該方法是執行緒安全的)

* @return snowflakeid

*/public synchronized long nextid()

//如果是同一時間生成的,則進行毫秒內序列

if (lasttimestamp == timestamp)

}//時間戳改變,毫秒內序列重置

else

//上次生成id的時間截

lasttimestamp = timestamp;

//移位並通過或運算拼到一起組成64位的id

return ((timestamp - twepoch) << timestampleftshift) //

| (datacenterid << datacenteridshift) //

| (workerid << workeridshift) //

| sequence;

}/**

* 阻塞到下乙個毫秒,直到獲得新的時間戳

* @param lasttimestamp 上次生成id的時間截

* @return 當前時間戳

*/protected long tilnextmillis(long lasttimestamp)

return timestamp;

}/**

* 返回以毫秒為單位的當前時間

* @return 當前時間(毫秒)

*/protected long timegen()

//******************************test*********************************************

/** 測試 */

public static void main(string args)

system.out.println((system.nanotime()-starttime)/1000000+"ms");

}

Twitter的分布式自增ID演算法

乙個唯一 id 在乙個分布式系統中是非常重要的乙個業務屬性,其中包括一些如訂單 id,訊息 id 會話 id,他們都有一些共有的特性 全域性唯一很好理解,目的就是唯一標識某個次請求,某個業務。通常有以下幾種方案 可以利用mysql中的自增屬性auto increment來生成全域性唯一 id,也能保...

MySQL分布式實現ID自增

由於資料量以及io效率的因素,很多專案對資料支援的資料庫會採取分庫分表的方式。使用了分庫分表之後需要解決的乙個問題就是主鍵的生成。多個表之間的主鍵就不能用資料庫本身的自增主鍵來支援,因為不同表之間生成的主鍵會重複。所以需要其他的方式獲取主鍵id。一般來說解決方案主要有三種 oracle sequen...

分布式唯一ID自增(雪花演算法)

public class idworker if datacenterid maxdatacenterid datacenterid 0 this.workerid workerid this.datacenterid datacenterid methods 獲得下乙個id 該方法是執行緒安全的 ...