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 相关文章推荐
Windows下redis下载、redis安装及使用教程
Jun 02 Redis
k8s部署redis cluster集群的实现
Jun 24 Redis
使用Redis实现实时排行榜功能
Jul 02 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
Redis RDB技术底层原理详解
Sep 04 Redis
SpringBoot整合Redis入门之缓存数据的方法
Nov 17 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
浅谈Redis跟MySQL的双写问题解决方案
Feb 24 Redis
Redis中有序集合的内部实现方式的详细介绍
Mar 16 Redis
Redis 的查询很快的原因解析及Redis 如何保证查询的高效
Mar 16 Redis
使用Redis做预定库存缓存功能
Apr 02 Redis
Redis 报错 error:NOAUTH Authentication required
May 15 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实现的简单压缩英文字符串的代码
2008/04/24 PHP
利用浏览器的Javascript控制台调试PHP程序
2014/01/08 PHP
PHP中的静态变量及static静态变量使用详解
2015/11/05 PHP
js 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
2009/04/10 Javascript
Jquery工作常用实例 使用AJAX使网页进行异步更新
2011/07/26 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
2012/12/28 Javascript
JS通过相同的name进行表格求和代码
2013/08/18 Javascript
jquery得到font-size属性值实现代码
2013/09/30 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
JS循环遍历JSON数据的方法
2014/07/08 Javascript
HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
2016/01/26 Javascript
node.js入门教程之querystring模块的使用方法
2017/02/27 Javascript
JS中正则表达式全局匹配模式 /g用法详解
2017/04/01 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
2018/05/16 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
ES6实现图片切换特效代码
2020/01/14 Javascript
解决微信授权成功后点击按返回键出现空白页和报错的问题
2020/06/08 Javascript
[01:19]2014DOTA2国际邀请赛 采访TITAN战队ohaiyo 能赢DK很幸运
2014/07/12 DOTA
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
Python实现的双色球生成功能示例
2017/12/18 Python
一行代码让 Python 的运行速度提高100倍
2018/10/08 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
Django model class Meta原理解析
2020/11/14 Python
使用Python+Appuim 清理微信的方法
2021/01/26 Python
有机童装:Toby Tiger
2018/05/23 全球购物
贝斯特韦斯特酒店集团官网:Best Western
2019/01/03 全球购物
颇特女士:NET-A-PORTER(直邮中国)
2020/07/11 全球购物
个人简历自我评价八例
2013/10/31 职场文书
餐厅经理岗位职责范本
2014/02/17 职场文书
公路绿化方案
2014/05/12 职场文书
支部鉴定材料
2014/06/02 职场文书
班组拓展活动方案
2014/08/14 职场文书
社区党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
运动会加油稿
2015/07/22 职场文书