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实现分布式锁的方法(lua脚本版)
May 12 Redis
厉害!这是Redis可视化工具最全的横向评测
Jul 15 Redis
springboot使用Redis作缓存使用入门教程
Jul 25 Redis
Redis入门教程详解
Aug 30 Redis
Redis Stream类型的使用详解
Nov 11 Redis
SpringBoot整合Redis入门之缓存数据的方法
Nov 17 Redis
Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题
Feb 12 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
使用Redis实现点赞取消点赞的详细代码
Mar 20 Redis
Redis如何使用乐观锁(CAS)保证数据一致性
Mar 25 Redis
使用Redis做预定库存缓存功能
Apr 02 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
一个从别的网站抓取信息的例子(域名查询)
2006/10/09 PHP
php时间不正确的解决方法
2008/04/09 PHP
ThinkPHP之getField详解
2014/06/20 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
laravel 如何实现引入自己的函数或类库
2019/10/15 PHP
最近项目写了一些js,水平有待提高
2009/01/31 Javascript
Javascript isArray 数组类型检测函数
2009/10/08 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
JavaScript入门之事件、cookie、定时等
2011/10/21 Javascript
JavaScript常用脚本汇总(一)
2015/03/04 Javascript
常用的Javascript数据验证插件
2015/08/04 Javascript
限制文本框只能输入数字||只能是数字和小数点||只能是整数和浮点数
2016/05/27 Javascript
AngularJS中$watch和$timeout的使用示例
2016/09/20 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
js+canvas实现动态吃豆人效果
2017/03/22 Javascript
windows下更新npm和node的方法
2017/11/30 Javascript
vue下拉菜单组件(含搜索)的实现代码
2018/11/25 Javascript
viewer.js实现图片预览功能
2020/06/24 Javascript
Python将xml和xsl转换为html的方法
2015/03/10 Python
python字符类型的一些方法小结
2016/05/16 Python
python字符串str和字节数组相互转化方法
2017/03/18 Python
Python基于回溯法子集树模板解决全排列问题示例
2017/09/07 Python
numpy中索引和切片详解
2017/12/15 Python
详解Python nose单元测试框架的安装与使用
2017/12/20 Python
pandas把所有大于0的数设置为1的方法
2019/01/26 Python
python粘包问题及socket套接字编程详解
2019/06/29 Python
python各层级目录下import方法代码实例
2020/01/20 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
Python如何把Spark数据写入ElasticSearch
2020/04/18 Python
使用Python快速打开一个百万行级别的超大Excel文件的方法
2021/03/02 Python
HTML5边玩边学(1)画布实现方法
2010/09/21 HTML / CSS
会计专业大学生求职信范文
2014/01/28 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
红与黑读书笔记
2015/06/29 职场文书
python基于tkinter制作下班倒计时工具
2021/04/28 Python
分析ZooKeeper分布式锁的实现
2021/06/30 Java/Android