Redis里头怎么搞自增ID,递增id算法那些事儿浅谈
- 问答
- 2026-01-17 02:06:31
- 1
主要参考了Redis官方文档关于INCR命令的说明、以及多位技术博主如江南一点雨、程序员囧辉等在个人博客上分享的分布式ID生成方案讨论)
在咱们做项目的时候,经常需要给每一条数据一个独一无二的号码,就像身份证号一样,这个就是ID,在单个小数据库里,这个事儿特别简单,让数据库自己往上加1就行了,但一旦系统变大了,数据分散在好多台机器上(这叫分布式系统),再让数据库自己管理自增ID就很容易乱套,比如会出现不同机器上生成了相同ID的尴尬情况。
这时候,Redis就能派上用场了,它有个特别简单的法宝,叫做INCR命令,这个命令是干啥的呢?就是你交给Redis一个钥匙(key),比如叫user:id,然后你每次对这把钥匙执行INCR命令,Redis就会给这个钥匙对应的数字增加1,并且把增加后的结果返回给你,最关键的是,这个操作是“原子性”的,你可以把它想象成一个只能一个人通过的独木桥,同一时刻只允许一个人执行加1操作,这样就不会出现两个人同时拿到同一个号码的情况了,保证了号码的唯一性和顺序递增。
(参考Redis官方文档)具体用起来超级简单,就像下面这样:
你第一次执行 INCR user:id,Redis返回1。
你第二次执行 INCR user:id,Redis返回2。
以此类推,每次都是在上一次的基础上加1。

直接用这个INCR命令来当数据库的主键ID行不行呢?当然可以,这是一种非常直接和简单的做法,如果我们仔细琢磨一下,尤其是在一些要求比较高的生产环境里,可能会发现一些可以优化或者需要注意的地方。
第一点,如果你重启了Redis服务,而这个key没有被持久化保存下来,那么重启后这个key的计数值可能会被重置,如果你希望ID是连续不断掉的,就需要配置好Redis的数据持久化机制(比如RDB快照或者AOF日志),确保这个计数值不会丢。
第二点,如果业务量非常大,所有业务都用一个唯一的key来生成ID,比如就叫global:id,那么这个key可能会成为一个瓶颈,因为所有的请求都盯着这一个key进行操作,为了解决这个问题,可以想一些办法来分散压力,一个常见的办法是使用“分段缓存”的思路,比如说,我们可以不是每次都用INCR取一个ID,而是先用INCR命令一次性申请一个区间范围,比如一下子增加1000,拿到1001到2000这一千个ID号段,然后把这1000个ID放在应用服务的内存里,慢慢分配,等这1000个快用完了,再去Redis申请下一个1000,这样就把对Redis的高频操作,降低成了每1000次请求才需要通信一次,大大减轻了Redis的压力,这种思路在很多大厂的实践中都有应用。

第三点,光有递增的数字可能还不够,我们有时候希望ID里能带上一些额外的信息,Twitter的Snowflake算法就启发了很多人,它生成的ID是一个64位的长整型数字,这个数字被划分成了几个部分:包括时间戳、工作机器ID、序列号等等,这样生成的ID不仅仅是递增的,还能从ID本身解析出是什么时候生成的、是哪台机器生成的这些信息。
那我们能不能用Redis来模仿这种更复杂的ID生成方式呢?当然可以,我们可以利用Redis的INCR特性来辅助生成其中的某些部分,比如说,我们可以设计一个ID结构,前半部分嵌入当前的时间(到天或者到小时),后半部分使用Redis的INCR命令来生成一个当天的自增序列,具体的key可以设计成带日期的,incr:id:20240520,这样,每天的这个key都会从1开始重新计数,生成的ID可能就是 20240520000001 这种格式,这样做的好处是,ID里包含了日期信息,而且同一天内的ID是连续的,看起来也比较直观,不过这种方案也需要考虑Redis的持久化问题,避免日期切换时序列丢失,如果每天凌晨瞬间流量很大,这个带日期的key在零点时可能会成为热点。
还有一种情况,有时候我们可能不希望ID是简单的连续数字,因为连续的ID有时候会暴露业务量(比如从用户ID猜出注册用户数),这时候,我们可以利用Redis生成一个足够大的基数,然后在这个基数上进行一些简单的、可逆的变换,比如按位取反、与固定值异或等,打乱一下顺序,生成一种“看起来无序”但实际递增的ID,这种方式可以在一定程度上避免信息泄露。
Redis通过其INCR命令的原子特性,为分布式系统生成自增ID提供了一个非常强大且简单的基石,从最基础的直接使用,到结合日期、业务前缀的复合键,再到采用号段模式提升性能,甚至模仿Snowflake的思路构造更丰富的ID信息,Redis都能灵活地支持,选择哪种方案,最终取决于项目的具体需求,比如你对性能的要求有多高、ID是否需要包含额外信息、以及对连续性和持久化的保证程度如何,理解了这些“花样”,你就能根据实际情况,用Redis玩转自增ID了。
约1200字)
本文由瞿欣合于2026-01-17发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/82134.html
