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集群方案
Jun 21 Redis
聊一聊Redis与MySQL双写一致性如何保证
Jun 26 Redis
在redisCluster中模糊获取key方式
Jul 09 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
关于使用Redisson订阅数问题
Jan 18 Redis
Redis 的查询很快的原因解析及Redis 如何保证查询的高效
Mar 16 Redis
Redis 哨兵机制及配置实现
Mar 25 Redis
基于Redis6.2.6版本部署Redis Cluster集群的问题
Apr 01 Redis
Redis基本数据类型Set常用操作命令
Jun 01 Redis
Redis入门基础常用操作命令整理
Jun 01 Redis
一文教你快速生成MySQL数据库关系图
Jun 28 Redis
基于redis+lua进行限流的方法
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
overlord人气高涨,却被菲利普频繁举报,第四季很难在国内上映
2020/05/06 日漫
PHP 面向对象详解
2012/09/13 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
JS实现打开本地文件或文件夹
2021/03/09 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
js取模(求余数)隔行变色
2014/05/15 Javascript
angular中使用路由和$location切换视图
2015/01/23 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
JS插件overlib用法实例详解
2015/12/26 Javascript
浅析jquery如何判断滚动条滚到页面底部并执行事件
2016/04/29 Javascript
ES6概念 Symbol toString()方法
2016/12/25 Javascript
Bootstrap模态窗口源码解析
2017/02/08 Javascript
微信小程序上传多图到服务器并获取返回的路径
2019/05/05 Javascript
JavaScript Date对象功能与用法学习记录
2020/04/28 Javascript
[01:08:57]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第二场
2014/05/24 DOTA
Python批量更改文件名的实现方法
2017/10/29 Python
给你选择Python语言实现机器学习算法的三大理由
2017/11/15 Python
python smtplib模块自动收发邮件功能(二)
2018/05/22 Python
将Dataframe数据转化为ndarry数据的方法
2018/06/28 Python
python多进程间通信代码实例
2019/09/30 Python
python读取多层嵌套文件夹中的文件实例
2020/02/27 Python
python 连续不等式语法糖实例
2020/04/15 Python
numpy矩阵数值太多不能全部显示的解决
2020/05/14 Python
django Model层常用验证器及自定义验证器详解
2020/07/15 Python
CSS3 @media的基本用法总结
2019/09/10 HTML / CSS
html5 canvas 实现光线沿不规则路径运动
2020/04/20 HTML / CSS
一套PHP的笔试题
2013/05/31 面试题
大学生两会精神学习心得体会
2014/03/10 职场文书
股权转让协议书
2014/04/12 职场文书
留学顾问岗位职责
2014/04/14 职场文书
中国梦演讲稿3分钟
2014/08/19 职场文书
群众路线专项整治方案
2014/10/27 职场文书
员工年终考核评语
2014/12/31 职场文书
办公室个人总结
2015/02/28 职场文书
学者《孟子》名人名言
2019/08/09 职场文书
Go语言切片前或中间插入项与内置copy()函数详解
2021/04/27 Golang