雪花算法工具类介绍

news2024/12/26 9:28:30

在这里插入图片描述

简介

雪花 (SnowFlake )算法是一种分布式唯一ID生成算法,可以生成全局唯一的ID标识符,就像自然界中雪花一般没有相同的雪花。它的核心思想是将一个64位的整数分成4部分,分别是:

1位标识符:即最高位,始终为0,用于区分正数和负数。
41位时间戳:表示生成ID的时间戳,精确到毫秒级别,可以使用69年。
10位数据中心ID:表示数据中心的编号,可以支持1024个数据中心。
12位机器ID:表示机器的编号,可以支持4096台机器。

snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。

在同一毫秒内,不同的机器或数据中心可以生成不同的序列号,通过这种方式保证了生成的ID的唯一性。另外,由于时间戳占据了64位整数的高位部分,因此生成的ID是越来越大的,可以满足一些需要按照时间顺序排序的场景需求。

雪花算法的优点在于:

简单易实现:主要依赖于时间戳、数据中心ID和机器ID三个参数,实现起来比较简单。
唯一性:生成的ID具有全局唯一性,可以满足分布式系统的需求。
时间有序:生成的ID是按照时间有序递增的,可以满足一些需要按照时间顺序排序的场景需求,存入数据库中,索引效率高。。
可扩展性:可以根据需要增加数据中心ID和机器ID的位数,支持更多的数据中心和机器。
高性能高可用:生成时不依赖于数据库,完全在内存中生成。
容量大:每秒中能生成数百万的自增ID。

但是,雪花算法也存在一些缺点:

依赖于系统时钟:如果系统时钟回拨,则可能会生成重复的ID。
数据中心ID和机器ID需要手动分配:需要手动配置数据中心ID和机器ID,不太方便管理。
机器编号有限:12位机器ID只能支持4096台机器,如果需要支持更多的机器,则需要增加机器ID的位数。

综上所述,雪花算法是一种简单易实现、具有唯一性和时间有序性的分布式ID生成算法,适用于分布式系统中的唯一ID标识符的生成。

Java实现

public class Snowflake {
    // 开始时间戳,一般为项目启动时间
    private final long twepoch = 1288834974657L;
    // 机器ID所占的位数
    private final long workerIdBits = 5L;
    // 数据标识ID所占的位数
    private final long datacenterIdBits = 5L;
    // 支持的最大机器ID,结果是31
    private final long maxWorkerId = ~(-1L << workerIdBits);
    // 支持的最大数据标识ID,结果是31
    private final long maxDatacenterId = ~(-1L << datacenterIdBits);
    // 序列号所占的位数
    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
    private final long sequenceMask = ~(-1L << sequenceBits);

    private long workerId; // 机器ID
    private long datacenterId; // 数据标识ID
    private long sequence = 0L; // 序列号
    private long lastTimestamp = -1L; // 上次生成ID的时间戳

    public Snowflake(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;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();

        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; // 序列号重置为0
        }

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

    public static void main(String[] args) {
        Snowflake idWorker = new Snowflake(0, 0);
        for (int i = 0; i < 1000; i++) {
            long id = idWorker.nextId();
            System.out.println(Long.toBinaryString(id));
            System.out.println(id);
        }
    }
}

Java相关工具类

Java版Snowflake开源库比较多,以下是一些常用的开源库及其使用方式:

  1. Twitter的snowflake:是雪花算法最早的Java实现版本,支持高并发、低延迟、高可用等特点。使用方式:

    Snowflake snowflake = new Snowflake(workerId, datacenterId);
    long id = snowflake.nextId();
    
  2. 百度的UidGenerator:是基于Twitter的snowflake算法改进而来的,支持高性能、高可用、高并发等特点。使用方式:

    UidGenerator uidGenerator = UidGenerator.getUidGenerator();
    long id = uidGenerator.getUID();
    
  3. 美团的Leaf:是一款高性能、轻量级的分布式ID生成器,支持多种ID生成算法,包括Snowflake算法。使用方式:

    SegmentIDGenImpl idGen = new SegmentIDGenImpl();
    idGen.init();
    long id = idGen.getId();
    
  4. 阿里巴巴的nacos:是一款轻量级的服务注册与发现工具,其中包含了雪花算法的Java实现版本。使用方式:

    SnowFlake snowFlake = new SnowFlake(dataCenterId, machineId);
    long id = snowFlake.nextId();
    
  5. yitter

  6. hutool工具类

    Snowflake snowflake = IdUtil.getSnowflake(1, 1);
    long id = snowflake.nextId();
    

    在这里插入图片描述

    渺万里层云,千山暮雪,只影向谁去?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/559302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于ERP系统,你可能不知道的10件事

