当前位置: 首页 > news >正文

Redis - 全局ID生成器 RedisIdWorker

文章目录

  • Redis - 全局ID生成器 RedisIdWorker
    • 一、引言
    • 二、实现原理
    • 三、代码实现
      • 代码说明
    • 四、使用示例
      • 示例说明
    • 五、总结

Redis - 全局ID生成器 RedisIdWorker

在这里插入图片描述

一、引言

在分布式系统中,生成全局唯一ID是一个常见的需求。传统的自增ID生成方式在分布式环境下容易出现冲突,而UUID虽然可以保证唯一性,但长度较长且不够紧凑。RedisIdWorker是一种基于Redis实现的全局ID生成器,它结合了时间戳和自增序列号,能够在分布式环境中高效地生成唯一且有序的ID。

二、实现原理

RedisIdWorker的核心思想是利用Redis的自增特性和时间戳来生成唯一且有序的ID。其生成的ID由两部分组成:

  1. 时间戳部分:使用当前时间戳减去一个起始时间戳(例如某个特定日期的时间戳),得到一个相对时间戳。时间戳部分通常占用31位,以秒为单位,这样可以保证在69年内生成的ID是唯一的。
  2. 自增序列号部分:使用Redis的INCR命令生成一个自增序列号,确保在相同的时间戳下,ID是唯一的。序列号部分通常占用32位,这意味着每秒可以生成2^32个不同的ID。

在具体实现中,时间戳部分和自增序列号部分通过位运算组合在一起。时间戳部分左移32位,然后与序列号部分进行按位或操作,最终生成一个64位的全局唯一ID。这种设计不仅保证了ID的唯一性,还确保了ID的递增性,有利于数据库索引的创建。

这种实现方式充分利用了Redis的原子操作特性,确保在高并发环境下生成的ID仍然是唯一的。同时,由于时间戳和序列号的结合,生成的ID具有一定的规律性,但又不会直接暴露业务逻辑。

三、代码实现

以下是RedisIdWorker的Java代码实现:

java复制

@Component
public class RedisIdWorker {// 开始时间戳(例如2022年1月1日)private static final long BEGIN_TIMESTAMP = 1640995200L;// 序列号的位数private static final int COUNT_BITS = 32;private StringRedisTemplate stringRedisTemplate;public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}// 获取下一个自动生成的IDpublic long nextId(String keyPrefix) {// 1. 生成时间戳LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIMESTAMP;// 2. 获取当前日期,用于生成keyString date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));// 3. 获取自增序列号long count = stringRedisTemplate.opsForValue().increment("incr:" + keyPrefix + ":" + date);// 4. 拼接并返回IDreturn timestamp << COUNT_BITS | count;}
}

代码说明

  1. 时间戳部分:通过LocalDateTime获取当前时间戳,并减去起始时间戳BEGIN_TIMESTAMP
  2. 自增序列号部分:使用StringRedisTemplateincrement方法,为每个日期生成一个自增序列号。
  3. ID拼接:将时间戳左移32位,然后与序列号进行按位或操作,生成最终的ID。

四、使用示例

以下是一个简单的使用示例:

java复制

@SpringBootTest
public class RedisIdWorkerTest {@Resourceprivate RedisIdWorker redisIdWorker;@Testpublic void testIdWorker() {// 生成订单IDlong orderId = redisIdWorker.nextId("order");System.out.println("Generated Order ID: " + orderId);// 生成用户IDlong userId = redisIdWorker.nextId("user");System.out.println("Generated User ID: " + userId);}
}

示例说明

  • nextId方法接收一个keyPrefix参数,用于区分不同类型的ID(例如订单ID、用户ID等)。
  • 每次调用nextId方法都会生成一个唯一的ID,并且由于时间戳和自增序列号的结合,生成的ID是严格递增的。

五、总结

RedisIdWorker是一种简单高效的全局ID生成器,特别适用于分布式系统。它通过结合时间戳和自增序列号,利用Redis的原子操作保证了ID的唯一性和有序性。在实际项目中,可以根据业务需求调整时间戳的起始值和序列号的位数,以满足不同的场景。


版权声明:本博客内容为原创,转载请保留原文链接及作者信息。

参考文章

  • [Redis - 全局ID生成器 RedisIdWorker - CSDN博客]
  • [Redis - 全局ID生成器 RedisIdWorker本文介绍了分布式系统中的全局ID生成器RedisIdWorke - 掘金]
http://www.lryc.cn/news/532726.html

相关文章:

  • 【Vitest】单元测试
  • 达梦数据库从单主模式转换为主备模式
  • 【Elasticsearch】nested聚合
  • 虹科波形小课堂 | 三分钟掌握车辆相对压缩测试!不拆发动机、不测缸压就能判断故障缸!
  • 【玩转全栈】--创建一个自己的vue项目
  • 基于 Spring Cloud + Spring AI + VUE 的知识助理平台介绍以及问题
  • < 自用文儿 > 下载 MaxMind GeoIP Databases 对攻击的 IP 做 地理分析
  • 前端知识速记:重绘和回流
  • webrtc peerconnection_client peerconnection_server 连接失败问题解决 win10 win11
  • 【C++】STL——list的使用与底层实现
  • iOS 音频录制、播放与格式转换
  • 【PyTorch】解决Boolean value of Tensor with more than one value is ambiguous报错
  • Jsoup库具体怎么用?
  • python:如何播放 .spx 声音文件
  • HTML学习笔记(6)
  • 走向基于大语言模型的新一代推荐系统:综述与展望
  • 【DeepSeek-R1 +1.5B】2060显卡ollama本地部署+open-webui界面使用
  • 《翻转组件库之发布》
  • 在深度学习中,样本不均衡问题是一个常见的挑战,尤其是在你的老虎机任务中,某些的中奖倍数较高
  • 语言月赛 202311【基因】题解(AC)
  • unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键
  • GB/T 43698-2024 《网络安全技术 软件供应链安全要求》标准解读
  • ASP.NET Core与EF Core的集成
  • 【AI大模型】Ubuntu18.04安装deepseek-r1模型+服务器部署+内网访问
  • SpringAI系列 - 使用LangGPT编写高质量的Prompt
  • Github - 记录一次对“不小心包含了密码的PR”的修复
  • 【玩转 Postman 接口测试与开发2_014】第11章:测试现成的 API 接口(下)——自动化接口测试脚本实战演练 + 测试集合共享
  • 前后端通过docker部署笔记
  • 五十天精通硬件设计第四天-场效应管知识及选型
  • 了解 ALV 中的 field catalog (ABAP List Viewer)