Redis唯一ID生成器的如何实现

六月下雨了,天又下了雨。我已经很久没有见过如此下雨了,柔软而缠绵,就像你的眼睛,轻轻地刷着我寂寞的肩膀。闻一闻书本,站在窗前,对朋友说:早上好!

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;

/**
* 描述:
* 唯一ID生成器
* @author jimmy
* @create 2020-11-06 16:06
*/
@Component
public class GenerateIDUtil {

  @Autowired
  private RedisTemplate redisTemplate;

  /**
  * 生成每天的初始Id
  * @param key
  * @return
  */ 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;
  }


  /**
  * 获取分布式Id  
  * @param key
  * @return
  */
  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;
  }


  /**
  * 判断当前时间距离第二天凌晨的秒数
  * @return 返回值单位为[s:秒]
  */
  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生成器内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能有感兴趣的文章
redis主从哨兵模式如何实现一主二从

k8s部署redis哨兵的如何实现

Redis7.0部署集群的如何实现步骤

如何利用Redis如何实现订单30分钟自动取消

Redis如何实现库存扣减的如何解决方案防止商品超卖