基于redis实现全局ID生成器

全局唯一ID:

全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足以下特征:

  • 唯一性
  • 递增性
  • 安全性
  • 高可用
  • 高性能

全局唯一ID生成策略:

  • UUID
  • Redis自增
  • snowflake算法
  • 数据库自增

Rdeis自增ID策略:

我们这里使用redis自增策略:

  • 每天一个key,方便统计
  • ID构造是 时间戳 + 计数器

代码实现

@Component
public class RedisIdWorker {

    /**
     * 开始时间戳
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;
    @Resource
    private 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 data = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        long count = stringRedisTemplate.opsForValue().increment("id:" + keyPrefix + ":" + data);
        // 3.拼接并返回
        return timestamp << COUNT_BITS | count;
    }
}

测试

使用Springboot测试

	//注解注入工具类
	@Resource
    private RedisIdWorker redisIdWorker;
	//线程池测试
    private final ExecutorService es = Executors.newFixedThreadPool(1000);

    @Test
    public void testRedisIdWorker() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(300);
        //实现Runnable接口定义线程任务
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                long id = redisIdWorker.nextId("test");
                //System.out.println("id==>" + id);
            }
            latch.countDown();
        };
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            es.submit(task);
        }
        latch.await();
        long end = System.currentTimeMillis();
        Thread.sleep(2000);
        System.out.println("time=================" + (end - begin));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值