实现高性能ID生成器:详解Java雪花算法

这篇具有很好参考价值的文章主要介绍了实现高性能ID生成器:详解Java雪花算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java中的雪花算法(Snowflake Algorithm)是一种用于生成唯一ID的算法,可以在分布式系统环境中防止ID重复。这种算法最初由Twitter开发,用于生成Twitter的唯一ID,由于其简单易懂和高效,已成为目前最常用的生成唯一ID的算法之一。

雪花算法生成的ID是一个64位的长整型数字,可以分为四个部分:

  1. 符号位(始终为0,占用1位)。
  2. 时间戳(毫秒级,占用41位),可以用的年限约69年。
  3. 数据中心ID(可以定义具体数据中心ID的位数,占用5位),用于区分不同的数据中心。
  4. 工作机器ID(可以定义具体工作机器ID的位数,占用5位),用于区分不同的工作机器。

以下是Java实现的基本流程:

  1. 获得时间戳,精确到毫秒级。
  2. 将所有位数的值全部初始化为0。
  3. 填充时间戳,对应41位。
  4. 填充数据中心ID,根据自身需求设置位数。
  5. 填充工作机器ID,根据自身需求设置位数。
  6. 填充序列号,一般使用一个计数器,生成一系列自增的整数。
  7. 将上述所有部分组合成一条64位的长整型数字,即为唯一ID,生成完成。

以下是一个Java实现的示例代码:

public class SnowFlake {

    // 起始的时间戳
    private final static long START_TIMESTAMP = 1480166465631L;

    // 每一部分占用的位数,符号位不算在内
    private final static long SEQUENCE_BIT = 12; // 序列号占用的位数
    private final static long MACHINE_BIT = 5; // 机器标识占用的位数
    private final static long DATACENTER_BIT = 5; // 数据中心占用的位数

