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 12 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
redis使用不当导致应用卡死bug的过程解析
Jul 01 Redis
Redis集群节点通信过程/原理流程分析
Mar 18 Redis
Redis分布式锁的7种实现
Apr 01 Redis
muduo TcpServer模块源码分析
Apr 26 Redis
Redis 报错 error:NOAUTH Authentication required
May 15 Redis
Redis实现订单过期删除的方法步骤
Jun 05 Redis
Redis实现短信验证码登录的示例代码
Jun 14 Redis
Redis实现分布式锁的五种方法详解
Jun 14 Redis
一文教你快速生成MySQL数据库关系图
Jun 28 Redis
Redis主从复制操作和配置详情
Sep 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中$_GET与$_POST过滤sql注入的方法
2014/11/03 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
2019/09/10 PHP
精通Javascript系列之Javascript基础篇
2011/06/07 Javascript
JavaScript鼠标事件,点击鼠标右键,弹出div的简单实例
2016/08/03 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
3分钟掌握常用的JS操作JSON方法总结
2017/04/25 Javascript
vue-ajax小封装实例
2017/09/18 Javascript
JS实现验证码倒计时的注册页面
2018/01/02 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
react-native 圆弧拖动进度条实现的示例代码
2018/04/12 Javascript
小程序文字跑马灯效果
2018/12/28 Javascript
详解使用React制作一个模态框
2019/03/14 Javascript
js实现简单抽奖功能
2020/11/24 Javascript
详细解读Python中解析XML数据的方法
2015/10/15 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
Python中static相关知识小结
2018/01/02 Python
Python做智能家居温湿度报警系统
2018/09/25 Python
Python绘制并保存指定大小图像的方法
2019/01/10 Python
详解Python匿名函数(lambda函数)
2019/04/19 Python
Python使用selenium + headless chrome获取网页内容的方法示例
2019/10/16 Python
Python hashlib模块加密过程解析
2019/11/05 Python
NumPy排序的实现
2020/01/21 Python
python中执行smtplib失败的处理方法
2020/07/01 Python
自我鉴定注意事项
2014/01/19 职场文书
纠纷协议书
2014/04/16 职场文书
节电标语大全
2014/06/23 职场文书
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
搞笑的婚礼主持词
2015/06/29 职场文书
六一活动主持词
2015/06/30 职场文书
2015年环卫处个人工作总结
2015/07/27 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
Golang原生rpc(rpc服务端源码解读)
2022/04/07 Golang
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
2022/04/21 Python
Python何绘制带有背景色块的折线图
2022/04/23 Python