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三种高可用方式部署的实现
May 11 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
解析Redis Cluster原理
Jun 21 Redis
Redis缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
redis cluster支持pipeline的实现思路
Jun 23 Redis
Redis源码阅读:Redis字符串SDS详解
Jul 15 Redis
Redis模仿手机验证码发送的实现示例
Nov 02 Redis
使用RedisTemplat实现简单的分布式锁
Nov 20 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
Redis特殊数据类型bitmap位图
Jun 01 Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 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 URL路由类实例
2013/11/12 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
2014/05/06 PHP
thinkPHP5.0框架开发规范简介
2017/03/25 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
PHP面向对象程序设计(OOP)之方法重写(override)操作示例
2018/12/21 PHP
jQuery前台数据获取实现代码
2011/03/16 Javascript
CSS(js)限制页面显示的文本字符长度
2012/12/27 Javascript
js实现人才网站职位选择功能的方法
2015/08/14 Javascript
jquery validation验证表单插件
2017/01/07 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
js使用highlight.js高亮你的代码
2017/08/18 Javascript
js获取文件里面的所有文件名(实例)
2017/10/17 Javascript
如何解决React官方脚手架不支持Less的问题(小结)
2018/09/12 Javascript
vue中的router-view组件的使用教程
2018/10/23 Javascript
[28:42]Ti4正赛VG vs NEWBEE1
2014/07/19 DOTA
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
2019/04/28 Python
Python面向对象封装操作案例详解 II
2020/01/02 Python
Pytorch maxpool的ceil_mode用法
2020/02/18 Python
Python虚拟环境的创建和使用详解
2020/09/07 Python
彻底解决Python包下载慢问题
2020/11/15 Python
flask项目集成swagger的方法
2020/12/09 Python
css3实现文字扫光渐变动画效果的示例
2017/11/07 HTML / CSS
丝芙兰波兰:Sephora.pl
2018/03/25 全球购物
英国皇家造币厂:The Royal Mint
2018/10/05 全球购物
美国帽子俱乐部商店:Hat Club
2019/07/05 全球购物
教师评优事迹材料
2014/01/10 职场文书
浙大毕业生自荐信
2014/01/26 职场文书
群教个人对照检查材料
2014/08/20 职场文书
党员群众路线教育实践活动剖析材料
2014/10/10 职场文书
大学新生入学感想
2015/08/07 职场文书
MySQL之MyISAM存储引擎的非聚簇索引详解
2022/03/03 MySQL
css如何把元素固定在容器底部的四种方式
2022/06/16 HTML / CSS
css之clearfix的用法深入理解(必看篇)
2023/05/21 HTML / CSS