当前位置:首页 / 编程技术 / 数据库 / Redis唯一ID生成器的实现
Redis唯一ID生成器的实现
发布时间:2022/07/10来源:编程网

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;


@Component
public class GenerateIDUtil {

  @Autowired
  private RedisTemplate redisTemplate;

   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;
  }


  
  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;
  }


  
  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生成器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

分享到:
免责声明:本文仅代表文章作者的个人观点,与本站无关,请读者仅作参考,并自行核实相关内容。文章内容来源于网络,版权归原作者所有,如有侵权请与我们联系,我们将及时删除。
资讯推荐
热门最新
精品工具
全部评论(0)
剩余输入数量90/90
暂无任何评论,欢迎留下你的想法
你可能感兴趣的资讯
换一批