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
详解Redis实现限流的三种方式
Apr 27 Redis
Java Socket实现Redis客户端的详细说明
May 26 Redis
详解Redis基本命令与使用场景
Jun 01 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
压缩Redis里的字符串大对象操作
Jun 23 Redis
Redis 彻底禁用RDB持久化操作
Jul 09 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
Redis中key的过期删除策略和内存淘汰机制
Apr 12 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis唯一ID生成器的实现
Jul 07 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
利用 window_onload 实现select默认选择
2006/10/09 PHP
使用PHP实现二分查找算法代码分享
2011/06/24 PHP
PHP判断文件是否存在、是否可读、目录是否存在的代码
2012/10/03 PHP
php使用cookie实现记住登录状态
2015/04/27 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
PHP Pipeline 实现中间件的示例代码
2020/04/26 PHP
javascript mouseover、mouseout停止事件冒泡的解决方案
2009/04/07 Javascript
javascript window对象属性整理
2009/10/24 Javascript
jQuery三级下拉列表导航菜单代码分享
2020/04/15 Javascript
基于React.js实现原生js拖拽效果引发的思考
2016/03/30 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
jQuery表单元素选择器代码实例
2017/02/06 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
vue-cli中的webpack配置详解
2017/09/25 Javascript
Vue Router去掉url中默认的锚点#
2018/08/01 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
javascript头像上传代码实例
2019/09/28 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
2019/10/23 Javascript
基于ts的动态接口数据配置的详解
2019/12/18 Javascript
JavaScript监听键盘事件代码实现
2020/06/03 Javascript
Vue实现移动端拖拽交换位置
2020/07/29 Javascript
[01:03:37]Secret vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
Hadoop中的Python框架的使用指南
2015/04/22 Python
python实现寻找最长回文子序列的方法
2018/06/02 Python
python爬虫解决验证码的思路及示例
2019/08/01 Python
python django 原生sql 获取数据的例子
2019/08/14 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
意大利珠宝店:Luxury Zone
2019/01/05 全球购物
大学秋游活动方案
2014/02/11 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
干货分享:推荐信写作技巧!
2019/06/21 职场文书
python实现语音常用度量方法的代码详解
2021/05/25 Python
CSS实现背景图片全屏铺满自适应的3种方式
2022/07/07 HTML / CSS