自學 分布式ID生成器

2021-09-10 18:50:09 字數 1855 閱讀 1039

最近在做乙個專案,遇到了乙個小問題:針對資料庫的主鍵自增這塊怎麼解決,前提是採用分片部署。如果還是用我們之前的方式主鍵自增,會造成乙個表中id的重複。舉例說明:比如有乙個商品表,將這個商品表部署在3臺伺服器上:server1、server2、server3。如果是以前的主鍵自增:server1中會從id1開始,server2中會從id1開始,server3中會從id1開始。如果將這個商品表合併的話,那麼就會出現商品表**現id都為1的商品,這種是不符合我們實際的開發的。所有必須採用另外一種方式將:使用程式來生產唯一的主鍵值。

雪花演算法:snowflake。

10bit的工作機器id可以 支援1024臺機器;

序列號支援1毫秒產生4096個自增序列id ;

snowflake的優點是,整體上按照時間自增排序,並且整個分布式系統內不會產生id碰撞(由資料中心id和機器id 作區分),並且效率較高,經測試,snowflake每秒能夠產生26萬id左右。

public class idworker 

/*** @param workerid

* 工作機器id

* @param datacenterid

* 序列號

*/public idworker(long workerid, long datacenterid)

if (datacenterid > maxdatacenterid || datacenterid < 0)

this.workerid = workerid;

this.datacenterid = datacenterid;

}/**

* 獲取下乙個id

** @return

*/public synchronized long nextid()

if (lasttimestamp == timestamp)

} else

lasttimestamp = timestamp;

// id偏移組合生成最終的id,並返回id

long nextid = ((timestamp - twepoch) << timestampleftshift)

| (datacenterid << datacenteridshift)

| (workerid << workeridshift) | sequence;

return nextid;

}private long tilnextmillis(final long lasttimestamp)

return timestamp;

}private long timegen()

/*** * 獲取 maxworkerid

* */

protected static long getmaxworkerid(long datacenterid, long maxworkerid)

/** mac + pid 的 hashcode 獲取16個低位

*/return (mpid.tostring().hashcode() & 0xffff) % (maxworkerid + 1);

}/**

* * 資料標識id部分

* */

protected static long getdatacenterid(long maxdatacenterid) else

} catch (exception e)

return id;

}public static void main(string args) }}

分布式ID生成器

一 需求緣起 幾乎所有的業務系統,都有生成乙個唯一記錄標識的需求,例如 這個記錄標識往往就是資料庫中的主鍵,資料庫上會建立聚集索引 cluster index 即在物理儲存上以這個字段排序。這個記錄標識上的查詢,往往又有分頁或者排序的業務需求,例如 所以往往要有乙個time欄位,並且在time欄位上...

分布式 ID 生成器

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

分布式ID生成器(雪花演算法)

目前微服務架構盛行,在分布式系統中的操作中都會有一些全域性性id的需求,所以我們不能使用資料庫本身的自增功能來產生主鍵值,只能由程式來生成唯一的主鍵值。我們採用的是開源的twitter 非官方中文慣稱 推特.是國外的乙個 是乙個社交網路及微部落格服務 的snowflake 雪花 演算法。各個段解析 ...