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 14 Redis
redis哨兵常用命令和监控示例详解
May 27 Redis
浅析Redis Sentinel 与 Redis Cluster
Jun 24 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
redis不能访问本机真实ip地址的解决方案
Jul 07 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
基于Redis结合SpringBoot的秒杀案例详解
Oct 05 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Mar 17 Redis
Redis实现订单过期删除的方法步骤
Jun 05 Redis
关于Redis的主从复制及哨兵问题
Jun 16 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速度全攻略
2006/10/09 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
PHP读取大文件末尾N行的高效方法推荐
2016/06/03 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
2020/03/26 PHP
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
javascript打印大全(打印页面设置/打印预览代码)
2013/03/29 Javascript
JS连接SQL数据库与ACCESS数据库的方法实例
2013/11/21 Javascript
七个很有意思的PHP函数
2014/05/12 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
javascript实现状态栏文字首尾相接循环滚动的方法
2015/07/22 Javascript
javascript基本算法汇总
2016/03/09 Javascript
使用JavaScript实现弹出层效果的简单实例
2016/05/31 Javascript
深入理解JS正则表达式---分组
2016/07/18 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
详解用vue编写弹出框组件
2017/07/04 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
AngularJS实现的base64编码与解码功能示例
2018/05/17 Javascript
vue基于element的区间选择组件
2018/09/07 Javascript
一些你可能不熟悉的JS知识点总结
2019/03/15 Javascript
[58:00]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第二场 2月7日
2021/03/11 DOTA
举例讲解Python中的身份运算符的使用方法
2015/10/13 Python
Using Django with GAE Python 后台抓取多个网站的页面全文
2016/02/17 Python
python Selenium 库的使用技巧
2020/10/16 Python
python字典与json转换的方法总结
2020/12/28 Python
将"引用"作为函数返回值类型的格式、好处和需要遵守的规则
2016/02/09 面试题
西安众合通用.net笔试题
2013/03/18 面试题
机械电子工程毕业生自荐信
2013/11/23 职场文书
关于旅游的活动方案
2014/08/15 职场文书
学习计划书怎么写
2014/09/15 职场文书
中班教师个人总结
2015/02/05 职场文书
幼儿体育课教学反思
2016/02/16 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS