雪花演算法詳解

2021-09-05 19:40:45 字數 2785 閱讀 1788

前言

雪花演算法是用來在分布式場景下生成唯一id的。

敘述

雪花演算法簡單描述:

+ 最高位是符號位,始終為0,不可用。

+ 41位的時間序列,精確到毫秒級,41位的長度可以使用69年。時間位還有乙個很重要的作用是可以根據時間進行排序。

+ 10位的機器標識,10位的長度最多支援部署1024個節點。

+ 12位的計數序列號,序列號即一系列的自增id,可以支援同一節點同一毫秒生成多個id序號,12位的計數序列號支援每個節點每毫秒產生4096個id序號。

package com.dmsdbj.cloud.tool.uuid;

import lombok.tostring;

/** * @description 雪花演算法生成器

* @author sunshine

* @date 2023年11月23日15:33:39

*/@tostring

public class snowflakeidfactory

/*** 建構函式

* @param workerid 工作id (0~31)

* @param datacenterid 資料中心id (0~31)

*/public snowflakeidfactory(long workerid, long datacenterid)

if (datacenterid > maxdatacenterid || datacenterid < 0)

this.workerid = workerid;

this.datacenterid = datacenterid;

}/**

* 獲得下乙個id (該方法是執行緒安全的)

* @return snowflakeid

*/public synchronized long nextid()

// 如果是同一時間生成的,則進行毫秒內序列

// sequencemask 為啥是4095 2^12 = 4096

if (lasttimestamp == timestamp)

}// 時間戳改變,毫秒內序列重置

else

// 上次生成id的時間截

lasttimestamp = timestamp;

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)

system.out.println((system.nanotime() - starttime) / 1000000 + "ms");

}}

問題1:twepoch 為什麼要等於1288834974657l 而不等於其他數

答: 1288834974657 是 (thu, 04 nov 2010 01:42:54 gmt) 這一時刻到1970-01-01 00:00:00時刻所經過的毫秒數。41位位元組作為時間戳數值的話,大約68年就會用完,假如你2023年1月1日開始開發系統,如果不減去2023年1月1日的時間戳,那麼白白浪費40年的時間戳啊!所有減去twepoch 可以讓系統在41位位元組作為時間戳的情況下的執行時間更長。1288834974657l可能就是該專案開始成立的時間。

問題2:類似這種long maxworkerid = -1l ^ (-1l << workeridbits);操作是什麼意思?

答: -1l ^ (-1l << n)表示佔n個bit的數字的最大值是多少。舉個栗子:-1l ^ (-1l << 2)等於10進製的3 ,即二進位制的11表示十進位制3。

注意:計算機存放數字都是存放數字的補碼,正數的原碼、補碼、反碼都一樣,負數的補碼是其反碼加一。符號位做取反操作時不變,做邏輯與、或、非、異或操作時要參與運算。

再來個栗子:

-1l原碼 : 1000 0001

-1l反碼 : 1111 1110

-1l補碼 : 1111 1111

-1l<<5 : 1110 0000

1111 1111 ^ 1110 0000 : 0001 1111

0001 1111是正數,所以補碼、反碼、原碼都一樣,所以0001 1111是31

問題3:**意思不明白

((timestamp - twepoch) << timestampleftshift) | (datacenterid << datacenteridshift) | (workerid << workeridshift) | sequence

小結

雪花演算法是乙個經典的id生成器的演算法,可以學習了解一下.

《演算法競賽高階指南》 雪花雪花雪花

有n片雪花,每片雪花由六個角組成,每個角都有長度。第i片雪花六個角的長度從某個角開始順時針依次記為ai,1,ai,2,ai,6。因為雪花的形狀是封閉的環形,所以從任何乙個角開始順時針或逆時針往後記錄長度,得到的六元組都代表形狀相同的雪花。例如ai,1,ai,2,ai,6和ai,2,ai,3,ai,6...

《演算法 雪花演算法》

一 概述 snowflake 演算法 是 twitter 開源的分布式 id 生成演算法。應用場景 高效能的產生不重複id,支援集群的橫向擴充套件。二 原理 其核心思想就是 使用乙個 64 bit 的 long 型的數字作為全域性唯一 id。在分布式系統中的應用十分廣泛,且id 引入了時間戳,基本上...

雪花演算法 snowflake

分布式系統中,有一些需要使用全域性唯一id的場景,這種時候為了防止id衝突可以使用36位的uuid,但是uuid有一些缺點,首先他相對比較長,另外uuid一般是無序的。有些時候我們希望能使用一種簡單一些的id,並且希望id能夠按照時間有序生成。而twitter的snowflake解決了這種需求,最初...