Java几种分布式全局唯一ID生成方案

yizhihongxing

Java几种分布式全局唯一ID生成方案包括:

  1. 基于UUID的方案

UUID是通用唯一识别码,可以根据时间、硬件等因素生成唯一ID。Java内置了UUID工具类java.util.UUID,使用非常方便。UUID有36个字符,可以通过去除其中的“-”符号,将其减少至32位,降低传输成本。但是,UUID并不是顺序递增的序列,如果需要使用有序递增的ID,则需要结合其他方案使用。

  1. 基于Snowflake算法的方案

Snowflake算法是Twitter开源的算法,可以生成唯一的ID序列。具体实现是将64位的ID分为5个部分:时间戳、数据中心ID、机器ID、序列号。其中时间戳占据了41位,可以使用到2082年,数据中心和机器ID各占5位,可以支持32个数据中心和每个数据中心32台机器,序列号占据了12位,每毫秒可以生成4096个唯一ID。

代码示例如下:

public class IdWorker {
    private long datacenterId;  //数据中心ID
    private long workerId;  //机器ID
    private long sequence = 0L; //序列号
    private long twepoch = 1288834974657L; //时间戳基准值
    private long datacenterIdBits = 5L; //数据中心ID位数
    private long workerIdBits = 5L; //机器ID位数
    private long sequenceBits = 12L; //序列号位数
    private long workerIdShift = sequenceBits; //机器ID左移位数
    private long datacenterIdShift = sequenceBits + workerIdBits; //数据中心ID左移位数
    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; //时间戳左移位数
    private long sequenceMask = ~(-1L << sequenceBits); //序列号掩码
    private long lastTimestamp = -1L; //上次生成ID的时间戳

    public IdWorker(long datacenterId, long workerId) {
        this.datacenterId = datacenterId;
        this.workerId = workerId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时钟回拨的时间太短了");
        }
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        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();
    }
}
  1. 基于Redis的方案

Redis可以作为分布式系统中的数据存储中心,提供全局唯一ID生成的服务。具体实现是使用Redis的原子性操作incr命令,每次请求incr命令都会自动+1,如果设置了过期时间,可以在过期后重置序列号。这种方案需要设置适当的过期时间,以免在系统宕机时导致ID重复。

示例代码如下:

public class RedisIdGenerator {
    private static final String ID_KEY = "my-id-generator";
    private static final int TIMEOUT = 60;
    private RedisTemplate redisTemplate;
    private RedisSerializer keySerializer = new StringRedisSerializer();
    private RedisSerializer valueSerializer = new Jackson2JsonRedisSerializer(Object.class);

    public RedisIdGenerator(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.redisTemplate.setKeySerializer(keySerializer);
        this.redisTemplate.setValueSerializer(valueSerializer);
    }

    public Long nextId() {
        ValueOperations<String, Long> ops = redisTemplate.opsForValue();
        Long id = ops.increment(ID_KEY, 1L);
        if (id == 1L) {
            redisTemplate.expire(ID_KEY, TIMEOUT, TimeUnit.SECONDS);
        }
        return id;
    }
}

以上是Java几种分布式全局唯一ID生成方案的详细讲解,如果有需要可以根据实际情况选择使用其中的一种方案。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java几种分布式全局唯一ID生成方案 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 用SQL实现统计报表中的”小计”与”合计”的方法详解

    下面是使用SQL实现统计报表中的”小计”与”合计”的方法详解: 为什么需要小计和合计? 在统计报表中,通常需要按照某个分类字段(如部门、时间、地区等)进行汇总,同时还需要在每个分类下计算小计和整个报表的合计。小计是指每个分类下的汇总值,合计是指整个报表的汇总值。这样做可以使数据更加清晰明了,方便读者快速了解各项数据的变化趋势和关键指标。 如何使用SQL实现小…

    database 2023年5月21日
    00
  • 详解MySQL AS:设置别名

    MySQL AS是用于给SQL查询结果列、表和子查询设置别名的关键字。AS不是必需的,但它使得查询结果更易于阅读和理解。 AS用法示例: 列别名 在SELECT语句中,使用AS关键字为查询结果列设置别名。例如: SELECT first_name AS given_name, last_name AS family_name FROM customers; …

    MySQL 2023年3月9日
    00
  • SQL中字符串中包含字符的判断方法

    下面是SQL中字符串中包含字符的判断方法的完整攻略: 1. LIKE操作符的使用 在SQL中进行字符串比较时,LIKE操作符是非常常用的一种操作符,用于匹配指定的字符串模式。其中,’%’和’_’是两个特殊的通配符,%表示零个或多个字符,_表示一个字符。通过LIKE操作符,我们可以判断一个字符串中是否包含某个字符。 例如,我们想要查询包含字母’o’的所有单词。…

    database 2023年5月21日
    00
  • 数据库服务器构建和部署检查列表详解

    下面是关于“数据库服务器构建和部署检查列表详解”的完整攻略。 数据库服务器构建和部署检查列表详解 介绍 数据库服务器是非常重要的基础设施之一。为了确保数据库服务器的安全性和稳定性,需要在构建和部署时进行一系列的检查。本文将介绍数据库服务器构建和部署的检查列表。 检查列表 操作系统安装 在安装操作系统时,需要检查以下内容: 确保使用稳定和安全的版本,在服务器操…

    database 2023年5月21日
    00
  • 盘点SqlServer 分页方式和拉姆达表达式分页

    下面是关于“盘点SqlServer 分页方式和拉姆达表达式分页”的完整攻略。 SqlServer 分页方式 SqlServer 分页方式一般使用 OFFSET…FETCH 子句完成,其基本语法如下: SELECT [column1], [column2], … FROM [table_name] ORDER BY [column1] [ASC|DESC]…

    database 2023年5月21日
    00
  • mysql常用日期时间/数值函数详解(必看)

    MySQL常用日期时间/数值函数详解(必看) 日期和时间函数 NOW() NOW() 函数返回当前日期和时间。 示例: SELECT NOW(); 输出: +———————+ | NOW() | +———————+ | 2021-10-27 16:30:53 | +——————-…

    database 2023年5月22日
    00
  • 关于通过java调用datax,返回任务执行的方法

    要通过Java调用DataX并返回任务执行的方法,以下是完整的攻略: 导入DataX依赖 需要在Java项目中添加DataX的依赖,可以通过Maven或者Gradle实现: <dependency> <groupId>com.alibaba</groupId> <artifactId>datax</art…

    database 2023年5月21日
    00
  • MySQL数据定义语言DDL的基础语句

    MySQL数据定义语言(DDL)的基础语句主要包含以下几种: CREATE语句:创建数据库、表、视图、存储过程、函数等对象。 — 创建一个名为example的数据库 CREATE DATABASE example; — 创建一个名为students的表 CREATE TABLE students( id INT PRIMARY KEY, name VAR…

    database 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部