分布式ID生成方式之雪花演算法

2021-10-03 02:13:55 字數 1547 閱讀 8552

在資料量不大的情況下,單庫單錶完全滿足現有業務,但是隨著資料日益增大,分庫分表是必然的操作,這時候繼續用資料庫的自增id無法滿足需求,因為假如有多張表都是存訂單的資訊,每個表都是自增的id,那就會出現重複的id號了,當然可以設定表的步長,比如表1的id從1開始,每隔兩步增長一次。表2的id從2開始,那麼他們的id就會是1,3,5,7,9…,2,4,6,8,10…,但是這樣後續的擴容也是很麻煩的事情,比如表的繼續增加咋辦,依然不是好的解決辦法。

如果要得到乙個全域性唯一的id,首先估計會想到使用uuid,生成方法很簡單:string uuid = uuid.randomuuid().tostring();得到的結果類似這樣:b8375e0f-4853-4f5c-9133-2ed64e7e7d87,這樣的字串用來做主鍵的話是不符合mysql的索引原則的,之前的文章有專門寫過mysql索引的原則,因為mysql在生成索引樹的時候是要計算左右子樹的大小的,這樣的id做主鍵會使mysql的儲存和查詢效率變得很低。

雪花演算法(snowflake)

public class snowflakeidworker 

if (datacenterid > maxdatacenterid || datacenterid < 0)

this.workerid = workerid;

this.datacenterid = datacenterid;

} /**

* 獲得下乙個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()

/** 測試 */

public static void main(string args)

}

雪花演算法生成分布式ID

package top.sponger.common.util import lombok.data 描述 twitter的分布式自增id雪花演算法snowflake public class snowflake if machineid max machine num machineid 0 th...

分布式ID生成方案

系統唯一id是設計乙個系統的時候常常會遇到的問題,也常常為這個問題而糾結。生成id的方法有很多,適應不同的場景 需求以及效能要求。所以有些比較複雜的系統會有多個id生成的策略。1 全域性唯一性 不能出現重複的id號,既然是唯一標識,這是最基本的要求 2 粗略有序 如果在分布式環境中做到完全有序,需要...

分布式全域性ID之雪花演算法

public class idworker if datacenterid maxdatacenterid datacenterid 0 system.out.printf worker starting.timestamp left shift d,datacenter id bits d,wor...