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 相关文章推荐
Redis6.0搭建集群Redis-cluster的方法
May 08 Redis
Redis Cluster 字段模糊匹配及删除
May 27 Redis
5分钟教你docker安装启动redis全教程(全新方式)
May 29 Redis
详解Redis基本命令与使用场景
Jun 01 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
使用redis实现延迟通知功能(Redis过期键通知)
Sep 04 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
分布式架构Redis中有哪些数据结构及底层实现原理
Mar 13 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
屏蔽浏览器缓存另类方法
2006/10/09 PHP
PHP 获取MSN好友列表的代码(2009-05-14测试通过)
2009/09/09 PHP
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
php简单生成随机数的方法
2015/07/30 PHP
PHP 前加at符合@的作用解析
2015/07/31 PHP
javascript字典探测用户名工具
2006/10/05 Javascript
javascript动画效果类封装代码
2007/08/28 Javascript
单独使用CKFinder选择图片的方法
2010/08/21 Javascript
Chosen 基于jquery的选择框插件使用方法
2012/05/30 Javascript
输入自动提示搜索提示功能的javascript:sugggestion.js
2013/09/02 Javascript
Javascript正则控制文本框只能输入整数或浮点数
2014/09/02 Javascript
Bootstrap登陆注册页面开发教程
2016/07/12 Javascript
easyui-combobox 实现简单的自动补全功能示例
2016/11/08 Javascript
拖动时防止选中
2017/02/03 Javascript
angularjs+bootstrap菜单的使用示例代码
2017/03/07 Javascript
微信小程序分享小程序码的生成(带参数)以及参数的获取
2020/03/25 Javascript
vue-cli3 热更新配置操作
2020/09/18 Javascript
python+selenium+autoit实现文件上传功能
2017/08/23 Python
通过Python 接口使用OpenCV的方法
2018/04/02 Python
python实现自动网页截图并裁剪图片
2018/07/30 Python
Python模拟百度自动输入搜索功能的实例
2019/02/14 Python
python定时复制远程文件夹中所有文件
2019/04/30 Python
Python 私有化操作实例分析
2019/11/21 Python
关于pytorch处理类别不平衡的问题
2019/12/31 Python
python实现udp聊天窗口
2020/03/31 Python
pandas中的ExcelWriter和ExcelFile的实现方法
2020/04/24 Python
新加坡最佳婴儿用品店:Mamahood.com.sg
2018/08/26 全球购物
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
Quiksilver荷兰官方网站:冲浪和滑雪板
2019/11/16 全球购物
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
2014年客服工作总结范文
2014/11/13 职场文书
2015年计生协会工作总结
2015/04/24 职场文书
如何写好闭幕词
2019/04/02 职场文书
导游词之重庆钓鱼城
2019/09/19 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
Pytorch中使用ImageFolder读取数据集时忽略特定文件
2022/03/23 Python