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 sentinel 频繁主备切换的问题
Apr 12 Redis
Redis IP地址的绑定的实现
May 08 Redis
详解Redis瘦身指南
May 26 Redis
使用Redis实现实时排行榜功能
Jul 02 Redis
Redis如何实现分布式锁
Aug 23 Redis
解决linux下redis数据库overcommit_memory问题
Feb 24 Redis
Redis 操作多个数据库的配置的方法实现
Mar 23 Redis
Redis批量生成数据的实现
Jun 05 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
利用Redis实现点赞功能的示例代码
Jun 28 Redis
Redis Lua脚本实现ip限流示例
Jul 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中截取字符串支持utf-8
2007/01/18 PHP
解析如何去掉CodeIgniter URL中的index.php
2013/06/25 PHP
ThinkPHP3.1新特性之字段合法性检测详解
2014/06/19 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
使用php-timeit估计php函数的执行时间
2015/09/06 PHP
PHP转换文本框内容为HTML格式的方法
2016/07/20 PHP
PHP基本语法实例总结
2016/09/09 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
Laravel 读取 config 下的数据方法
2019/10/13 PHP
PHP safe_mode开启对于PHP系统函数有什么影响
2020/11/10 PHP
jQuery滚动加载图片效果的实现
2013/03/06 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
jquery预览图片实现鼠标放上去显示实际大小
2014/01/16 Javascript
浅析AngularJS中的生命周期和延迟处理
2015/06/18 Javascript
JavaScript Split()方法
2015/12/18 Javascript
JS动态增删表格行的方法
2016/03/03 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
2016/03/07 Javascript
JS中使用变量保存arguments对象的方法
2016/06/03 Javascript
jQuery插件Validation快速完成表单验证的方式
2016/07/28 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
通过js动态创建标签,并设置属性方法
2018/02/24 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
微信小程序实现抖音播放效果的实例代码
2020/04/11 Javascript
Windows和Linux下使用Python访问SqlServer的方法介绍
2015/03/10 Python
Python编写生成验证码的脚本的教程
2015/05/04 Python
python实现寻找最长回文子序列的方法
2018/06/02 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
Pycharm 2020最新永久激活码(附最新激活码和插件)
2020/09/17 Python
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
贺卡寄语大全
2014/04/11 职场文书
销售行政专员岗位职责
2014/06/10 职场文书
个人遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
开展党的群众路线教育实践活动总结报告
2014/10/31 职场文书
2014年发展党员工作总结
2014/11/12 职场文书
网站文案策划岗位职责
2015/04/14 职场文书
pandas中DataFrame数据合并连接(merge、join、concat)
2021/05/30 Python