美文网首页
Redis-全局唯一ID

Redis-全局唯一ID

作者: 石头耳东 | 来源:发表于2022-03-25 22:46 被阅读0次

零、本文纲要

  • 一、全局唯一ID
  • 二、Redis生成全局唯一ID
    1、snowflake算法全局唯一ID策略
    2、Redis自增全局唯一ID策略
  • 三、代码实现

tips:Ctrl + F快速定位所需内容阅读吧。

一、全局唯一ID

1、全局唯一ID特点

  • ① 全局唯一性
  • ② 高性能
  • ③ 单调递增
  • ④ 信息安全
  • ⑤ 高可用

2、全局唯一ID生成策略

  • ① UUID
  • ② Redis自增
  • ③ snowflake算法
  • ④ 数据库自增
  • ⑤ Zookeeper的znode版本生成ID

二、Redis生成全局唯一ID

1、snowflake算法全局唯一ID策略

此处我们参考snowflake算法的ID策略,其具体策略如下:

① 1位,固定位;
② 41位,用来记录时间戳(毫秒),接近69年;
③ 10位,用来记录工作机器id;
④ 12位,序列号,用来记录同毫秒内产生的不同id;

snowflake算法的ID策略.png

2、Redis自增全局唯一ID策略

自定义我们自己的Redis自增的ID策略,具体如下:

① 1位,固定位;
② 31位,用来记录时间戳(秒),接近69年;
③ 32位,序列号,用来记录同一秒内产生的不同id;

Redis自增的ID策略.png

三、代码实现

1、获取开始时间戳

LocalDateTime#of(int year, int month, int dayOfMonth, int hour, int minute, int second)方法,传入自己需要的起始年月日时分秒;

    public static void main(String[] args) {
        LocalDateTime time = LocalDateTime.of(2022,1,1,0,0,0);
        long l = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println(l);
    }

如:2022年1月1日 00点00分00秒,为1640995200L

2、编写ID生成工具类

@Component注解,将工具类注册到Spring容器当中,方便使用;
BEGIN_TIMESTAMP自定义起始的时间戳;
COUNT_BITS位移量,后续拼接全局唯一ID时使用;

@Component
public class RedisIdWorker {

    // 开始时间戳
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    // 位移量
    private static final long COUNT_BITS = 32L;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public long nextId(String keyPrefix){...}

}

timestamp获取当前设置起始时间戳的偏移量;
拼接key,例如:incr:order:20220325;
位运算拼接全局ID,timestamp << COUNT_BITS | count;

    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 currentDate = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        //2.2 自增长
        // 拼接的key,例如:incr:order:20220325
        long count = stringRedisTemplate.opsForValue().increment(
                RedisConstants.INCR_ID
                + keyPrefix
                + RedisConstants.SEPARATE
                + currentDate);

        //3. 拼接并返回
        return timestamp << COUNT_BITS | count;
    }

3、测试生成全局唯一ID

注入RedisIdWorker对象,用于测试;

    @Resource
    private RedisIdWorker redisIdWorker;

编写测试方法:

① 使用线程池模拟并发调用,此处简单处理;

    private ExecutorService es = Executors.newFixedThreadPool(500);

② 使用CountDownLatch控制线程执行;

        CountDownLatch latch = new CountDownLatch(300); //设置300阈值

        Runnable task = () -> {
            ...
            latch.countDown();//每次循环结束,latch -1
        };

        ... //开始时间
        ... //执行任务
        latch.await();//等待直到 latch 变为 0
        ... //结束时间

完整的测试方法如下:

    @Test
    public void testIDWorker() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(300);

        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                long id = redisIdWorker.nextId("order");
                System.out.println(id);
            }
            latch.countDown();
        };

        long begin = System.currentTimeMillis();
        for (int i = 0; i < 300; i++) {
            es.submit(task);
        }
        latch.await();
        long end = System.currentTimeMillis();
        System.out.println("time = " + (end - begin));
    }

四、结尾

以上即为Redis全局唯一ID的基础内容,感谢阅读。

相关文章

  • Redis-全局唯一ID

    零、本文纲要 一、全局唯一ID 二、Redis生成全局唯一ID1、snowflake算法全局唯一ID策略2、Red...

  • 防止mq重复消费

    1. 利用全局唯一id 消息里放入全局唯一id,做完业务后查询id是否存在表里,不存在则将唯一id插入数据库单独...

  • 全局唯一ID

    生成全局唯一ID 通过MySQL的自增主键,作为唯一id; 通过内存中变量AtomicLong的自增来得到唯一id...

  • 全局唯一ID设计

    在分布式系统中,经常需要使用全局唯一ID查找对应的数据。产生这种ID需要保证系统全局唯一,而且要高性能以及占用相对...

  • 全局唯一ID - snowflake

    为什么需要全局唯一ID 比如以下 分布式下唯一ID 如果数据库分了库/表, 那么表的自增主键就不再唯一, 这时候就...

  • 全局唯一ID设计

    一、前言 这周网上的各种瓜真的是吃到肚子里都是水啊。按照惯例周末聊点轻松的,这次我们讲几种全局唯一ID。 平常一些...

  • 04.分布式系统的id生成方式

    分布式ID需要满足那些条件? 全局唯一:必须保证ID是全局性唯一的,基本要求高性能:高可用低延时,ID生成响应要块...

  • 就这?分布式 ID 发号器实战

    分布式 ID 需要满足的条件: 全局唯一:这是最基本的要求,必须保证 ID 是全局唯一的。 高性能:低延时,不能因...

  • 就这?分布式 ID 发号器实战

    分布式 ID 需要满足的条件: 全局唯一:这是最基本的要求,必须保证 ID 是全局唯一的。 高性能:低延时,不能因...

  • 分布式唯一Id(雪花算法),原理+对比+方案

    集群高并发情况下如何保证分布式唯一全局Id生成 为什么需要分布式全局唯一Id,以及分布式Id的业务需求 在复杂分布...

网友评论

      本文标题:Redis-全局唯一ID

      本文链接:https://www.haomeiwen.com/subject/lbadjrtx.html