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

24.Redis实现全局唯一ID

是一种分布式系统下用来生成全局唯一ID的工具。

特点

1.唯一性

2.高可用

3.高性能

4.递增性,数据也要保持一种递增,有利于数据库进行查询。

5.安全性

全局唯一ID的生成策略

1.UUID(没有顺序,字符串类型,效率不高)

2.Redis自增

3.snowflake算法

4.数据库自增(单独设计一张表存放多张表的主键id)

Redis自增ID策略

每天一个key,方便统计订单量。

ID构造是时间戳+计数器

package com.xkj.org.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

@Component
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"));
        // 2.2.自增长
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 3.拼接并返回
        // timestamp的值向左移动32位,然后加上count的值
        return timestamp << COUNT_BITS | count;
    }
}
package com.xkj.org;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xkj.org.entity.Shop;
import com.xkj.org.entity.Student;
import com.xkj.org.service.impl.ShopServiceImpl;
import com.xkj.org.utils.CacheClient;
import com.xkj.org.utils.RedisConstants;
import com.xkj.org.utils.RedisIdWorker;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@SpringBootTest
public class SpringBootDataRedisTest {

    @Resource
    private RedisIdWorker redisIdWorker;

    private ExecutorService executorService = Executors.newFixedThreadPool(500);

    @Test
    void testIDWorker() throws InterruptedException {
        long begin = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(300);
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                long orderId = redisIdWorker.nextId("order");
                System.out.println("orderId=="+orderId);
            }
            countDownLatch.countDown();
        };
        for (int i = 0; i < 300; i++) {
            executorService.submit(task);
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("耗费时间:"+(end - begin));

    }
}

因为是多个线程交叉运行,所以输出的结果没有顺序性。其实它是有序的。

产生的id也是long型的。

 可以统计出这一天产生的订单数量。


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

相关文章:

  • Qt 和 WPF(Windows Presentation Foundation)
  • 【Qt】Macbook M1下载安装
  • Vim9 语法高亮syntax 在指定的缓冲区和窗口执行命令
  • 【css】html里面的图片宽度设为百分比,高度要与宽度一样
  • 关于sass在Vue3中编写bem框架报错以及警告问题记录
  • HTML(超文本标记语言)
  • 电脑信息安全:挑战与应对策略
  • PAT甲级-1055 The World‘s Richest
  • 【C++学习入门】6.左值右值
  • 软件测试方法及其应用概述
  • JZ2440开发板——S3C2440的时钟体系
  • RFID射频模块(MFRC522 STM32)
  • Linux 之父 Linus Torvalds:低调的神话创造者
  • 网络协议全景:Linux环境下的TCP/IP、UDP
  • chattr:修改文件的特殊属性
  • Linux抢占调度
  • kali——tshark的使用
  • 2024 批量下载知乎回答/文章/想法/专栏/视频/收藏夹,导出 excel 和 pdf
  • Django_Vue3_ElementUI_Release_004_使用nginx部署
  • idea插件开发的第四天-完善JSON工具
  • 算法:76.最小覆盖子串
  • 文章-深入GPU硬件架构及运行机制 学习后记
  • 撤回仓库的提交
  • 基于SpringBoot实现SpringMvc上传下载功能实现
  • uniapp 如何自定义导航栏并自适应机型
  • 【ESP32】ESP-IDF开发 | 中断矩阵+按键输入中断例程