• 雪花算法的使用


    雪花算法的使用(工具类utils)

    1. import org.springframework.beans.factory.annotation.Value;
    2. import org.springframework.stereotype.Component;
    3. // 雪花算法
    4. @Component
    5. public class SnowflakeUtils {
    6. // Generated ID: 1724603634882318341;
    7. // Generated ID: 1724603717312974850
    8. // Generated ID: 1724603717312974851
    9. public static void main(String[] args) {
    10. // 创建一个 SnowflakeUtils 实例
    11. SnowflakeUtils snowflakeUtils = new SnowflakeUtils(1, 1);
    12. // 生成10个唯一ID并打印
    13. for (int i = 0; i < 10; i++) {
    14. long id = snowflakeUtils.nextId();
    15. System.out.println("Generated ID: " + id);
    16. }
    17. }
    18. // 工作机器ID
    19. private final long workerId;
    20. public SnowflakeUtils() {
    21. this.workerId = 1L; // 设置默认值
    22. this.dataCenterId = 1L; // 设置默认值
    23. // 初始化雪花算法实例
    24. }
    25. public SnowflakeUtils(@Value("${snowflake.workerId}") long workerId) {
    26. this.workerId = workerId;
    27. // 初始化雪花算法实例
    28. }
    29. // public SnowflakeUtils(@Value("${snowflake.workerId}") long workerId,@Value("${snowflake.dataCenterId}") long dataCenterId) {
    30. // this.workerId = workerId;
    31. // this.dataCenterId = dataCenterId;
    32. // }
    33. // 起始的时间戳
    34. private final long twepoch = 1288834974657L;
    35. // 机器ID所占的位数
    36. private final long workerIdBits = 5L;
    37. // 数据标识ID所占的位数
    38. private final long dataCenterIdBits = 5L;
    39. // 支持的最大机器ID,结果是31
    40. private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    41. // 支持的最大数据标识ID,结果是31
    42. private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);
    43. // 序列在ID中占的位数
    44. private final long sequenceBits = 12L;
    45. // 机器ID的偏移量(12)
    46. private final long workerIdShift = sequenceBits;
    47. // 数据标识ID的偏移量(12+5)
    48. private final long dataCenterIdShift = sequenceBits + workerIdBits;
    49. // 时间戳的偏移量(12+5+5)
    50. private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
    51. // 生成序列的掩码,这里为4095
    52. private final long sequenceMask = -1L ^ (-1L << sequenceBits);
    53. // 数据中心ID
    54. private long dataCenterId;
    55. // 毫秒内序列
    56. private long sequence = 0L;
    57. // 上次生成ID的时间截
    58. private long lastTimestamp = -1L;
    59. public SnowflakeUtils(long workerId, long dataCenterId) {
    60. if (workerId > maxWorkerId || workerId < 0) {
    61. throw new IllegalArgumentException("workerId can't be greater than " + maxWorkerId + " or less than 0");
    62. }
    63. if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
    64. throw new IllegalArgumentException("dataCenterId can't be greater than " + maxDataCenterId + " or less than 0");
    65. }
    66. this.workerId = workerId;
    67. this.dataCenterId = dataCenterId;
    68. }
    69. // 生成ID
    70. public synchronized long nextId() {
    71. long timestamp = timeGen();
    72. if (timestamp < lastTimestamp) {
    73. throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds.");
    74. }
    75. if (lastTimestamp == timestamp) {
    76. sequence = (sequence + 1) & sequenceMask;
    77. if (sequence == 0) {
    78. timestamp = tilNextMillis(lastTimestamp);
    79. }
    80. } else {
    81. sequence = 0L;
    82. }
    83. lastTimestamp = timestamp;
    84. return ((timestamp - twepoch) << timestampLeftShift) |
    85. (dataCenterId << dataCenterIdShift) |
    86. (workerId << workerIdShift) |
    87. sequence;
    88. }
    89. private long tilNextMillis(long lastTimestamp) {
    90. long timestamp = timeGen();
    91. while (timestamp <= lastTimestamp) {
    92. timestamp = timeGen();
    93. }
    94. return timestamp;
    95. }
    96. private long timeGen() {
    97. return System.currentTimeMillis();
    98. }
    99. }

    调用雪花算法工具类

    long snowflakeUtils= snowflakeUtils.nextId();

    雪花算法(Snowflake Algorithm)是一种用于生成唯一ID的分布式算法。它最初是由Twitter开发的,用于生成分布式系统中的唯一标识符。雪花算法的核心思想是将一个64位的整数ID分成多个部分,每个部分表示不同的信息。

    雪花算法的结构一般包括:

    1. 时间戳(41位): 用于表示生成ID的时间戳,精确到毫秒级别。
    2. 机器ID(10位): 用于标识生成ID的机器,确保每个机器都有唯一的标识符。
    3. 序列号(12位): 在同一毫秒内生成的ID的计数器,确保同一机器同一时间戳内产生不同的ID。

    优点:

    1. 唯一性: 雪花算法生成的ID在分布式系统中是唯一的,不同机器生成的ID不会重复。
    2. 趋势递增: 生成的ID按时间有序递增,有助于提高数据库索引性能。
    3. 分布式: 雪花算法适用于分布式环境,每台机器生成ID不依赖于中心化的资源分配。

    缺点:

    1. 时钟回拨问题: 如果系统时钟发生回拨,可能会导致生成的ID不是严格递增的。
    2. 依赖机器ID: 需要分配唯一的机器ID,可能需要一定的管理和配置。
    3. 有限的并发: 在同一毫秒内生成的ID并发量有限,最多只能生成4096个不同的ID。

    总体来说,雪花算法是一种简单且高效的分布式ID生成方案,但在特定场景下需要注意其一些缺点。后续再补充。

  • 相关阅读:
    kafka修改对应topic的日志保存周期
    EasyExcel导入从第几行开始
    新技术:WEB组态能页面嵌套、属性继承吗?
    达美乐面试(部分)(未完全解析)
    HDF格式遥感影像批量转为TIFF格式:ArcPy实现
    Dijkstra求单源最短路
    U盘恢复怎么做?3个宝藏方法分享!
    Java的设计模式:
    策略路由和路由策略
    Day06-filebeat,logstash多实例,pipline,ElasticStack项目架构梳理及实战案例
  • 原文地址:https://blog.csdn.net/Lantzrung/article/details/134520267