用Redis咋整全局唯一ID,快速拿到不重复的全局编号
- 问答
- 2026-01-19 11:26:51
- 4
关于如何使用Redis来生成全局唯一ID,快速获取不重复的全局编号,这个思路的核心在于利用Redis单线程原子操作的特性和其高性能的特点,下面详细说明几种常见的方法。
核心思想:利用Redis的原子性
最关键的一点是理解为什么Redis能胜任这个工作,Redis是单线程处理命令的,这意味着在任何给定的时刻,只有一个命令会被执行,像INCR(自增)这样的操作是原子性的,不会出现多个客户端同时请求导致编号重复的问题,这是实现全局唯一ID的基础保障。
基本方法:使用INCR命令
这是最简单、最直接的方法,思路是:在Redis中设置一个键(Key),比如叫做global:unique:id,然后每次需要获取新ID时,就对这个键执行INCR命令。
-
操作步骤:
- 首次使用前,可以执行
SET global:unique:id 初始值,比如从10000开始,避免ID过小,如果键不存在,INCR命令会默认从1开始。 - 每当需要一个新ID时,应用程序就向Redis发送一条
INCR global:unique:id命令。 - Redis会将该键的值增加1,并将增加后的新值返回给应用程序,这个返回的值就是全局唯一的ID。
- 首次使用前,可以执行
-
优点:
- 极其简单:实现起来非常快速,几乎不需要额外逻辑。
- 绝对有序:生成的ID是连续的、严格递增的,有利于数据库索引和按时间排序。
-
缺点:
- 暴露信息:ID是连续的,容易被外界猜测出业务量,存在一定的安全风险,通过订单ID可以推算出一天的订单总数。
- 可读性差:如果只用数字,可能不包含其他业务信息。
改进方法:INCRBY + 业务前缀
为了解决基本方法中ID过于简单的问题,可以在应用程序端对Redis返回的数字进行“包装”。

-
操作步骤:
- 仍然使用
INCR命令来获取一个持续增长的基础数字。 - 在应用程序中,将这个数字与一些有意义的字符串拼接起来,形成最终的ID。
- 仍然使用
-
举例:
- 生成订单号:
"ORDER" + 年月日(如20240520) + Redis自增ID(补齐位数)。ORDER20240520000001。 - 生成用户ID:
"UID" + Redis自增ID。
这里,日期部分可以每天清零自增序列,比如键名可以设为
global:unique:id:20240520,这样每天的自增ID都会从1开始,这需要应用程序在生成键名时动态拼接日期。 - 生成订单号:
-
优点:
- 含义清晰:ID中包含了业务类型、日期等信息,一目了然。
- 一定程度上的安全:由于拼接了前缀和日期,单纯的数字序列被隐藏,不易被直接猜测总量。
-
缺点:
- ID长度变长。
- 需要应用程序进行简单的拼接处理。
更复杂的方案:结合时间戳和序列号

这种方法模仿了雪花算法(Snowflake)的思想,但使用Redis来管理序列号部分,生成的ID通常是64位的长整型数字,结构通常为:时间戳 + 数据中心标识 + 机器标识 + 自增序列号。
-
操作步骤:
- 时间戳部分:由应用程序获取当前时间的毫秒数。
- 数据中心和机器ID:提前为不同的服务实例配置好标识,比如机器ID可以是Pod编号、服务器IP尾号等,确保每个实例的标识唯一。
- 序列号部分:这是关键,在Redis中,为同一毫秒内的请求分配自增序号,键名可以设计为
global:unique:id:timestamp,其中timestamp就是当前毫秒时间戳。- 应用程序在生成ID前,先获取当前毫秒时间戳。
- 向Redis发送命令,对键
global:unique:id:[当前毫秒时间戳]执行INCR命令,这个键可以设置一个很短的过期时间(比如1秒),因为它只在当前毫秒内有意义。 - Redis返回当前毫秒内的序列号。
- 应用程序将时间戳(左移若干位)、机器ID(左移若干位)、序列号这三部分通过位运算组合成一个长的64位整数。
-
优点:
- 高性能:在Redis的加持下,每秒可以生成百万级别的ID。
- 趋势递增:由于高位是时间戳,整体ID是随时间变大的,有利于数据库索引。
- 全局唯一:结合了时间、机器、序列号,几乎不可能重复。
- ID长度固定(64位),存储效率高。
-
缺点:
- 实现复杂:需要在应用程序中进行位运算和Redis键的生命周期管理。
- 依赖时钟:如果服务器时钟回拨(时间突然变慢),可能导致生成重复ID,需要额外的机制来处理。
实践中的注意事项
- Redis持久化:为了防止Redis重启后丢失当前的自增计数,需要配置Redis的持久化机制(RDB或AOF),否则重启后ID可能会从初始值重新开始,导致重复。
- 键的命名空间:为不同的业务使用不同的Redis键,订单用
id:order,用户用id:user,避免所有业务共用一个序列导致ID数字过大和不直观。 - 性能考虑:虽然Redis很快,但如果ID生成频率极高(例如每秒数十万次),网络往返也可能成为瓶颈,可以考虑在客户端批量获取一批ID(例如一次性获取1000个ID范围缓存在本地,用完了再取),以减少对Redis的请求次数。
用Redis生成全局唯一ID是一个非常实用且高效的方案,选择哪种方法取决于具体业务需求:
- 如果只需要简单的唯一数字,用 INCR 命令就够了。
- 如果希望ID有更好的可读性,用 INCRBY + 业务前缀。
- 如果追求极致的性能和分布式系统下的高可用,则推荐实现 结合时间戳和序列号 的方案。
(引用来源:Redis官方文档中对INCR命令原子性的说明;分布式系统设计中常见的唯一ID生成方案,如雪花算法;以及普遍的系统架构实践经验。)
本文由畅苗于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/83637.html
