用Redis咋快速整出独一无二的6位数ID,效率杠杠的那种
- 问答
- 2025-12-29 13:40:46
- 4
最核心、最推荐的方法:用INCR命令
这个方法简单粗暴,但极其有效,它的原理就像是在银行拿号,柜台里只有一个发号员(Redis单线程),你来一个,他给你一个号码,绝对不会给重,具体操作如下:

- 设个起始键:在Redis里,我们设置一个键,比如就叫
unique_id:6digits,它的值我们设置为一个起点数字,100000,为什么不从1开始?因为我们要的是6位数,1是1位数,前面补零虽然可以,但处理起来麻烦,直接从最小的6位数100000开始最省事。 - 发号全靠它:每当你的应用需要一个新的唯一ID时,就向Redis发送一条
INCR unique_id:6digits命令,这个命令的作用是,先获取unique_id:6digits当前的值(比如是100000),然后把这个值增加1(变成100001),最后把这个新值返回给你。 - 拿到就用:你的应用拿到返回的数字,比如100001,这就是你的唯一ID了,下一个应用再来请求,拿到就是100002,依此类推。
为什么这个方法效率杠杠的?
- 原子性:
INCR是原子操作,这是最关键的一点,就算一瞬间有十万个请求同时涌向Redis,Redis也会排着队,一个一个地执行INCR命令,每个命令都是“读-加-写”一气呵成,中间绝不会被其他命令打断,这就从根本上杜绝了重复ID的产生。 - 速度快:Redis本身就是在内存里操作,速度堪比闪电。
INCR又是一个非常简单的命令,没有复杂的计算,所以单机每秒处理几十万次请求跟玩一样。 - 极其简单:代码写起来就一两行,维护起来也轻松,不需要考虑太复杂的东西。
光这样还不够完美,得考虑几个现实问题:

数字一直涨,超过999999怎么办? 6位数最大到999999,如果你业务量超大,这个数字总有一天会用完,解决办法有几种:
- 方案A:循环使用(有风险,不推荐):当
INCR得到的值大于999999时,通过Redis的SET命令强行把它重置回100000。但这样做非常危险! 因为在重置的那一刻,如果还有请求在进来,可能会拿到重复的ID(比如一个请求刚拿到999999,你重置成了100000,下一个请求就拿100000,而100000这个号可能很久以前已经发出去了),除非你能保证在重置期间绝对没有新的请求,这在分布式环境下很难做到。 - 方案B:用更长的位数(推荐):其实没必要非得卡死6位数,你可以一开始就把键的初始值设为更大的数,比如用8位数
10000000,这样可用的ID空间就大大增加,在绝大多数业务场景下,到你公司倒闭可能都用不完,到时候返回的ID虽然是8位,但你可以在应用程序里截取后6位来用(前提是业务能接受后6位唯一的风险,通常可以),这是一种妥协且实用的办法。 - 方案C:结合日期(强烈推荐):这是更高级、更常用的方法,把ID和日期结合起来,你的Redis键可以叫
unique_id:20240520,值是每天从1开始递增,这样,每天的ID序列都是独立的,永远不会超过当天的数量上限,比如今天(20240520)的第一个ID是200001,第二个是200002……明天(20240521)的键变成unique_id:20240521,又从210001开始,这样做的好处是:- 根本解决了上限问题:每天都是新的开始,数字永远涨不满。
- 自带日期信息:从ID里就能看出是哪天生成的,便于数据归档和查询。
- 键不会无限膨胀:旧的日期键可以在一定时间后(比如一个月)删除,节省空间。
Redis挂了怎么办?数据丢了ID不就重复了吗? 是的,如果Redis是单机模式,并且没有开启持久化(RDB或AOF),那么Redis一旦重启,内存数据清空,你重新设置键为100000,就会发出重复的ID。
- 解决办法:必须开启Redis的持久化功能,无论是RDB(定时快照)还是AOF(记录每一条写命令),都能保证在Redis重启后恢复之前的数据状态,这样,即使Redis重启,
unique_id键的值也会恢复到宕机前的最后一个数字,从而避免重复,对于这种绝对不能丢的数据,建议配置为AOF持久化,并且设置appendfsync everysec或appendfsync always(性能会有所下降,但数据更安全)。
能不能更快点?一次多拿几个?
对于极端高并发的场景,频繁地通过网络调用Redis的 INCR 命令,虽然Redis本身扛得住,但网络开销可能会成为瓶颈。
- 解决办法:批量化获取,你可以不用每次要ID都去调Redis,而是通过一个命令,
INCRBY unique_id:6digits 1000,一次性将ID增加1000,然后把当前这1000个ID(比如从100001到101000)的范围一次性拉取到你的应用服务器内存中,之后,应用在需要ID时,直接从内存里分配一个即可,分配完了再去Redis申请下一个批次。 - 好处:极大地减少了网络往返次数,性能提升巨大。
- 注意:如果应用服务器在分配完这1000个ID之前重启了,那么内存中还没分配出去的ID就浪费了,会造成ID号段的中断(即不连续),但在大多数业务中,ID只要唯一就行,不要求绝对连续,所以这个缺点是可以接受的。
总结一下最佳实践:
- 核心命令:坚定不移地用
INCR或INCRBY。 - 解决溢出:采用“日期+序列”的方式设置键名,
unique_id:20240520,一劳永逸。 - 保证安全:务必配置Redis的持久化(AOF推荐),防止宕机后数据丢失导致ID重复。
- 追求极致:在并发量极高的场景下,使用
INCRBY进行号段批量获取,在应用本地分配,将性能压榨到极致。
按照这个路子去弄,你的6位数ID生成器绝对是效率杠杠的,而且稳如老狗。

本文由凤伟才于2025-12-29发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/70679.html
