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
详解缓存穿透击穿雪崩解决方案
May 28 Redis
详解Redis复制原理
Jun 04 Redis
redis requires ruby version2.2.2的解决方案
Jul 15 Redis
浅谈redis整数集为什么不能降级
Jul 25 Redis
Redis分布式锁Redlock的实现
Aug 07 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
使用redis生成唯一编号及原理示例详解
Sep 15 Redis
Jedis操作Redis实现模拟验证码发送功能
Sep 25 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
Redis基本数据类型哈希Hash常用操作命令
Jun 01 Redis
Redis keys命令的具体使用
Jun 05 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
用 PHP5 轻松解析 XML
2006/12/04 PHP
Discuz板块横排显示图片的实现方法
2007/05/28 PHP
简单的移动设备检测PHP脚本代码
2011/02/19 PHP
简单的cookie计数器实现源码
2013/06/07 PHP
PHP实现Javascript中的escape及unescape函数代码分享
2015/02/10 PHP
PHP ajax 异步执行不等待执行结果的处理方法
2015/05/27 PHP
PHP PDOStatement::execute讲解
2019/01/31 PHP
javascript判断是否按回车键并解决浏览器之间的差异
2014/05/13 Javascript
微信企业号开发之微信考勤百度地图定位
2015/09/11 Javascript
js中获取键盘事件的简单实现方法
2016/10/10 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
详解Vue的computed(计算属性)使用实例之TodoList
2017/08/07 Javascript
使用nodejs+express实现简单的文件上传功能
2017/12/27 NodeJs
axios的拦截请求与响应方法
2018/08/11 Javascript
node和vue实现商城用户地址模块
2018/12/05 Javascript
在vue中利用v-html按分号将文本换行的例子
2019/11/14 Javascript
[02:12]2015国际邀请赛 SHOWOPEN
2015/08/05 DOTA
python Django连接MySQL数据库做增删改查
2013/11/07 Python
python连接mysql实例分享
2016/10/09 Python
Python Cookie 读取和保存方法
2018/12/28 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
Tensorflow tf.tile()的用法实例分析
2020/05/22 Python
python实现excel公式格式化的示例代码
2020/12/23 Python
HTML5 Canvas像素处理使用接口介绍
2012/12/02 HTML / CSS
LightInTheBox西班牙站点:全球商品在线采购
2016/09/22 全球购物
荷兰优雅女装网上商店:Heine
2016/11/14 全球购物
乐天旅游台湾网站:Rakuten Travel TW
2017/06/01 全球购物
Gina Bacconi官网:吉娜贝康尼连衣裙和礼服
2018/04/24 全球购物
Seavenger官网:潜水服、浮潜、靴子和袜子
2020/03/05 全球购物
线程的基本概念、线程的基本状态以及状态之间的关系
2012/10/26 面试题
副总经理任命书
2014/06/05 职场文书
退休职工欢送会致辞
2015/08/01 职场文书
孕妇病假条怎么写
2015/08/17 职场文书
《山中访友》教学反思
2016/02/24 职场文书
2019XX公司员工考核管理制度!
2019/08/07 职场文书
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android