Redis全局ID生成器的实现


Posted in Redis onJune 05, 2022

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

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

实现原理:

为了增加ID的安全性,可以不直接使用Redis自增的数值,而是拼接一些其他的信息,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 相关文章推荐
浅谈redis五大数据结构和使用场景
Apr 12 Redis
Redis遍历所有key的两个命令(KEYS 和 SCAN)
Apr 12 Redis
Redis6.0搭建集群Redis-cluster的方法
May 08 Redis
详解Redis主从复制实践
May 19 Redis
Redis Cluster 字段模糊匹配及删除
May 27 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
Redis读写分离搭建的完整步骤
Sep 14 Redis
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Nov 17 Redis
使用Redis做预定库存缓存功能
Apr 02 Redis
浅谈Redis的事件驱动模型
May 30 Redis
一文教你快速生成MySQL数据库关系图
Jun 28 Redis
Redis过期数据是否会被立马删除
Jul 23 Redis
Redis keys命令的具体使用
Jun 05 #Redis
Redis入门基础常用操作命令整理
Jun 01 #Redis
Redis基本数据类型String常用操作命令
Jun 01 #Redis
Redis基本数据类型List常用操作命令
Jun 01 #Redis
Redis基本数据类型Set常用操作命令
Jun 01 #Redis
Redis基本数据类型哈希Hash常用操作命令
Jun 01 #Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 #Redis
You might like
社区(php&amp;&amp;mysql)五
2006/10/09 PHP
BBS(php &amp; mysql)完整版(四)
2006/10/09 PHP
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
php的dl函数用法实例
2014/11/06 PHP
PHP中字符与字节的区别及字符串与字节转换示例
2016/10/15 PHP
PHP设计模式之装饰器模式实例详解
2018/02/07 PHP
尝试动手制作javascript放大镜效果
2015/12/25 Javascript
Javascript 字符串模板的简单实现
2016/02/13 Javascript
基于iscroll.js实现下拉刷新和上拉加载效果
2016/11/28 Javascript
正则中的回溯定义与用法分析【JS与java实现】
2016/12/27 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
2017/06/20 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
详解React Native开源时间日期选择器组件(react-native-datetime)
2017/09/13 Javascript
JavaScript实现音乐自动切换和轮播
2017/11/05 Javascript
vue.js简单配置axios的方法详解
2017/12/13 Javascript
在 webpack 中使用 ECharts的实例详解
2018/02/05 Javascript
Nodejs把接收图片base64格式保存为文件存储到服务器上
2018/09/26 NodeJs
webpack4实现不同的导出类型
2019/04/09 Javascript
简单通过settimeout看javascript的运行机制
2019/05/10 Javascript
12 种使用Vue 的最佳做法
2020/03/30 Javascript
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
python3实现mysql导出excel的方法
2019/07/31 Python
Django实现网页分页功能
2019/10/31 Python
Python 绘制可视化折线图
2020/07/22 Python
使用CSS3制作一个简单的Chrome模拟器
2015/07/15 HTML / CSS
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
工程造价自荐信
2013/10/09 职场文书
护理专业毕业生推荐信
2013/10/31 职场文书
数控专业大学毕业生职业规划范文
2014/02/06 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
植树造林的宣传标语
2014/06/23 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
银行职员工作失误检讨书
2014/10/14 职场文书
企业党支部工作总结2015
2015/05/21 职场文书
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
2022/02/12 Servers
delete in子查询不走索引问题分析
2022/07/07 MySQL