生成唯一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無規則。核心思想是結合機器的網絡卡 當地時間 乙個隨機數來生成。優點 缺點 利用資料庫自增...