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存储数据类型及存取值方法
May 08 Redis
基于Redis位图实现用户签到功能
May 08 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
Redis做数据持久化的解决方案及底层原理
Jul 15 Redis
关于redisson缓存序列化几枚大坑说明
Aug 04 Redis
redis中lua脚本使用教程
Nov 01 Redis
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
Mar 16 Redis
Redis集群节点通信过程/原理流程分析
Mar 18 Redis
Redis监控工具RedisInsight安装与使用
Mar 21 Redis
浅谈Redis 中的过期删除策略和内存淘汰机制
Apr 03 Redis
浅谈Redis缓冲区机制
Jun 05 Redis
Redis过期数据是否会被立马删除
Jul 23 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发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
php 如何获取数组第一个值
2013/08/06 PHP
php+js实现图片的上传、裁剪、预览、提交示例
2013/08/27 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
情人节专属 纯js脚本1k大小的3D玫瑰效果
2012/02/11 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
2015/03/02 Javascript
js点击返回跳转到指定页面实现过程
2020/08/20 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
vue-ajax小封装实例
2017/09/18 Javascript
layui table 表格模板按钮的实例代码
2019/09/21 Javascript
微信小程序自定义tabbar custom-tab-bar 6s出不来解决方案(cover-view不兼容)
2019/11/01 Javascript
Node Express用法详解【安装、使用、路由、中间件、模板引擎等】
2020/05/13 Javascript
[01:32:50]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第一场 1月25日
2021/03/11 DOTA
python进阶教程之异常处理
2014/08/30 Python
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
在Python中用has_key()方法查找键是否存在的教程
2015/05/21 Python
python解决汉字编码问题:Unicode Decode Error
2017/01/19 Python
python中numpy包使用教程之数组和相关操作详解
2017/07/30 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
2019/06/26 Python
python try except返回异常的信息字符串代码实例
2019/08/15 Python
Python hashlib模块实例使用详解
2019/12/24 Python
Python实现Canny及Hough算法代码实例解析
2020/08/06 Python
中国综合性网上购物商城:当当(网上卖书起家)
2016/11/16 全球购物
专科毕业生自我鉴定
2013/12/01 职场文书
英语自我评价范文
2014/01/24 职场文书
向领导表决心的话
2014/03/11 职场文书
大学竞选班长演讲稿
2014/04/24 职场文书
计算机应用专业毕业生求职信
2014/06/03 职场文书
廉政文化进校园广播稿
2014/10/20 职场文书
国际贸易实训报告
2014/11/05 职场文书
免职通知
2015/04/23 职场文书
读书笔记格式
2015/07/02 职场文书
使用nginx配置访问wgcloud的方法
2021/06/26 Servers
Python使用openpyxl模块处理Excel文件
2022/06/05 Python
Zabbix对Kafka topic积压数据监控的问题(bug优化)
2022/07/07 Servers
html,css,javascript是怎样变成页面的
2023/05/07 HTML / CSS