Redis全局ID生成器的实现

 更新时间:2022年06月02日 11:22:23   作者:G_amazing  
全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,本文主要介绍了Redis全局ID生成器的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般满足下列特性:

  • 唯一性:确保ID是唯一的,不可重复
  • 递增性:确保是整体逐渐增大的,这样有利于数据库创建索引
  • 安全性:ID的规律性不是特别的明显,防止根据ID号猜测其他的ID,确保安全性
  • 高性能:确保生成ID的速度足够快
  • 高可用:确保任何时候都能用

实现原理:

为了增加ID的安全性,可以不直接使用Redis自增的数值,而是拼接一些其他的信息,ID的组成如下图:

  • 符号位:1bit,永远为0,表示正数
  •  时间戳:31bit,以秒为单位,可以使用大约69年
  •  序列号:32bit,相同秒数的情况下,ID在序列号位置上增加,支持每秒产生2^32个不同的ID

代码实现:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
 
@Component
public class RedisIdWorker {
 
    /**
     * 开始时间戳 (2022-01-01 00:00:00)
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
 
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;
 
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
 
    /**
     * 生成ID
     *
     * @param keyPrefix 业务系统的前缀
     * @return ID
     */
    public long nextId(String keyPrefix) {
        // 生成时间戳
        long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - BEGIN_TIMESTAMP;
        // 生成序列号
        String key = "icr:" + keyPrefix + ":" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = stringRedisTemplate.opsForValue().increment(key);
        // 拼接并返回
        return timestamp << COUNT_BITS | count;
    }
 
    /**
     * 获取时间戳 (2022-01-01 00:00:00)
     * @param args
     */
    public static void main(String[] args) {
        LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println(second);
    }
}

生成序号:

Redis的自增是有上限的,最大值为2^64。虽然这个数是很大了,但是毕竟还有会有上限,时间足够长还是有可能超过这个数的。所以即使是同一个业务,也不能使用同一个key。因此可以在key中增加日期,比如:icr:业务名:2022:05:14。这样的话每天都会是新的key,每天的自增量不可能超过2^64,所以这样的key是比较合适的选择。

到此这篇关于Redis全局ID生成器的实现的文章就介绍到这了,更多相关Redis全局ID生成器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • Redis使用SETNX命令实现分布式锁

    Redis使用SETNX命令实现分布式锁

    分布式锁是一种用于在分布式系统中控制多个节点对共享资源进行访问的机制,本文主要为大家详细介绍了Redis如何使用SETNX命令实现分布式锁,需要的可以参考下
    2025-01-01
  • 浅谈Redis常见延迟问题定位与分析

    浅谈Redis常见延迟问题定位与分析

    大部分时候,redis延迟很低,但是在某些时刻,有些redis实例会出现很高的响应延时,本文主要介绍了浅谈Redis常见延迟问题定位与分析,具有一定的参考价值,感兴趣的可以了解一下
    2022-06-06
  • Spring Boot中使用Redis常用数据格式API操作技巧

    Spring Boot中使用Redis常用数据格式API操作技巧

    本文介绍了在Spring Boot中使用Redis的一些技巧和数据格式,通过配置Redis连接,可以连接到Redis数据库,结合实例代码介绍的非常详细,需要的朋友参考下吧
    2024-03-03
  • Windows下注册Redis服务失败的解决方案

    Windows下注册Redis服务失败的解决方案

    在Windows系统中,有时候我们需要将Redis作为一个服务运行,以便于在后台长期运行并提供服务,本篇技术博客文章将为你解答在Windows下注册Redis服务失败的一些常见问题,并提供相应的解决方案,需要的朋友可以参考下
    2024-11-11
  • Redis源码环境构建过程详解

    Redis源码环境构建过程详解

    这篇文章主要介绍了Redis源码环境构建过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Redis 的内存淘汰策略和过期删除策略的区别

    Redis 的内存淘汰策略和过期删除策略的区别

    这篇文章主要介绍了Redis 的内存淘汰策略和过期删除策略的区别,Redis 是可以对 key 设置过期时间的,因此需要有相应的机制将已过期的键值对删除,而做这个工作的就是过期键值删除策略
    2022-07-07
  • Redis过期键与内存淘汰策略深入分析讲解

    Redis过期键与内存淘汰策略深入分析讲解

    因为redis数据是基于内存的,然而内存是非常宝贵的资源,然后我们就会对一些不常用或者只用一次的数据进行存活时间设置,这样才能提高内存的使用效率,下面这篇文章主要给大家介绍了关于Redis中过期键与内存淘汰策略,需要的朋友可以参考下
    2022-11-11
  • 如何利用Redis作为Mybatis的二级缓存

    如何利用Redis作为Mybatis的二级缓存

    这篇文章主要介绍了如何利用Redis作为Mybatis的二级缓存,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • Redis 常见缓存问题总结

    Redis 常见缓存问题总结

    这篇文章主要给大家总结了一些Redis 常见缓存问题,并介绍了解决办法,文中的图文示例介绍的非常仔细,感兴趣的同学可以参考阅读下
    2023-06-06
  • 关于Redis最常见的十道面试题总结大全

    关于Redis最常见的十道面试题总结大全

    Redis作为一个高性能的内存数据存储系统,具有快速读写、持久性、数据结构多样性等特点,广泛应用于各种应用场景,这篇文章主要给大家介绍了关于Redis最常见的十道面试题总结的相关资料,需要的朋友可以参考下
    2024-07-07

最新评论