国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Twitter的分布式雪花算法 SnowFlake 每秒自增生成26個萬個可排序的ID (Java版

Awbeci / 1574人閱讀

摘要:原理的雪花算法,使用語言實現。生成的整體上按照時間自增排序,并且整個分布式系統內不會產生碰撞由和作區分,并且效率較高。據說每秒能夠產生萬個。

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

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

而twitter的SnowFlake解決了這種需求,最初Twitter把存儲系統從MySQL遷移到Cassandra,因為Cassandra沒有順序ID生成機制,所以開發了這樣一套全局唯一ID生成服務。

原理

Twitter的雪花算法SnowFlake,使用Java語言實現。

SnowFlake算法產生的ID是一個64位的整型,結構如下(每一部分用“-”符號分隔):

</>復制代碼

  1. 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000

1位標識部分,在java中由于long的最高位是符號位,正數是0,負數是1,一般生成的ID為正數,所以為0;

41位時間戳部分,這個是毫秒級的時間,一般實現上不會存儲當前的時間戳,而是時間戳的差值(當前時間-固定的開始時間),這樣可以使產生的ID從更小值開始;41位的時間戳可以使用69年,(1L << 41) / (1000L 60 60 24 365) = 69年;

10位節點部分,Twitter實現中使用前5位作為數據中心標識,后5位作為機器標識,可以部署1024個節點;

12位序列號部分,支持同一毫秒內同一個節點可以生成4096個ID;

SnowFlake算法生成的ID大致上是按照時間遞增的,用在分布式系統中時,需要注意數據中心標識和機器標識必須唯一,這樣就能保證每個節點生成的ID都是唯一的。或許我們不一定都需要像上面那樣使用5位作為數據中心標識,5位作為機器標識,可以根據我們業務的需要,靈活分配節點部分,如:若不需要數據中心,完全可以使用全部10位作為機器標識;若數據中心不多,也可以只使用3位作為數據中心,7位作為機器標識。

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

源碼

本機實測:100萬個ID 耗時5秒

</>復制代碼

  1. /**
  2. * 描述: Twitter的分布式自增ID雪花算法snowflake (Java版)
  3. * https://github.com/souyunku/SnowFlake
  4. *
  5. * @author yanpenglei
  6. * @create 2018-03-13 12:37
  7. **/
  8. public class SnowFlake {
  9. /**
  10. * 起始的時間戳
  11. */
  12. private final static long START_STMP = 1480166465631L;
  13. /**
  14. * 每一部分占用的位數
  15. */
  16. private final static long SEQUENCE_BIT = 12; //序列號占用的位數
  17. private final static long MACHINE_BIT = 5; //機器標識占用的位數
  18. private final static long DATACENTER_BIT = 5;//數據中心占用的位數
  19. /**
  20. * 每一部分的最大值
  21. */
  22. private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
  23. private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
  24. private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
  25. /**
  26. * 每一部分向左的位移
  27. */
  28. private final static long MACHINE_LEFT = SEQUENCE_BIT;
  29. private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
  30. private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
  31. private long datacenterId; //數據中心
  32. private long machineId; //機器標識
  33. private long sequence = 0L; //序列號
  34. private long lastStmp = -1L;//上一次時間戳
  35. public SnowFlake(long datacenterId, long machineId) {
  36. if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
  37. throw new IllegalArgumentException("datacenterId can"t be greater than MAX_DATACENTER_NUM or less than 0");
  38. }
  39. if (machineId > MAX_MACHINE_NUM || machineId < 0) {
  40. throw new IllegalArgumentException("machineId can"t be greater than MAX_MACHINE_NUM or less than 0");
  41. }
  42. this.datacenterId = datacenterId;
  43. this.machineId = machineId;
  44. }
  45. /**
  46. * 產生下一個ID
  47. *
  48. * @return
  49. */
  50. public synchronized long nextId() {
  51. long currStmp = getNewstmp();
  52. if (currStmp < lastStmp) {
  53. throw new RuntimeException("Clock moved backwards. Refusing to generate id");
  54. }
  55. if (currStmp == lastStmp) {
  56. //相同毫秒內,序列號自增
  57. sequence = (sequence + 1) & MAX_SEQUENCE;
  58. //同一毫秒的序列數已經達到最大
  59. if (sequence == 0L) {
  60. currStmp = getNextMill();
  61. }
  62. } else {
  63. //不同毫秒內,序列號置為0
  64. sequence = 0L;
  65. }
  66. lastStmp = currStmp;
  67. return (currStmp - START_STMP) << TIMESTMP_LEFT //時間戳部分
  68. | datacenterId << DATACENTER_LEFT //數據中心部分
  69. | machineId << MACHINE_LEFT //機器標識部分
  70. | sequence; //序列號部分
  71. }
  72. private long getNextMill() {
  73. long mill = getNewstmp();
  74. while (mill <= lastStmp) {
  75. mill = getNewstmp();
  76. }
  77. return mill;
  78. }
  79. private long getNewstmp() {
  80. return System.currentTimeMillis();
  81. }
  82. public static void main(String[] args) {
  83. SnowFlake snowFlake = new SnowFlake(2, 3);
  84. long start = System.currentTimeMillis();
  85. for (int i = 0; i < 1000000; i++) {
  86. System.out.println(snowFlake.nextId());
  87. }
  88. System.out.println(System.currentTimeMillis() - start);
  89. }
  90. }

循環生成的ID,運行結果如下:

</>復制代碼

  1. 170916032679263329
  2. 170916032679263330
  3. 170916032679263331
  4. 170916032679263332
  5. 170916032679263333
  6. 170916032679263334
  7. 170916032679263335
  8. 170916032679263336
  9. 170916032679263337
  10. 170916032679263338
  11. 170916032679263339
  12. 170916032679263340
  13. 170916032679263341
  14. 170916032679263342
開源地址

Github:https://github.com/souyunku/SnowFlake

推薦閱讀 Spring Cloud 系列教程

Spring Cloud(一)服務的注冊與發現 Eureka

Spring Cloud(二)Consul 服務治理實現

Spring Cloud(三)服務提供者 Eureka + 服務消費者(rest + Ribbon)

Spring Cloud(四)服務提供者 Eureka + 服務消費者 Feign

Spring Cloud(五)斷路器監控(Hystrix Dashboard)

Spring Cloud(六)服務網關 zuul 快速入門

Spring Cloud(七)服務網關 Zuul Filter 使用

Spring Cloud(八)高可用的分布式配置中心 Spring Cloud Config

Spring Cloud(九)高可用的分布式配置中心 Spring Cloud Config 集成 Eureka 服務

Spring Cloud(十)高可用的分布式配置中心 Spring Cloud Config 中使用 Refresh

Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息總線集成(RabbitMQ)

Spring Boot 系列教程

源碼 + 教程

Github:https://github.com/souyunku/spring-boot-examples

Docker 容器

Docker Compose 1.18.0 之服務編排詳解

Docker CE 安裝 初窺 Dockerfile 部署 Nginx

Docker Container 容器操作

Docker Hub 倉庫使用,及搭建 Docker Registry

Docker Registry Server 搭建,配置免費 HTTPS 證書,及擁有權限認證、TLS 的私有倉庫

Docker Registry 企業級私有鏡像倉庫Harbor管理WEB UI, 可能是最詳細的部署

Docker 部署 SpringBoot 項目整合 Redis 鏡像做訪問計數 Demo

Docker Maven Plugin 生成 Docker 鏡像 push 到 DockerHub上

環境搭建

搭建 Apache RocketMQ 單機環境

手把手教你 MongoDB 的安裝與詳細使用(一)

手把手教你 MongoDB 的安裝與詳細使用(二)

搭建 MongoDB分片(sharding) / 分區 / 集群環境

搭建 SolrCloud 集群服務

搭建 Solr 單機服務

搭建 RabbitMQ 集群服務

搭建 RabbitMQ 單機服務

Mycat 讀寫分離 數據庫分庫分表 中間件 安裝部署,及簡單使用

離線部署 CDH 5.12.1 及使用 CDH 部署 Hadoop 大數據平臺集群服務

Contact

作者:鵬磊

出處:http://www.ymq.io

版權歸作者所有,轉載請注明出處

Wechat:關注公眾號,搜云庫,專注于開發技術的研究與知識分享

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68769.html

相關文章

  • 墻裂推薦:搜云庫技術團隊,面試必備技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    SegmentFault 評論0 收藏0
  • 墻裂推薦:搜云庫技術團隊,面試必備技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    Neilyo 評論0 收藏0
  • 關于生成訂單號規則一些思考

    摘要:關于我為什么寫這篇文章是因為今天在做訂單模塊的時候看到之前的上描述的年月日用戶位企業位四位自增長數。背景對于其定訂單的生成。個人的看法是主要是唯一,其他關于業務方面的不是太太重要。自增實現了用于將的值遞增,并返回結果。 關于我為什么寫這篇文章是因為今天在做訂單模塊的時候,看到之前的PRD上描述的年月日+用戶id2位+企業id位+四位自增長數。然后竟被我反駁的突然改成了精確時間+4位自增...

    omgdog 評論0 收藏0
  • 雪花算法 - snowflake

    摘要:有些時候我們希望能使用一種簡單一些的,并且希望能夠按照時間有序生成。轉換成字符串后長度最多生成的整體上按照時間自增排序,并且整個分布式系統內不會產生碰撞由和作區分,并且效率較高。經測試每秒能夠產生萬個。 概述 分布式系統中,有一些需要使用全局唯一ID的場景,這種時候為了防止ID沖突可以使用36位的UUID,但是UUID有一些缺點,首先他相對比較長,另外UUID一般是無序的。 有些時候我...

    lemon 評論0 收藏0
  • 布式id生成方案概述

    摘要:序本文主要來聊聊分布式的生成方案。分布式的生成,以為代表的,系列算法采用的就是劃分命名空間并行生成的思路。 序 本文主要來聊聊分布式id的生成方案。 目標 業務系統需要什么樣的ID生成器中提出了幾點目標: 唯一性 時間相關 粗略有序 可反解 可制造 主要思路 對于每個標識,都需要有一個命名空間(namespace),來保證其相對唯一性。分布式的ID生成,以Twitter Snowf...

    Terry_Tai 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<