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配置文件中常用配置详解
Apr 14 Redis
浅谈Redis存储数据类型及存取值方法
May 08 Redis
redis实现的四种常见限流策略
Jun 18 Redis
解析Redis Cluster原理
Jun 21 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
redis cluster支持pipeline的实现思路
Jun 23 Redis
redis的list数据类型相关命令介绍及使用
Jan 18 Redis
redis数据结构之压缩列表
Mar 21 Redis
Grafana可视化监控系统结合SpringBoot使用
Apr 19 Redis
Redis特殊数据类型HyperLogLog基数统计算法讲解
Jun 01 Redis
Redis基本数据类型Set常用操作命令
Jun 01 Redis
利用Redis实现点赞功能的示例代码
Jun 28 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
Discuz 模板引擎的封装类代码
2008/07/18 PHP
编译PHP报错configure error Cannot find libmysqlclient under usr的解决方法
2014/06/27 PHP
PHP中使用TCPDF生成PDF文档实例
2014/07/01 PHP
PHP树的深度编历生成迷宫及A*自动寻路算法实例分析
2015/03/10 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
js 函数的副作用分析
2011/08/23 Javascript
jquery easyui combobox模糊过滤(示例代码)
2013/11/30 Javascript
让input框实现类似百度的搜索提示(基于jquery事件监听)
2014/01/31 Javascript
再探JavaScript作用域
2014/09/24 Javascript
jQuery实现按键盘方向键翻页特效
2015/03/18 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
纯js模拟div层弹性运动的方法
2015/07/27 Javascript
ES6的新特性概览
2016/03/10 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
Vue-路由导航菜单栏的高亮设置方法
2018/03/17 Javascript
vue实现点击按钮下载文件功能
2019/10/11 Javascript
Vue数据双向绑定原理实例解析
2020/05/15 Javascript
Vue中父子组件的值传递与方法传递
2020/09/28 Javascript
[05:59]带你看看DPC的台前幕后
2021/03/11 DOTA
python中list常用操作实例详解
2015/06/03 Python
Python 3中print函数的使用方法总结
2017/08/08 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
python绘制简单彩虹图
2018/11/19 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
Python实现的微信支付方式总结【三种方式】
2019/04/13 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
Keras实现将两个模型连接到一起
2020/05/23 Python
Html5 APP中监听返回事件处理的方法示例
2018/03/15 HTML / CSS
Penhaligon’s英国官网:成立于1870年的英国香水制造商
2021/02/18 全球购物
大学生社会实践评语
2014/04/25 职场文书
个人房屋转让协议书范本
2014/10/26 职场文书
小学班主任个人总结
2015/03/03 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
大学生受助感言
2015/08/01 职场文书
2016新年感言
2015/08/03 职场文书
Spring Data JPA的Audit功能审计数据库的变更
2021/06/26 Java/Android