    // 每一部分的最大值
    private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
    private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
    private final static long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);

    // 每一部分向左的位移
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTAMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;

    private long datacenterId; // 数据中心
    private long machineId; // 机器标识
    private long sequence = 0L; // 序列号
    private long lastTimestamp = -1L;// 上一次时间戳

    public SnowFlake(long datacenterId, long machineId) {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
            throw new IllegalArgumentException("Datacenter ID can't be greater than MAX_DATACENTER_NUM or less than 0");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException("Machine ID can't be greater than MAX_MACHINE_NUM or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    /**
     * 产生下一个ID
     *
     * @return 下一个ID
     */
    public synchronized long nextId() {
        long currTimestamp = getTimestamp();
        if (currTimestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate id");
        }

        // 如果是同一时间生成的,则进行毫秒内序列
        if (currTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            // 序列号已经达到最大值,下一个毫秒
            if (sequence == 0L) {
                currTimestamp = getNextTimestamp();
            }
        } else {
            // 时间戳改变,毫秒内序列重置
            sequence = 0L;
        }

        // 上次生成ID的时间截
        lastTimestamp = currTimestamp;

        // 移位并通过或运算拼到一起组成64位的ID
        return (currTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT // 时间戳部分
                | datacenterId << DATACENTER_LEFT // 数据中心部分
                | machineId << MACHINE_LEFT // 机器标识部分
                | sequence; // 序列号部分
    }

    /**
     * 获取下一个毫秒数
     *
     * @return 下一个毫秒数
     */
    private long getNextTimestamp() {
        long timestamp = getTimestamp();
        while (timestamp <= lastTimestamp) {
            timestamp = getTimestamp();
        }
        return timestamp;
    }

    /**
     * 获取当前的时间戳
     *
     * @return 当前的时间戳
     */
    private long getTimestamp() {
        return System.currentTimeMillis();
    }

    public static void main(String[] args) {
        SnowFlake snowFlake = new SnowFlake(1, 1);

        long startTime = System.nanoTime();

        for (int i = 0; i < 1000000; i++) {
            System.out.println(snowFlake.nextId());
        }

        long endTime = System.nanoTime();

        System.out.println("用时:" + (endTime - startTime) / 1000000 + "ms");
    }
}

在以上示例代码中,SnowFlake类的构造函数接收数据中心ID和机器ID作为参数,用户可以根据自己的业务需求设置不同的数值。nextId()方法用于生成雪花算法的唯一ID。

除此之外,为了防止时间回退的情况,采用了getNextTimestamp()方法来获得下一个合法的时间戳。可以看到,这是一种高效、易扩展、高可用的算法,适合于生成分布式系统下唯一的ID。

 文章来源地址https://www.toymoban.com/news/detail-426515.html

到了这里,关于实现高性能ID生成器:详解Java雪花算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • zookeeper应用场景之分布式的ID生成器

    zookeeper应用场景之分布式的ID生成器

            在分布式系统中, 分布式ID生成器的使用场景非常之多 : 大量的数据记录,需要分布式ID。 大量的系统消息,需要分布式ID。 大量的请求日志,如restful的操作记录,需要唯一标识,以便进行后续的用户行为分析和调用链路分析。 分布式节点的命名服务,往往也

    2024年01月23日
    浏览(17)
  • 【Spring Boot 3】【Redis】分布式唯一ID生成器

    软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或少的时间、检索不止一篇资料才能得出一个可工作的DEMO,这占用了我大量的时

    2024年01月20日
    浏览(8)
  • 对于现有的分布式id发号器的思考 id生成器 雪花算法 uuid

    目录 雪花id tinyid uuid 分布式id特点 业务编号 数据中心编号 当前时间 ip地址 当前序号 对于时钟回拨问题 发号器机器当期时间小于redis的时间 解决步骤 发号器机器当期时间等于redis时间 发号器机器当期时间大于redis最大的时间(相关的key不存在) 分布式id的单次获取和批次获

    2024年02月13日
    浏览(8)
  • 一文读懂Stable Diffusion教程,搭载高性能PC集群,实现生成式AI应用

    图生图 | PC集群 | PC Farm | Stable 文生图 | 生成式AI | Stable Diffusion 在当今计算领域中,PC集群和Stable Diffusion技术的应用已经成为不可或缺的一部分。这些技术在深度学习、AI绘画、高性能计算、人工智能、大数据、ChatGPT、AIGC等领域中都具有重要的应用价值。特别是在AI生成式内

    2024年02月10日
    浏览(8)
  • 开箱即用轻量级雪花算法id生成器Java工具类

    在 Java后端研发过程中,对于分布式微服务来说,一般需要分布式 id生成. 这里分享一个非常好用且大多数情况下都可用的开箱即用轻量级雪花算法id生成器Java工具类。 这种方式生成的雪花算法生成器生成的唯一主键id,好处是不依赖第三方组件,轻量级,缺点是服务器的时钟

    2024年02月07日
    浏览(6)
  • Python中的迭代器与生成器提高性能的秘密武器【第143篇—迭代器与生成器】

    Python中的迭代器与生成器提高性能的秘密武器【第143篇—迭代器与生成器】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Python编程中,迭代器和生成器是提高性能和减少内存消耗的重要工具。它们不仅简化了代码结构,而且在处理大型数据集时具有明显的优势

    2024年03月24日
    浏览(11)
  • 高性能渲染——详解Html Canvas的优势与性能

    高性能渲染——详解Html Canvas的优势与性能

    本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 一、什么是Canvas 想必学习前端的同学们对Canvas 都不陌生,它是 HTML5 新增的“画布”元素,可以使用JavaScript来绘制图形。 Canvas元素是在

    2024年02月06日
    浏览(8)
  • Python asyncio高性能异步编程 详解

    Python asyncio高性能异步编程 详解

    目录 一、协程 1.1、greenlet实现协程 1.2、yield 1.3、asyncio 1.4、async await 二、协程意义 三、异步编程 3.1、事件循环 3.2、快速上手 3.3、await 3.4、Task对象 3.5、asyncio.Future对象 3.5、concurrent.futures.Future对象 3.7、异步迭代器 3.8、异步上下文管理器 四、uvloop 五、实战案例

    2024年02月20日
    浏览(13)
  • 详解Python中的排列组合生成器

    在实际的开发场景中,经常需要遍历多个数组中的元素,将它们组合在一起使用。要取完所有可能的组合,最基本的方法是使用嵌套的循环,有多少个数组就嵌套多少层循环。嵌套循环是基本的原理,但不够简洁,Python中有更优雅的方式来实现这种功能。 在Python的内置模块

    2024年02月10日
    浏览(8)
  • 【沐风老师】3DMAX宇宙生成器(一键生成星系)插件使用方法详解

    【沐风老师】3DMAX宇宙生成器(一键生成星系)插件使用方法详解

    3DMAX宇宙生成器(一键生成星系)插件  3DMAX宇宙生成器(一键生成星系)插件,用于模拟星团及星系的运动。可以创建单个集合进行动画计算,也可以输入不同坐标,建立多个集合后统一进行动画计算。 【安装方法】 无需安装,使用时直接拖动插件文件到3dMax视口打开即可

    2024年02月08日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包