Redis唯一ID生成器的实现


Posted in Redis onJuly 07, 2022

ID的组成部分:

  • 符号位:1bit,永远为0
  • 时间戳:31bit,以秒为单位,可以使用69年
  • 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID

生成代码:

public class RedisIdWorker {

    /**
     * 开始时间戳
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;
        //构造方法形式注入
    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public long nextId(String keyPrefix){
        //1. 生成时间戳
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;
        //2.生成序列号
        // 2.1 获取当前日期,精确到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
        //3.拼接并返回

        return timestamp << COUNT_BITS | count;
    }
}

PS:Redis实现全局唯一id生成

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

/**
 * 描述:
 * 唯一ID生成器
 * @author jimmy
 * @create 2020-11-06 16:06
 */
@Component
public class GenerateIDUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 生成每天的初始Id
     * @param key
     * @return
     */  public String initPrimaryId(String key) {
        Assert.hasLength(key, "hashName不能为空");
        String hashCol = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        //自定义编号规则
        String hashColVal = hashCol + "00001";
//        redisTemplate.opsForHash().putIfAbsent(hashName, hashCol, hashColVal);

        Long expiresTime = getSecondsNextEarlyMorning();
        redisTemplate.opsForValue().set(key, Long.valueOf(hashColVal), expiresTime, TimeUnit.SECONDS);
        return hashColVal;
    }


    /**
     * 获取分布式Id     
     * @param key
     * @return
     */
    public String getPrimaryId(String key) {

        String id = "";
        if(redisTemplate.hasKey(key)){
            // redisTemplate.opsForValue().get(key);
            // redisTemplate.delete(key);
            id = String.valueOf(redisTemplate.opsForValue().increment(key, 1));
        } else {
            id = initPrimaryId(key);
        }
        return id;
    }


    /**
     * 判断当前时间距离第二天凌晨的秒数
     * @return 返回值单位为[s:秒]
     */
    public Long getSecondsNextEarlyMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }
}

到此这篇关于Redis唯一ID生成器的实现的文章就介绍到这了,更多相关Redis唯一ID生成器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
解决redis sentinel 频繁主备切换的问题
Apr 12 Redis
浅谈redis五大数据结构和使用场景
Apr 12 Redis
基于Redis实现分布式锁的方法(lua脚本版)
May 12 Redis
Redis 配置文件重要属性的具体使用
May 20 Redis
详解Redis复制原理
Jun 04 Redis
浅析Redis Sentinel 与 Redis Cluster
Jun 24 Redis
浅谈Redis中的RDB快照
Jun 29 Redis
springboot使用Redis作缓存使用入门教程
Jul 25 Redis
Redisson实现Redis分布式锁的几种方式
Aug 07 Redis
为什么RedisCluster设计成16384个槽
Sep 25 Redis
详解redis在微服务领域的贡献
Oct 16 Redis
redis缓存存储Session原理机制
Nov 20 Redis
Redis+AOP+自定义注解实现限流
Jun 28 #Redis
利用Redis实现点赞功能的示例代码
Jun 28 #Redis
一文教你快速生成MySQL数据库关系图
Jun 28 #Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 #Redis
浅谈Redis变慢的原因及排查方法
使用Redis实现分布式锁的方法
Jun 16 #Redis
关于Redis的主从复制及哨兵问题
Jun 16 #Redis
You might like
PHP实现文件安全下载
2006/10/09 PHP
怎样在PHP中通过ADO调用Asscess数据库和COM程序
2006/10/09 PHP
探讨如何使用SimpleXML函数来加载和解析XML文档
2013/06/07 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
基于PHP实现的多元线性回归模拟曲线算法
2018/01/30 PHP
JS控件的生命周期介绍
2012/10/22 Javascript
比较新旧两个数组值得增加和删除的JS代码
2013/10/30 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
javascript实现的淘宝旅行通用日历组件用法实例
2015/08/03 Javascript
谈谈javascript中使用连等赋值操作带来的问题
2015/11/26 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
2016/11/20 Javascript
js随机生成一个验证码
2017/06/01 Javascript
如何通过非数字与字符的方式实现PHP WebShell详解
2017/07/02 Javascript
微信小程序中吸底按钮适配iPhone X方案
2017/11/29 Javascript
详细分析vue响应式原理
2020/06/22 Javascript
python函数中return后的语句一定不会执行吗?
2017/07/06 Python
django中forms组件的使用与注意
2019/07/08 Python
python自动识别文本编码格式代码
2019/12/26 Python
Django 后台带有字典的列表数据与页面js交互实例
2020/04/03 Python
基于python实现上传文件到OSS代码实例
2020/05/09 Python
为什么相对PHP黑python的更少
2020/06/21 Python
canvas绘制太极图的实现示例
2020/04/29 HTML / CSS
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
区域总监的岗位职责
2013/11/21 职场文书
电子专业自荐信
2014/07/01 职场文书
竞选大学学委演讲稿
2014/09/13 职场文书
村党建工作汇报材料
2014/11/02 职场文书
中考学习决心书
2015/02/04 职场文书
个人总结怎么写
2015/02/26 职场文书
工程进度款催款函
2015/06/24 职场文书
mysql5.5中文乱码问题解决的有用方法
2022/05/30 MySQL
Redis全局ID生成器的实现
2022/06/05 Redis
Django框架模板用法详解
2022/06/10 Python