谈到ERP系统&#xff0c;大多数人只是考虑ERP日常管理的核心功能&#xff0c;即财务、销售、采购、库存、生产和分销。保持对这些关键领域的控制对任何企业的成功都是不可或缺的。但这些只是冰山一角&#xff0c;如果深入挖掘ERP系统&#xff0c;你可能会惊讶于它的其他功能。以…

vue3 - 【完整源码】实现容器用鼠标拖曳功能,将容器 “限制在指定范围内“ 鼠标拖拽移动并拿到横纵坐标(详细示例源码及注释,一键复制开箱即用)

效果图 在vue3网页项目中,实现将一个容器设置为鼠标可拖动拖曳效果(并限制在边界内不可拖出去),并且拖拽时自动获取横纵坐标以及相关的事件,基础的示例可自定义为任何你想要的效果。 你可以直接下方效果图的示例源代码,配合详细的原理描述及代码注释保证可用!稍微改改就…

SIEM(安全信息与事件管理)的重要性及 Log360 的卓越功能

摘要&#xff1a;随着网络安全威胁的不断增加&#xff0c;企业和组织对于安全信息与事件管理&#xff08;SIEM&#xff09;解决方案的需求日益迫切。本文将重点介绍 SIEM 的重要性&#xff0c;并详细探讨 ManageEngine 公司旗下的 Log360 解决方案所提供的卓越功能和优势。 引…

胶片打印、排版、自助打印(二)

一、DICOM打印的两种类型 灰度图像打印&#xff1a; 彩色图像打印&#xff1a; 通常情况下RGB类型DICOM图像包含如下的内容&#xff1a; (0028,0010)Rows 图像的高度 (0028,0011)Columns 图像的宽度 (0028,0030)Pixel Spacing 图像像素间距&#xff0c;读取Pixel Data的时候…

Niagara——概述

Niagara是最新一代VFX系统&#xff0c;无需程序员的帮助&#xff0c;即可创建丰富多彩的效果&#xff1b;高级用户还可自定义模块modules&#xff1b; 核心组件 SystemsEmittersModulesParameters systems systems是构建效果容器&#xff0c;创建不同类型效果元素以实现整体效果…

Python从多个表格中随机抽取数据加以处理后合并全部数据

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;基于其中每一个文件&#xff0c;随机从其中选取一部分数据&#xff0c;并将全部文件中随机获取的数据合并为一个新的Excel表格文件的方法。 首先&#xff0c;我们来明确一下本文的具体需求。…

免交互expect

免交互 一、expect1、环境安装2、基本命令2.1 脚本解释器2.2 spawn&#xff08;跟踪&#xff09;2.3 expect &#xff08;捕捉&#xff09;2.4 send&#xff08;发送&#xff09;2.5 结束符2.7 exp_continue2.8 send user2.9 接收参数 二、ssh无交互登录到远程服务器1、登录完成…

Android 自定义弹窗 附带搜索过滤功能

项目场景&#xff1a; 前两天要求在项目中添加个小功能&#xff0c;今天正好有时间随手写了一个小demo&#xff0c;过程分享给大家。以后如果有此类需求可直接移植使用。 需求是因为在下拉列表中选择一个项作为数据显示在界面上&#xff0c;但是所有的选项很多&#xff0c;下翻…

软件著作权容易搞吗?

没有代码、材料&#xff0c;只有一个软件名字就能拿证&#xff0c;你说容易不… 当然这是对我们软著一级代理来说&#xff0c;每年申请下证几千个软著。下面说说下证要点给大家避坑。人群覆盖高新企业、大学生、大学老师、互联网公司。 软件著作权想要轻松下证&#xff0c;必…

