当前位置: 首页 > article >正文

【Redis实现全局唯一ID】

一、全局唯一ID的需求产生。

在订单业务中,我们需要保证id是绝对唯一的。
使用数据库自增长的id在分布式的情况下把表做了拆分处理后有可能会出现id重复的情况,这就违背了唯一性。而且数据自增长的id有很强的规律性,可以根据id推断出订单的数量信息,这也是不安全的。

二、使用redis实现全局唯一ID生成器。

redis可以用作全局唯一ID生成器实现的原因:

  • 递增性:redis本身就采用递增方案。
  • 唯一性:redis是独立于数据库之外的,不论数据库有几张表,redis只有一个,使用incr命令自增是唯一的。
  • 高可用性:redis可以用主从,集群等等方案可以确保它的高可用性。
  • 安全性:使用时间戳进行拼接确保安全性。并且Redis 的自增命令是原子性的,保证了在多线程或多进程并发情况下生成的 ID 的唯一性。
  • 高性能:Redis 是一个基于内存的数据库,读写速度非常快
    在这里插入图片描述
    使用这种拼接方式,前面为31位的时间戳,大约为68年,理论完全可用,但是在高并发的情况下,每秒可能有很多个订单,这种方式支持2^32个订单,完全可用。

代码实现

public class RedisIdWorker {
    /**
     * 开始时间戳
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;//2022年1月1日0时0分0秒对应的时间戳
    /**
     * 序列号的位数
     */
    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"));
        // 2.2.自增长
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 3.拼接并返回
        return timestamp << COUNT_BITS | count;//使用逻辑运算符拼接
    }
}

http://www.kler.cn/a/157696.html

相关文章:

  • Linux lshw命令(lshw指令)(List Hardware,获取底层硬件信息)(查询硬件信息)
  • python中字符串的常用方法
  • PostgreSQL 连接更新操作
  • 京东数据分析(京东数据运营):2023年10月咖啡市场销售数据分析(商家销量销额店铺数据)
  • Flink 读写Doris
  • enum 枚举类型
  • 【openssl】RSA 生成公钥私钥 |通过私钥获取公钥
  • SpringBoot——嵌入式 Servlet容器
  • 如何判别使用的junit是4还是5
  • 树莓派外接上显示器以后一直黑屏无画面显示
  • 流媒体方案之FFmpeg——实现物联网视频监控项目
  • Linux系统安装Python3环境
  • 7、Qt延时的使用
  • 解决 Xshell 无法使用 root 账户远程登录 Linux 的问题
  • ffmpeg格式转换 免费使用视频格式转换教程
  • visual studio 2022中使用vcpkg包管理器
  • Java架构师技术架构路线
  • PTA 7-226 sdut-C语言实验-矩阵输出(数组移位)
  • Mysql内联接inner join以后数据条数比原数据表多
  • 小白备战蓝桥杯:Java常用API