日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java實現Twitter的分布式自增ID算法snowflake

瀏覽:4日期:2022-08-26 09:21:22

概述

分布式系統中,有一些需要使用全局唯一ID的場景,這種時候為了防止ID沖突可以使用36位的UUID,但是UUID有一些缺點,首先他相對比較長,另外UUID一般是無序的。

有些時候我們希望能使用一種簡單一些的ID,并且希望ID能夠按照時間有序生成。

而twitter的snowflake解決了這種需求,最初Twitter把存儲系統從MySQL遷移到Cassandra,因為Cassandra沒有順序ID生成機制,所以開發了這樣一套全局唯一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型。(轉換成字符串后長度最多19)

snowflake生成的ID整體上按照時間自增排序,并且整個分布式系統內不會產生ID碰撞(由datacenter和workerId作區分),并且效率較高。經測試snowflake每秒能夠產生26萬個ID。

源碼

(JAVA版本的源碼)

/** * Twitter_Snowflake<br> * SnowFlake的結構如下(每部分用-分開):<br> * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br> * 1位標識,由于long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0<br> * 41位時間截(毫秒級),注意,41位時間截不是存儲當前時間的時間截,而是存儲時間截的差值(當前時間截 - 開始時間截) * 得到的值),這里的的開始時間截,一般是我們的id生成器開始使用的時間,由我們程序來指定的(如下下面程序IdWorker類的startTime屬性)。41位的時間截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br> * 10位的數據機器位,可以部署在1024個節點,包括5位datacenterId和5位workerId<br> * 12位序列,毫秒內的計數,12位的計數順序號支持每個節點每毫秒(同一機器,同一時間截)產生4096個ID序號<br> * 加起來剛好64位,為一個Long型。<br> * SnowFlake的優點是,整體上按照時間自增排序,并且整個分布式系統內不會產生ID碰撞(由數據中心ID和機器ID作區分),并且效率較高,經測試,SnowFlake每秒能夠產生26萬ID左右。 */public class SnowflakeIdWorker { // ==============================Fields=========================================== /** 開始時間截 (2015-01-01) */ private final long twepoch = 1420041600000L; /** 機器id所占的位數 */ private final long workerIdBits = 5L; /** 數據標識id所占的位數 */ private final long datacenterIdBits = 5L; /** 支持的最大機器id,結果是31 (這個移位算法可以很快的計算出幾位二進制數所能表示的最大十進制數) */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits); /** 支持的最大數據標識id,結果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); /** 序列在id中占的位數 */ private final long sequenceBits = 12L; /** 機器ID向左移12位 */ private final long workerIdShift = sequenceBits; /** 數據標識id向左移17位(12+5) */ private final long datacenterIdShift = sequenceBits + workerIdBits; /** 時間截向左移22位(5+5+12) */ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** 生成序列的掩碼,這里為4095 (0b111111111111=0xfff=4095) */ private final long sequenceMask = -1L ^ (-1L << sequenceBits); /** 工作機器ID(0~31) */ private long workerId; /** 數據中心ID(0~31) */ private long datacenterId; /** 毫秒內序列(0~4095) */ private long sequence = 0L; /** 上次生成ID的時間截 */ private long lastTimestamp = -1L; //==============================Constructors===================================== /** * 構造函數 * @param workerId 工作ID (0~31) * @param datacenterId 數據中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format('worker Id can’t be greater than %d or less than 0', maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format('datacenter Id can’t be greater than %d or less than 0', maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } // ==============================Methods========================================== /** * 獲得下一個ID (該方法是線程安全的) * @return SnowflakeId */ public synchronized long nextId() { long timestamp = timeGen(); //如果當前時間小于上一次ID生成的時間戳,說明系統時鐘回退過這個時候應當拋出異常 if (timestamp < lastTimestamp) { throw new RuntimeException( String.format('Clock moved backwards. Refusing to generate id for %d milliseconds', lastTimestamp - timestamp)); } //如果是同一時間生成的,則進行毫秒內序列 if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; //毫秒內序列溢出 if (sequence == 0) {//阻塞到下一個毫秒,獲得新的時間戳timestamp = tilNextMillis(lastTimestamp); } } //時間戳改變,毫秒內序列重置 else { sequence = 0L; } //上次生成ID的時間截 lastTimestamp = timestamp; //移位并通過或運算拼到一起組成64位的ID return ((timestamp - twepoch) << timestampLeftShift) //| (datacenterId << datacenterIdShift) //| (workerId << workerIdShift) //| sequence; } /** * 阻塞到下一個毫秒,直到獲得新的時間戳 * @param lastTimestamp 上次生成ID的時間截 * @return 當前時間戳 */ protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } /** * 返回以毫秒為單位的當前時間 * @return 當前時間(毫秒) */ protected long timeGen() { return System.currentTimeMillis(); } //==============================Test============================================= /** 測試 */ public static void main(String[] args) { SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); for (int i = 0; i < 1000; i++) { long id = idWorker.nextId(); System.out.println(Long.toBinaryString(id)); System.out.println(id); } }}

參考

https://github.com/twitter/snowflake

到此這篇關于Java實現Twitter的分布式自增ID算法snowflake的文章就介紹到這了,更多相關Java 自增ID算法snowflake內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品毛片久久| 亚洲精品人人| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 国产剧情在线观看一区| 韩国三级一区| 99久久99久久精品国产片果冰| 国产精品www.| 国内精品麻豆美女在线播放视频| 亚洲97av| 亚洲欧美一级| 亚洲精品观看| 午夜精品久久久久久久久久蜜桃| 久久中文在线| 乱一区二区av| 亚洲激情中文| 久久国产精品99国产| 久久久久国产| 欧美日韩国产高清| 亚洲精品中文字幕99999| 蜜桃久久av一区| 日韩精品一页| 国产精选在线| 野花国产精品入口| 久久一二三区| 鲁大师精品99久久久| 久久激情网站| 久热精品在线| 亚洲精品福利| 久久一级电影| 国产一区 二区| 久久久久91| 中文字幕视频精品一区二区三区| 最新亚洲国产| 日韩不卡视频在线观看| 亚洲91网站| 热三久草你在线| 久久午夜精品一区二区| 国内精品亚洲| 91精品二区| 久久gogo国模啪啪裸体| 波多野结衣一区| 日韩亚洲国产欧美| 美女视频免费精品| 亚洲我射av| 国产一区二区视频在线看| 99久久久久| 亚洲免费影院| 日韩欧美看国产| 欧美私人啪啪vps| 精品久久亚洲| 国产精品日本一区二区三区在线| 欧美在线亚洲综合一区| 国产精品一区二区三区www| 国产精品国产三级国产在线观看| 日韩精品导航| 亚洲一区二区小说| 精品美女久久| 欧美日韩一区二区三区在线电影| 久久久久免费| 国产精品分类| 综合亚洲自拍| 日韩综合一区二区三区| 久久中文字幕av| 中文字幕在线免费观看视频| 国产精品日本一区二区三区在线| 视频一区视频二区中文| 高清av一区| 久久亚洲国产精品尤物| 日本欧美大码aⅴ在线播放| 9色精品在线| 在线日韩中文| 日韩精品电影| 欧美sm一区| 在线一区视频观看| 在线手机中文字幕| 日韩国产欧美一区二区| 日韩综合一区| 91精品啪在线观看国产18| 国产不卡人人| | 成人精品天堂一区二区三区| 精品视频亚洲| 激情黄产视频在线免费观看| 日韩欧美中文| 中文亚洲欧美| 首页国产欧美久久| 欧美私人啪啪vps| 久久影院一区二区三区| 狠狠久久伊人| 日韩国产专区| 欧美美女一区| 久久最新视频| 国产精品极品国产中出| 国产成人精品亚洲线观看| 免费观看不卡av| 欧美大黑bbbbbbbbb在线| 欧美午夜不卡| 欧美日韩调教| 福利一区二区三区视频在线观看| 在线天堂资源www在线污| 激情丁香综合| 国产亚洲精品自拍| 色一区二区三区四区| 欧美国产偷国产精品三区| 99视频精品视频高清免费| 亚洲2区在线| 久久精品免费一区二区三区| 99久精品视频在线观看视频| 日韩在线观看中文字幕| 天堂√8在线中文| 欧美日韩午夜电影网| 亚洲精品电影| 久久久男人天堂| 亚洲精品免费观看| 国产成人精品亚洲日本在线观看| 激情欧美丁香| 国产精品日本一区二区三区在线| 国产在线|日韩| 欧美一区二区三区免费看| 美女少妇全过程你懂的久久| 日本特黄久久久高潮| 一区二区精彩视频| 国产精品99一区二区三| 久久国产三级精品| 日韩一区二区久久| 国产91精品对白在线播放| 欧美激情亚洲| 日韩av二区在线播放| 日本午夜精品| 四虎成人精品一区二区免费网站| 国产一区二区三区视频在线| 中文字幕成人| 亚洲午夜免费| 久久高清免费观看| 激情欧美一区二区三区| av在线最新| 国产不卡av一区二区| 国产福利资源一区| 青青青国产精品| 好吊视频一区二区三区四区| 激情黄产视频在线免费观看| 久久国产尿小便嘘嘘| 久久国内精品| 国产精品**亚洲精品| 老色鬼精品视频在线观看播放| 久久亚洲欧美| 欧美日韩四区| 91九色精品国产一区二区| 亚洲二区在线| 亚洲大片在线| 91精品久久久久久久久久不卡| 久久精品二区亚洲w码| 国产高清视频一区二区| 日韩国产一二三区| 亚洲精品日本| 日韩精彩视频在线观看| 涩涩涩久久久成人精品| 日韩激情一二三区| 日本免费在线视频不卡一不卡二| 亚洲欧美网站在线观看| 免费在线观看视频一区| 亚洲激情偷拍| 日韩福利视频导航| 久久久久伊人| 日本一区二区高清不卡| 亚洲一区国产| 国产精品videossex| 久久影院资源站| 久久久精品五月天| 香蕉久久久久久久av网站| 日韩欧美高清一区二区三区| 欧美视频精品全部免费观看| 精品久久福利| 免费人成黄页网站在线一区二区| 日韩精品一页| 久久三级中文| 99久久亚洲精品| 久久国产麻豆精品| 欧美日韩精品在线一区| 日韩1区2区3区| 日韩中文影院| 日本中文字幕一区二区| 伊人久久国产| 婷婷成人av| 亚洲特色特黄| 免费亚洲婷婷| 日本一区二区三区中文字幕| 99久久久久国产精品| 麻豆国产精品一区二区三区| 日韩毛片网站| 国产极品模特精品一二| 欧美精品九九| 亚洲精品**中文毛片| 国产一区二区三区精品在线观看| 日本精品在线播放| 中文字幕av亚洲精品一部二部 | 91精品一区| 视频一区二区不卡| 日本在线精品| 黄色成人精品网站|