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

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日

相关文章

  • mysql中索引与FROM_UNIXTIME的问题

    问题描述: 在MySQL中,如果在表中添加了时间列,可以使用FROM_UNIXTIME函数将UNIX时间戳转换为日期格式,但是在加入索引的时候,会遇到一些问题。 解决方案: 为了优化查询速度,我们通常会在表中加入索引。但是,当我们在表中添加时间列,并使用FROM_UNIXTIME函数将UNIX时间戳转换为日期格式时,索引的效率会受到影响。 原因是,MySQL…

    database 2023年5月22日
    00
  • Java面试题冲刺第二十六天–实战编程

    Java面试题冲刺第二十六天的实战编程主要涵盖了将一串字符串进行翻转操作的问题。下面我们将具体讲解该题的攻略。 题目描述 给定一个字符串,将字符串中的每个单词翻转过来。 例子: 输入:”the sky is blue”输出:”blue is sky the” 思路分析 该题解题过程分为以下几步: 将字符串按照空格切分为单个单词,并转化为字符数组。 遍历单个单…

    database 2023年5月18日
    00
  • Mysql数据类型与CRUD操作详细讲解

    Mysql数据类型与CRUD操作详细讲解 MySQL是一种流行的关系型数据库管理系统,常用于访问、存储和管理数据。在使用MySQL时,了解其支持的数据类型和常见的CRUD操作是非常重要的。 Mysql数据类型 MySQL支持多种数据类型,包括数值型、字符型、日期时间型等等。以下是一些常见的数据类型及其用途: INT – 整型数据,用于存储整数。 VARCHA…

    database 2023年5月18日
    00
  • MySQL5.6基本优化配置

    MySQL5.6基本优化配置是数据库性能优化的重要一环,本文将从如下三个方面来进行详细讲解: 硬件选型与参数配置 MySQL参数优化 SQL语句优化 1. 硬件选型与参数配置 1.1 硬件选型 对于MySQL数据库,硬件选型非常重要。基于不同的应用场景,硬件选型的重点也不同,通常需要考虑CPU、内存、磁盘IO性能等因素。 MySQL在CPU的利用上较为看重单…

    database 2023年5月22日
    00
  • java redis 工具类

    1 package com.mohecun.jedis; 2 3 public interface JedisClient { 4 5 String set(String key, String value); 6 String get(String key); 7 Boolean exists(String key); 8 Long expire(Stri…

    Redis 2023年4月11日
    00
  • Docker的MySQL容器时区问题修改

    针对这个问题,我的解决方案如下: 1. 查看MySQL容器的默认时区 首先我们需要确认MySQL容器的默认时区,可以通过以下步骤查看: 进入MySQL容器 docker exec -it mysql_container_name bash 这里的mysql_container_name为你创建的MySQL容器的名称,如果不知道可以通过docker ps命令查…

    database 2023年5月22日
    00
  • 使用shell脚本一键部署LNMP架构的方法

    使用shell脚本一键部署LNMP架构的方法需要以下几个步骤: 1. 安装必要的软件 在使用shell脚本部署LNMP之前,需要安装以下软件:- Git:用于从Github上下载LNMP的脚本文件;- Nginx:用于提供HTTP服务并负责反向代理PHP-FPM;- MySQL:用于存储数据;- PHP:用于解析PHP代码;- PHP-FPM:用于处理PHP…

    database 2023年5月22日
    00
  • 微信小程序云开发如何实现数据库自动备份实现

    下面我将详细讲解微信小程序云开发如何实现数据库自动备份的攻略。具体的实现步骤如下: 创建云函数 在微信开发者工具中,选择云开发选项,然后进入云函数管理页面,点击新建云函数。在云函数配置页面中,我们需要设置云函数的名称、执行环境和上传入口文件等信息。 在入口文件中编写函数代码 “`js const cloud = require(‘wx-server-sdk…

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