唯一ID的生成方法

2021-10-06 03:20:20 字數 3016 閱讀 4791

生成唯一id的幾種方案:

(1) uuid

(2) mysql的自增主鍵

(3) mysql多例項自增主鍵

(4) 雪花id(snowflake演算法)(配合專案啟動命令效果更佳)

(5) redis生成方案

1. uuid生成方案

優點:**實現簡單,本機生成,沒有什麼效能問題,況且是全球唯一的id,所以遷移資料的時候比較容易

缺點:生成的id是無序的,無法滿足遞增趨勢;而且uuid的字串儲存,查詢效率較慢,儲存空間也大

綜上來看:uuid適用於類似生成token令牌的業務場景,但是不適於一些要求遞增趨勢的id場景

2.mysql自增主鍵

利用mysql的主鍵自增auto_increment,預設每次id加1

優點:數位化id遞增,查詢速度快,並且具有一定的業務可讀

缺點:存在單點問題(乙個主機連線多個處理節點,主節點負責分發任務,而子節點負責處理業務,當主節點發生故障時,會導致整個系統發故障),倘若mysql掛了,就無法進行id的生成;並且資料庫壓力會很大,高併發情況下扛不住

3.mysql多例項主鍵自增

解決mysql的單點問題,但是不方便擴容,所以在資料不需要擴容的場景適用,

4.雪花snowflake演算法

雪花演算法生成64位的二進位制正整數,然後轉換成10進製的數。64位二進位制數由如下部分組成

1位識別符號:始終是0

41位時間戳:41位時間截不是儲存當前時間的時間截,而是儲存時間截的差值(當前時間截 - 開始時間截 )得到的值,這裡的的開始時間截,一般是我們的id生成器開始使用的時間,由我們程式來指定的

10位機器標識碼:可以部署在1024個節點,如果機器分機房(idc)部署,這10位可以由 5位機房id + 5位機器id 組成

12位序列:毫秒內的計數,12位的計數順序號支援每個節點每毫秒(同一機器,同一時間截)產生4096個id序號

加起來剛好64位,為乙個long型

優點:效能快,整體上按照時間自增排序,並且整個分布式系統內不會產生ip重複碰撞(由資料中心id和機器id作區分),效率較高

缺點:依賴機器的時鐘,如果伺服器時鐘回撥,會導致重複id生成(docker部署專案深有體會,啟動命令需要寫好serviceid)

public class snowflakeidworker 

public static final snowflakeidworker getinstance()

//獲取aid

public static final string getaid()

//******************************constructors***********************************==

/*** 建構函式

* @param workeridstr 工作id (0~31)

* @param datacenteridstr 資料中心id (0~31)

*/private snowflakeidworker(string workeridstr) else

if (workerid > maxworkerid || workerid < 0)

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(snowflakeidworkerholder.instance.nextid());

}}

6.redis生成方案

利用redis的incr原子性操作自增,一般演算法為:

年份 + 當天距當年第多少天 + 天數 + 小時 + redis自增

優點:有序遞增,可讀性強

缺點:占用頻寬,每次要向redis傳送請求,有網路請求耗時,併發強依賴了redis。這個設計是有風險的,一旦redis掛了,整個系統不可用,使用者是可以**下乙個id號是多少,因為演算法是遞增的(安全性)

惟一ID生成方法

幾乎所有的業務系統,都存在生成惟一id的需求,例如 使用者id user id 訂單id order id 訊息id msg id 常見的id生成有三大類方法 一 中介軟體實現 1 利用mysql的auto increment,oracle的sequence實現 優點 簡單,遞增 缺點 伸縮性 擴充...

Zookeeper全域性唯一ID生成方案解析

系統唯一id生成分案有很多種,例如 資料庫 auto increment,uuid,redis生成id redis原子操作incr和incrby twiitter的snowflake演算法,zookeeper生成id,mongodb的objectid,下面我們就看一下zookeeper實現分布式系統...

分布式唯一ID的生成方案

不能出現重複的id,這是最基本的要求。有利於關聯式資料庫索引效能。既然是服務於分布式系統,為多個服務提供id服務,訪問壓力一定很大,所以需要保證高可用。如果id是有規律的,就容易被惡意操作,在一些場景下需要id無規則。核心思想是結合機器的網絡卡 當地時間 乙個隨機數來生成。優點 缺點 利用資料庫自增...