当前位置:网站首页>基於Redis的分布式ID生成器

基於Redis的分布式ID生成器

2022-07-06 12:12:00 阿杆.

基於Redis的分布式ID生成器

ID自增策略

  • 每天一個key,方便統計訂單量
  • ID構造是 時間戳 + 計數器

ID的組成部分

image-20220621171917673

  • 符號比特:1bit,永遠為0
  • 時間戳:31bit,以秒為單比特,從2022年1月開始計數,可以使用68年,也可以根據需求,修改為每分鐘、每小時或每天的計數器,可以增大可用時間。
  • 序列號:32bit,每天的計數器,支持每天產生2^32個不同ID,也可以根據需求,修改為每小時、每分鐘或每秒的計數器,但需要和時間戳相配合,可以增大ID數量。

這裏是以秒為單比特的時間戳和以天為單比特的序列化計數器組成的ID生成器。

package cn.sticki.common.redis.utils;

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

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

/** * @author 阿杆 * @version 1.0 * @date 2022/6/20 20:29 */
@Component
public class RedisIdGenerator {
    

	/** * 開始時間戳 */
	private static final long BEGIN_TIMESTAMP = 1640995200L;

	/** * 序列號的比特數 */
	private static final int COUNT_BITS = 32;

	private final RedisTemplate<String, Long> redisTemplate;

	public RedisIdGenerator(RedisTemplate<String, Long> redisTemplate) {
    
		this.redisTemplate = redisTemplate;
	}

	@SuppressWarnings("ConstantConditions")
	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 獲取redis自增長值
		long increment = redisTemplate.opsForValue().increment("id:" + keyPrefix + ":" + date);

		// 3. 拼接並返回
		return increment << COUNT_BITS | timestamp;
	}

}

其他全局唯一ID生成策略

  • UUID
  • Redis自增
  • snowflake算法
  • 數據庫自增
原网站

版权声明
本文为[阿杆.]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060913400889.html