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实现分布式锁的方法(lua脚本版)
May 12 Redis
浅谈redis整数集为什么不能降级
Jul 25 Redis
缓存替换策略及应用(以Redis、InnoDB为例)
Jul 25 Redis
Redis 常见使用场景
Aug 30 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
解决linux下redis数据库overcommit_memory问题
Feb 24 Redis
Redis 操作多个数据库的配置的方法实现
Mar 23 Redis
一文搞懂Redis中String数据类型
Apr 03 Redis
Grafana可视化监控系统结合SpringBoot使用
Apr 19 Redis
Redis高并发缓存架构性能优化
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调用Google translate_tts api实现代码
2013/08/07 PHP
php stream_get_meta_data返回值
2013/09/29 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
2016/04/01 PHP
PHP实现加密文本文件并限制特定页面的存取的效果
2016/10/21 PHP
PHP插件PHPMailer发送邮件功能
2017/02/28 PHP
Yii实现微信公众号场景二维码的方法实例
2020/08/30 PHP
css图片自适应大小
2007/11/28 Javascript
jQuery+CSS 实现的超Sexy下拉菜单
2010/01/17 Javascript
3款实用的在线JS代码工具(国外)
2012/03/15 Javascript
js解析与序列化json数据(一)json.stringify()的基本用法
2013/02/01 Javascript
Jquery取得iframe下内容的方法
2013/11/18 Javascript
js中reverse函数的用法详解
2013/12/26 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
js读取并解析JSON类型数据的方法
2015/11/14 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
你有必要知道的25个JavaScript面试题
2015/12/29 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
Vue.js开发环境搭建
2016/11/10 Javascript
JavaScript实现垂直滚动条效果
2017/01/18 Javascript
解析jquery easyui tree异步加载子节点问题
2017/03/08 Javascript
浅谈react.js 之 批量添加与删除功能
2017/04/17 Javascript
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
JS的函数调用栈stack size的计算方法
2018/06/24 Javascript
详解vue+webpack+express中间件接口使用
2018/07/17 Javascript
详解vue-router导航守卫
2019/01/19 Javascript
JavaScript 继承 封装 多态实现及原理详解
2019/07/29 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
简单的python协同过滤程序实例代码
2018/01/31 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
Python实现自定义读写分离代码实例
2019/11/16 Python
关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题
2020/11/28 Python
医学生职业规划范文
2014/01/05 职场文书
酒店值班经理的工作职责范本
2014/02/18 职场文书
工作决心书
2014/03/11 职场文书
史上最牛的辞职信
2015/02/28 职场文书