分布式系統中,有一些需要使用全域性唯一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 該方法是執行緒安全的 ...