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过期事件实现订单超时取消
May 08 Redis
Redis主从配置和底层实现原理解析(实战记录)
Jun 30 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
缓存替换策略及应用(以Redis、InnoDB为例)
Jul 25 Redis
CentOS8.4安装Redis6.2.6的详细过程
Nov 20 Redis
高并发下Redis如何保持数据一致性(避免读后写)
Mar 18 Redis
Redis 异步机制
May 15 Redis
Redis实现订单过期删除的方法步骤
Jun 05 Redis
Redis实现短信验证码登录的示例代码
Jun 14 Redis
redis protocol通信协议及使用详解
Jul 15 Redis
redis lua限流算法实现示例
Jul 15 Redis
基于redis+lua进行限流的方法
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转成EXE文件
2006/10/09 PHP
php.ini中的php-5.2.0配置指令详解
2008/03/27 PHP
PHP读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
php绘图之生成饼状图的方法
2015/01/24 PHP
服务器上配置PHP运行环境教程
2015/02/12 PHP
分享五个PHP7性能优化提升技巧
2015/12/07 PHP
PHP实现的XML操作类【XML Library】
2016/12/29 PHP
Javascript 中的类和闭包
2010/01/08 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
ajax与302响应代码测试
2013/10/23 Javascript
AngularJS入门教程(二):AngularJS模板
2014/12/06 Javascript
HTML5+setCutomValidity()函数验证表单实例分享
2015/04/24 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
深入理解JS DOM事件机制
2016/08/06 Javascript
JS去除重复并统计数量的实现方法
2016/12/15 Javascript
初探js和简单隐藏效果的实例
2017/11/23 Javascript
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
Nuxt项目支持eslint+pritter+typescript的实现
2019/05/20 Javascript
js实现简单的贪吃蛇游戏
2020/04/23 Javascript
Python中统计函数运行耗时的方法
2015/05/05 Python
分享Python文本生成二维码实例
2016/01/06 Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
2018/03/19 Python
对pycharm 修改程序运行所需内存详解
2018/12/03 Python
pandas ix &amp;iloc &amp;loc的区别
2019/01/10 Python
Django框架设置cookies与获取cookies操作详解
2019/05/27 Python
redis数据库及与python交互用法简单示例
2019/11/01 Python
细说CSS3中的选择符
2008/10/17 HTML / CSS
巴黎卡诗美国官方网站:始于1964年的头发头皮护理专家
2017/07/10 全球购物
英国领先的电视购物零售商:Ideal World
2019/03/18 全球购物
Elemental Herbology官网:英国美容品牌
2019/04/27 全球购物
哪些情况下不应该使用索引
2015/07/20 面试题
公司离职证明样本
2014/09/13 职场文书
奠基仪式致辞
2015/07/30 职场文书
python处理json数据文件
2022/04/11 Python