Redis全局ID生成器如何实现

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

  • 唯一性:确保ID是唯一的,不可重复

  • 递增性:确保是整体逐渐增大的,这样有利于数据库创建索引

  • Redis全局ID生成器:提高业务可用性的利器

    安全性:ID的规律性不是特别的明显,防止根据ID号猜测其他的ID,确保安全性

  • 高性能:确保生成ID的速度足够快

  • 高可用:确保任何时候都能用

实现原理:

为了提高ID的安全性,可以采用将Redis自增数值与其他信息进行拼接的方式来组成ID,具体组成方式如图所示:

  • 符号位:1bit,永远为0,表示正数

  • 时间戳:31bit,以秒为单位,可以使用大约69年

  • 序列号:32bit,相同秒数的情况下,ID在序列号位置上增加,支持每秒产生2^32个不同的ID

代码实现:

import org.springframework.beans.factory.annotation.Autowired;

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 {

/**
* 开始时间戳 (2022-01-01 00:00:00)
*/
private static final long BEGIN_TIMESTAMP = 1640995200L;


/**
* 序列号的位数
*/
private static final int COUNT_BITS = 32;


@Autowired
private StringRedisTemplate stringRedisTemplate;


/**
* 生成ID
*
* @param keyPrefix 业务系统的前缀
* @return ID
*/
public long nextId(String keyPrefix) {
// 生成时间戳
long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - BEGIN_TIMESTAMP;

// 生成序列号
String key = "
icr:"
+ keyPrefix + "
:"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("
yyyy:MM:dd"
));

long count = stringRedisTemplate.opsForValue().increment(key);

// 拼接并返回
return timestamp <
<
COUNT_BITS | count;

}

/**
* 获取时间戳 (2022-01-01 00:00:00)
* @param args
*/
public static void main(String[] args) {
LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);

long second = time.toEpochSecond(ZoneOffset.UTC);

System.out.println(second);

}
}

生成序号:

Redis的自增是有上限的,最大值为2^64。尽管这个数字很大,但毕竟有一个上限,如果时间足够长,仍有可能超过这个数字。所以即使是同一个业务,也不能使用同一个key。因此可以在key中增加日期,比如:icr:业务名:2022:05:14。以这种方式生成的键每天都会是一个新的键,每天的自增量不会超过2^64,因此这样的键是一个比较合适的选择。



Redis是目前最流行的高性能NoSQL数据库之一,以其快速、易用的优势,被广泛应用于业务系统中。而在这其中,Redis全局ID生成器则是一个备受瞩目的利器。
01.什么是全局ID生成器?
全局ID生成器是为了解决在分布式系统环境下的唯一标识问题而诞生的一种机制。它能够为不同的业务生成唯一性ID,解决分布式系统中数据一致性的问题。
02.全局ID生成器实现方式
全局ID生成器的实现方式有多种,如UUID、Twitter的Snowflake算法等。而Redis则使用的是类似于Snowflake算法的方式。Redis全局ID生成器的算法可以自行根据业务需求定制化,生成的ID可以采用不同的格式,例如:全数字、时间戳与数字组合等形式。
03.Redis全局ID生成器优势
相较于其他的全局ID生成器,Redis全局ID生成器有以下几个优势:
1)性能高 - Redis是内存数据库,比传统的磁盘型数据库更快速,ID生成效率更高。
2)可定制化 - 可按照业务需求设计生成规则。
3)易于部署 - Redis数据库本身即可以作为全局ID生成器所运行,不需要第三方组件或服务器。
04.Redis全局ID生成器使用场景
1)分布式系统 - 在分布式系统中,Redis全局ID生成器能够为不同业务系统生成唯一标识,保障数据一致性。
2)订单生产 - 订单生成是一个需要唯一标识的场景,使用Redis全局ID生成器能够使生成订单号更加可靠。
3)流水号生产 - 在数据记录、流水记录中,使用Redis全局ID生成器能够为数据快速、准确地生成唯一标识,便于管理和追溯。
05.Redis全局ID生成器集群化
在高并发的情况下,单节点Redis全局ID生成器可能会因为线程阻塞导致无法处理 ID 生成的请求,因此需要进行集群化处理。常用的方式有动态分片、HashTag等,达到数据的可靠性、性能的扩展和高可用性等目的。
06.如何保障全局ID的唯一性?
Redis全局ID生成器实现方式中,主键的唯一性需要得到保障。常用的方式有两种:(1)用Redis中的自增方法(例如INCRBY)将ID值递增,保证ID唯一性;(2)记录使用过的ID,判断新生成的ID是否和已有ID重复。
07.总结
Redis全局ID生成器在分布式系统中的应用重要性不言而喻,它的可定制化、易部署、高性能等优势也让这一工具备受关注。我们需要根据业务需求,选择合适的生成算法和部署方式,并保证全局ID的唯一性和集群化处理,提高业务系统的可用性和稳定性。