全局 ID

一、什么是全局 ID?

一句话:

全局唯一 ID = 整个系统里永远不会重复的 ID。

不管多少台服务器、多少张表、多少服务,生成出来的 ID 都绝对不重复

比如:

  • 订单 ID
  • 优惠券 ID
  • 用户 ID
  • 流水号

这些都必须全局唯一,不能重复。

二、为什么需要全局 ID?(你写的那两个问题是核心)

你学习笔记里写的两点,就是分布式系统必须用全局 ID 的真正原因

1. 数据库自增 ID 不安全、规律太明显

如果订单 ID 是:

101、102、103、104...

别人一看就能猜到:

  • 今天卖了多少单
  • 总订单量多少
  • 商业机密直接暴露

全局 ID 是乱序的,别人猜不到。

2. 分库分表后,数据库自增 ID 会重复

比如:

  • 订单表 1 自增到 100
  • 订单表 2 自增也到 100

那就出现两个订单 ID = 100

系统直接乱套!

所以必须用全局唯一 ID

三、全局 ID 怎么生成?(你给的 Redis 实现就是最经典方案)

你代码里的 Redis 生成方案,结构是:

plaintext

全局ID = 符号位(0) + 时间戳(31位) + 序列号(32位)

1. 时间戳(31 位)

从一个固定时间开始算(比如 2022-01-01)

每秒一个数字,能用 69 年

作用:保证不同时间生成的 ID 一定不重复

2. 序列号(32 位)

Redis 里执行:

java

运行

stringRedisTemplate.opsForValue().increment(键);

Redis 自增是原子性的,并发再高也不会重复。

一秒钟最多能生成 2^32 = 42 亿 个 ID,完全够用。

四、最终 ID 怎么拼出来的?(核心代码解释)

java

运行

return timestamp << 32 | count;

这句就是拼接全局 ID的核心:

  1. timestamp << 32把时间戳往左移 32 位给后面的序列号腾出位置
  2. | count把 时间戳 和 序列号 按位合并变成一个唯一的 long 数字

最终效果:

时间戳不同 → ID 不同

时间戳相同 → 序列号不同 → ID 也不同

所以永远不会重复!

五、这个 Redis 全局 ID 有什么好处?

  1. 绝对不重复
  2. 高并发性能极高
  3. 不依赖数据库
  4. 分库分表也能用
  5. ID 无规律,安全
  6. 自带时间顺序
  7. 可以按天统计数量(因为 key 里带日期)

六、怎么使用这个全局 ID?(超简单)

你在代码里需要生成订单 ID 时,直接写:

java

运行

long orderId = redisIdWorker.nextId("order");

生成优惠券 ID:

java

运行

long voucherId = redisIdWorker.nextId("voucher");

生成用户 ID:

java

运行

long userId = redisIdWorker.nextId("user");

不同业务用不同前缀,互不干扰。

七、测试代码里的 CountDownLatch 是什么?

你笔记里写的:

CountDownLatch = 主线程等所有子线程执行完再结束

作用:

  • 开 500 个线程
  • 每个线程生成 100 个 ID
  • 主线程必须等全部完成
  • 才能统计总耗时

这样测试出来的时间才准确。

全部评论

相关推荐

05-19 16:41
复旦大学 Python
ynq2126:我一直觉得现在考算法题没啥意义 真要选拔人才不如把公司实际项目中遇到的问题当成一系列场景题抛给求职者答 这才是能检测能力的东西
点赞 评论 收藏
分享
05-21 22:52
Java
2025916Ney...:你这个简历写的一眼看上去不是很舒服
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务