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 11 Redis
redis内存空间效率问题的深入探究
May 17 Redis
Redis 配置文件重要属性的具体使用
May 20 Redis
详解Redis瘦身指南
May 26 Redis
Redis缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
Redis分布式锁的7种实现
Apr 01 Redis
Redis中key的过期删除策略和内存淘汰机制
Apr 12 Redis
muduo TcpServer模块源码分析
Apr 26 Redis
Redis实现分布式锁的五种方法详解
Jun 14 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
回答PHPCHINA上的几个问题:URL映射
2007/02/14 PHP
解决css和js的{}与smarty定界符冲突问题的两种方法
2013/09/10 Javascript
用jquery统计子菜单的条数示例代码
2013/10/18 Javascript
Jquery实现图片预加载与延时加载的方法
2014/12/22 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
JS实现霓虹灯文字效果的方法
2015/08/06 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
2016/07/15 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
JavaScript实现经典排序算法之选择排序
2016/12/28 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
2018/07/11 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
简单了解Javscript中兄弟ifream的方法调用
2019/06/17 Javascript
js实现翻牌小游戏
2020/07/31 Javascript
Vue切换Tab动态渲染组件的操作
2020/09/21 Javascript
python根据时间生成mongodb的ObjectId的方法
2015/03/13 Python
Python中使用ElementTree解析XML示例
2015/06/02 Python
使用python加密自己的密码
2015/08/04 Python
Python学习pygal绘制线图代码分享
2017/12/09 Python
快速了解python leveldb
2018/01/18 Python
Django数据库表反向生成实例解析
2018/02/06 Python
python实现任意位置文件分割的实例
2018/12/14 Python
Django框架视图函数设计示例
2019/07/29 Python
Tensorflow实现在训练好的模型上进行测试
2020/01/20 Python
Python基于内置库pytesseract实现图片验证码识别功能
2020/02/24 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
Linux中如何用命令创建目录
2015/01/12 面试题
求职信模板标准格式范文
2014/02/23 职场文书
事业单位分类改革实施方案
2014/03/21 职场文书
重点工程汇报材料
2014/08/27 职场文书
2014年银行年终工作总结
2014/12/19 职场文书
实习介绍信范文
2015/05/05 职场文书
换届选举主持词
2015/07/03 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
初一年级组工作总结
2015/08/12 职场文书
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android