《微服务实战》 第十六章 Spring cloud stream应用

前言 https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit 官方定义Spring Cloud Stream是一个构建消息驱动微服务的框架。应用程序通过inputs或者outputs来与Spring Cloud Stream中binder对象交互。通过我们配置来binding(绑定),而Spring Cloud Stream的bin…

lwIP更新记06:申请 TCP 控制块(tcp_alloc)

从 lwIP-2.0.0 开始&#xff0c;申请 tcp_pcb 控制块的逻辑发生了变化。 每个 tcp 连接都必须有一个 PCB 控制块 &#xff0c;使用函数 tcp_new() 申请 PCB 控制块。tcp_new 函数代码如下所示&#xff1a; /*** Creates a new TCP protocol control block but doesnt place it…

进阶篇丨链路追踪(Tracing)很简单:常见问题排查

作者&#xff1a;涯海 经过前面多篇内容的学习&#xff0c;想必大部分同学都已经熟练掌握分布式链路追踪的基础用法&#xff0c;比如回溯链路请求轨迹&#xff0c;定位耗时瓶颈点&#xff1b;配置核心接口黄金三指标告警&#xff0c;第一时间发现流量异常&#xff1b;大促前梳…

公司刚来的测试,00后真卷,上班还没2年,跳到我们公司起薪20k....

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

neo4j图形数据库

目录 1. neo4j简介1.1 什么是图形数据库1.2 什么是neo4j1.3 neo4j的特性1.4neo4j的优点1.5 neo4j的构建元素 2. 安装部署2.1 环境说明2.2 下载安装包2.3 解压安装包2.4 配置安装jdk环境2.5 配置neoj4全局变量2.6 修改neo4j配置文件2.7 服务基本操作2.8 测试访问 3. 使用DBeaver…

上门洗车小程序软件开发所需要的功能有哪些呢?

相信很多企业及投资者都想开发一款属于自己的小程序系统。那么一款专业好用的上门洗车小程序软件开发所需要的功能有哪些呢&#xff1f; 1. 用户注册与登录。 用户可以通过手机号码或微信账号进行注册和登录。注册后可以查看历史订单、评价技师、参加活动等。 …

浅析EasyCVR视频能力在自然灾害风险预警场景中的应用意义

一、方案背景 我国是自然灾害多发的国家&#xff0c;夏季也是灾害多发季节&#xff0c;山洪、泥石流、洪涝、冰雹、飓风、地震等自然灾害每年都给国家经济带来巨大的损失。建设自然灾害风险预警视频监控系统&#xff0c;实现对自然灾害的可视化预警监测和监管&#xff0c;并提…

分布式事务的21种武器 - 2

在分布式系统中&#xff0c;事务的处理分布在不同组件、服务中&#xff0c;因此分布式事务的ACID保障面临着一些特殊难点。本系列文章介绍了21种分布式事务设计模式&#xff0c;并分析其实现原理和优缺点&#xff0c;在面对具体分布式事务问题时&#xff0c;可以选择合适的模式…

【业务架构】业务驱动的推荐系统相关技术总结

什么是推荐系统 推荐系统是一种基于用户历史行为和属性信息为用户推荐个性化内容的技术。而业务驱动的推荐系统&#xff0c;是指根据业务需求&#xff0c;将推荐系统集成进业务流程中&#xff0c;通过推荐系统提高业务效率、提升用户体验等目的。以下是一些相关实现技术。 用户…

Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(一)

今天开始使用 vue3 ts 搭建一个项目管理的后台&#xff0c;因为文章会将项目的每一个地方代码的书写都会讲解到&#xff0c;所以本项目会分成好几篇文章进行讲解&#xff0c;我会在最后一篇文章中会将项目代码开源到我的GithHub上&#xff0c;大家可以自行去进行下载运行&…

C语言隐藏自己源码成lib静态库的和使用lib静态库的方法

首先从头开始创建一个新项目&#xff1a; 这个sub.c内的文件内容很简单&#xff0c;就写一个减法函数 // 定义一个减法函数&#xff0c;传入两个整数&#xff0c;返回差 int sub(int x, int y) { return x - y; } // 定义一个减法函数&#xff0c;传入两个整数&#xff0…