柚子快報邀請碼778899分享:java 分布式id-雪花算法
柚子快報邀請碼778899分享:java 分布式id-雪花算法
通常我們在生成用戶id或者訂單id時都需要一個全局唯一的id來唯一標(biāo)識,在單體情況下我們可以使用UUID、時間戳、數(shù)據(jù)庫自增id
而在分布式情況下,需要考慮大量服務(wù)器之間生成的id全局唯一,所以就使用了今天要介紹的雪花算法來生成分布式下的全局id
單體服務(wù)UUID、時間戳、數(shù)據(jù)庫自增id存在以下問題:
UUID是無序的且數(shù)據(jù)非常大(128bit),且一般會使用36位長度的字符串存儲,這樣會導(dǎo)致id存入數(shù)據(jù)庫時需要大量的存儲空間來存放id,且id一般為主鍵,則在生成聚簇索引時則會耗費(fèi)巨大的空間,并且UUID一般不呈遞增趨勢,在生成數(shù)據(jù)庫索引時會出現(xiàn)大量頁分裂等情況,影響性能; 時間戳則不滿足高并發(fā)情況下的id,對于在某一毫秒只能生成的一個id,無法應(yīng)對高并發(fā)場景下的id生成 自增id不適合分布式數(shù)據(jù)庫分庫分表,對于多個數(shù)據(jù)庫,id無法滿足所有數(shù)據(jù)庫生成的id全局唯一,并且每次從數(shù)據(jù)庫中獲取id性能非常低
所以我們引入了一個分布式id生成算法:雪花算法,接下來就詳細(xì)介紹一下雪花算法
雪花算法主要是由三部分組成:
? ? ? 1. 1bit的符號位+41bit的時間戳格式
1bit符號位即0表示正數(shù),1表示負(fù)數(shù),由于一般都是使用正數(shù),所以一般都是直接固定為0
為什么時間戳格式是41位呢?
雪花算法是直接使用currentTimeMillis()方法生成的時間戳
System.currentTimeMillis();
該方法生成的時間戳是一個13位的十進(jìn)制格式,但是轉(zhuǎn)換為二進(jìn)制是41位
long l = System.currentTimeMillis();
System.out.println(l); //1716194029842
System.out.println(Long.toBinaryString(System.currentTimeMillis()) ); //11000111110010101001000101011000100010011
? ? ? 2. 5bit的數(shù)據(jù)中心+5bt的機(jī)器標(biāo)識
數(shù)據(jù)中心:表示當(dāng)前服務(wù)器所在集群地,例如設(shè)置北京為0,上海為1,深圳為2...,數(shù)據(jù)中心最多只支持2^5 -?1個
機(jī)器標(biāo)識:表示服務(wù)器的一個唯一標(biāo)識,對于某地來說最多只能支持2^5 - 1個機(jī)器
? ? ? 3. 12bit的序列號
序列號主要是為了滿足在高并發(fā)場景下,需要生成大量id且滿足不重復(fù)的需求,所以雪花算法在原本基礎(chǔ)上加上了序列,即在數(shù)據(jù)中心、機(jī)器標(biāo)識確定時,每一毫秒最多可生成2^12 - 1個不重復(fù)的id
由于雪花算法是使用的Long數(shù)據(jù)類型,使用的位數(shù)加起來1+41+5+5+12 = 64位的Long數(shù)據(jù)類型,將Long類型的位數(shù)最大化了
各位數(shù)是怎么進(jìn)行拼湊的呢?
我們使用全1表示的時間戳,則符號位加時間戳為
011111111111111111111111111111111111111111
我們將時間戳左移22位即可得到(右邊用0補(bǔ)齊)
0111111111111111111111111111111111111111110000000000000000000000
使用全1的數(shù)據(jù)中心及機(jī)器標(biāo)識,并將數(shù)據(jù)中心和機(jī)器標(biāo)識分別向左移動17位和12位,即得到:
0000000000000000000000000000000000000000001111100000000000000000
0000000000000000000000000000000000000000000000011111000000000000
最后12位為序列號,不需要做移位操作,直接拼接即可
最后將所有的數(shù)字做與運(yùn)算,即可拼接為完整的64位Long類型的id號
1111111111111111111111111111111111111111111111111111000000000000
總結(jié):
雪花算法生成的全局id可滿足高并發(fā)情況下的id唯一性要求雪花算法采用的時間戳+序列號,滿足全局id的遞增趨勢,提高數(shù)據(jù)庫索引xing'n雪花算法生成的id采用Long數(shù)據(jù)類型,保存時相對于字符串占用更少的存儲空間
柚子快報邀請碼778899分享:java 分布式id-雪花算法
推薦文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。