您的位置:首页 > 文旅 > 旅游 > app制作外包_专业建站公司电话咨询_厦门seo收费_友链交换网站

app制作外包_专业建站公司电话咨询_厦门seo收费_友链交换网站

2025/4/19 3:23:59 来源:https://blog.csdn.net/weixin_42541479/article/details/147295753  浏览:    关键词:app制作外包_专业建站公司电话咨询_厦门seo收费_友链交换网站
app制作外包_专业建站公司电话咨询_厦门seo收费_友链交换网站

全局ID生成器

在这里插入图片描述

文章目录

  • 全局ID生成器
    • 一、全局ID生成器的定义
      • 定义
      • 核心作用
    • 二、全局ID生成器需满足的特征
      • 1. 唯一性(Uniqueness)​
      • 2. 高性能(High Performance)​
      • 3. 可扩展性(Scalability)​
      • 4. 有序性(Orderliness)​
      • 5. 可靠性(Reliability)​
      • 6. 安全性(Security)​
      • 7. 兼容性(Compatibility)​
    • 三、全局唯一ID生成策略:
      • 1. UUID
      • 2. 数据库自增ID
      • 3. Snowflake算法(Twitter开源)​
      • 4. Redis自增
      • 5. 数据库号段模式
      • 6. Leaf(美团开源)​
    • 四、策略对比
    • 五、选型建议

一、全局ID生成器的定义

定义

  • 全局ID生成器是一种在分布式系统中生成唯一标识符(ID)的机制,确保生成的ID在整个系统范围内(可能跨多个服务、数据库或数据中心)具有唯一性。它是解决分布式环境下数据唯一性、数据关联和事务协调等问题的核心技术之一。

核心作用

  • ​唯一性:确保每个生成的ID在全局范围内不重复。
  • 可识别性:通过ID快速定位资源或关联业务(如订单、用户、消息等),不能被看出太明显的规律。
  • ​扩展性:支持系统规模增长(如分库分表、多节点部署)时仍能高效生成ID,高效应对海量数据。

二、全局ID生成器需满足的特征

全局ID生成器,是分布式系统环境下生成全局唯一ID的工具,一般需要满足下列特征:

1. 唯一性(Uniqueness)​

  • 核心要求:生成的ID在全局范围内绝对唯一。
  • 意义:避免数据冲突(如主键重复、消息覆盖)。
  • 实现方式
    • 算法设计(如Snowflake通过时间戳+机器ID+序列号保证唯一)。
    • 中心化协调(如数据库自增ID依赖数据库的唯一约束)。

2. 高性能(High Performance)​

  • 要求:生成ID的速度快,延迟低,支持高并发场景。
  • 意义:避免成为系统瓶颈(如秒杀场景下每秒生成数十万ID)。
  • 实现方式
    • 本地生成(如Snowflake在内存中生成,无需网络请求)。
    • 批量预分配(如数据库号段模式一次性获取多个ID)。

3. 可扩展性(Scalability)​

  • 要求:支持系统横向扩展(如新增节点)时无需重构ID生成逻辑。
  • 意义:适应业务增长,避免单点瓶颈。
  • 实现方式
    • 分布式算法(如Snowflake允许动态增加机器ID)。
    • 去中心化设计(如UUID无需中心节点)。

4. 有序性(Orderliness)​

  • 要求:生成的ID按时间递增或可排序。
  • 意义:便于数据库索引优化、分页查询和业务排序(如按时间排序订单)。
  • 实现方式
    • 时间戳高位(如Snowflake将时间戳放在ID的高位)。
    • 数据库自增ID天然有序,但分布式下需分片步长策略。

5. 可靠性(Reliability)​

  • 要求:生成过程容错,避免单点故障。
  • 意义:保障系统高可用(如机器宕机不影响ID生成)。
  • 实现方式
    • 去中心化算法(如Snowflake无单点依赖)。
    • 冗余设计(如Leaf通过ZooKeeper管理机器ID,支持故障转移)。

6. 安全性(Security)​

  • 要求:防止ID被猜测或遍历(如避免暴露业务量或用户隐私)。
  • 意义:防止恶意攻击(如通过ID遍历批量查询数据)。
  • 实现方式
    • 加入随机性(如UUIDv4的随机部分)。
    • 加密或哈希处理(如美团的Leaf-Segment加密号段)。

7. 兼容性(Compatibility)​

  • 要求:ID格式适配现有技术栈(如数据库类型、网络传输)。
  • 意义:降低集成成本(如避免使用超长ID导致存储浪费)。
  • 实现方式
    • 数值型ID(如Snowflake的64位Long类型,兼容MySQL BIGINT)。
    • 字符串ID(如UUID的128位字符串,适配NoSQL数据库)。

三、全局唯一ID生成策略:

1. UUID

  • 原理:生成128位随机字符串(如 550e8400-e29b-41d4-a716-446655440000)。
  • 优点:简单、无需中心化协调。
  • 缺点:无序、长度长、存储和索引效率低。
  • 适用场景:非高频查询场景,如日志跟踪、临时标识。
  • 优化:使用UUIDv4(随机生成)避免隐私问题。

2. 数据库自增ID

  • 原理:利用数据库自增主键生成唯一ID。
  • 优点:简单、天然有序。
  • 缺点:单点瓶颈、横向扩展困难。
  • 优化
    • 分库分表:为每个分片设置不同步长(如库1步长=2,起始值=1;库2步长=2,起始值=2)。
    • 批量获取:一次性申请多个ID(如 INSERT … SELECT MAX(id)+N)。

3. Snowflake算法(Twitter开源)​

  • ID结构​(64位):
    | 符号位(1) | 时间戳(41) | 机器ID(10) | 序列号(12) |
    
  • 优点:有序、高性能、去中心化。
  • 缺点:依赖系统时钟(时钟回拨需处理)。
  • 实现
    public class Snowflake {private final long machineId;   // 机器ID(0~1023)private long lastTimestamp = -1L;private long sequence = 0L;public synchronized long nextId() {long timestamp = System.currentTimeMillis();if (timestamp < lastTimestamp) throw new RuntimeException("时钟回拨");if (timestamp == lastTimestamp) {sequence = (sequence + 1) & 0xFFF; // 序列号自增,溢出则等待下一毫秒if (sequence == 0) timestamp = waitNextMillis();} else {sequence = 0;}lastTimestamp = timestamp;return ((timestamp - TWEPOCH) << 22) | (machineId << 12) | sequence;}
    }
    

4. Redis自增

  • 原理:利用Redis的原子操作 INCR 或 INCRBY 生成自增ID。使用Java的Long类型存储,为了增加ID的安全性,我们可以不直接只用Redis自增的数值,而是拼接一些其他信息:

    ID的组成部分(Java Long类型存储,占用8个字节,也就是64个比特位):0  - 0000000 00000000 00000000 00000000 - 00000000 00000000 00000000 00000000↑                  ↑                                     ↑符号位 |<------- 时间戳(31 bit)-------->|  |<-------- 序列号(32 bit)-------->|
    
    • 符号位: 1 bit,永远为0(表示正数)
    • 时间戳:31 bit,以秒为单位,以2000年1月1日00时作为参照系,用当前时间 - 参照时间 = 时间戳,2^31 秒 约等于69年。
    • 序列号:31 bit,Redis自增的值,该方式理论上支持每秒产生 2^32 个不同ID。
  • ​优点:高性能、简单。

  • 缺点:依赖Redis可用性,需处理持久化问题。

  • 优化:集群模式 + 多Key分片(如 order_id:shard_1)。

  • 实现

    @Component
    public class RedisIdGenerator {/*** 开始时间戳 2000年1月1日零时零分零秒*/private static final long BEGIN_TIMESTAMP = 946684800L;/*** 序列号位数*/private static final int COUNT = 32;private StringRedisTemplate stringRedisTemplate;@Autowiredpublic RedisIdGenerator(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}public long nextId(String keyPrefix) {// 1.生成时间戳LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIMESTAMP;// 2.生成序列号String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); // 使用冒号分割,方便统计Long increment = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date); // 加入日期,防止超出2^32上限(Redis自增上限为2^64)long incrementUnbox = 0L;if (increment != null) {incrementUnbox = increment;}// 3.拼接并返回return timestamp << COUNT | incrementUnbox; // 左移 32位,拼接时间戳和序列号}public static void main(String[] args) {// 2000年1月1日零时零分零秒 的秒数LocalDateTime time = LocalDateTime.of(2000, 1, 1, 0, 0, 0);long second = time.toEpochSecond(ZoneOffset.UTC);System.out.println("second = " + second); // second = 946684800}
    }
    

5. 数据库号段模式

  • 原理:从数据库批量获取号段(如一次分配1000个ID),缓存在本地使用。
  • 表设计
    CREATE TABLE id_segment (biz_tag VARCHAR(32) PRIMARY KEY,  -- 业务标识max_id BIGINT NOT NULL,           -- 当前最大IDstep INT NOT NULL                 -- 每次步长
    );
    
  • 优点:减少数据库压力、可扩展性强。
  • 缺点:需维护号段表,处理并发冲突。

6. Leaf(美团开源)​

  • 混合模式
    • 号段模式:类似数据库号段,依赖数据库。
    • Snowflake模式:依赖ZooKeeper分配机器ID。
  • 优点:高可用、灵活切换模式。
  • 实现:通过ZooKeeper管理机器ID,支持号段预分配。

四、策略对比

策略唯一性有序性性能可靠性典型场景
UUID日志跟踪、临时标识
​数据库自增ID❌(单点)中小规模分库分表
Snowflake极高✅(去中心化)高并发订单、消息队列
Redis INCR❌(依赖Redis)短期唯一ID(如会话ID)
​Leaf(美团)​✅(混合模式)大规模分布式系统

五、选型建议

场景推荐方案关键考虑
高性能、有序IDSnowflake处理时钟回拨(NTP同步、异常等待)
简单、无序UUID v4适合临时标识
依赖RedisRedis INCR需保障Redis高可用
数据库友好、可控数据库号段模式适合中小规模分布式系统
企业级复杂场景Leaf结合号段和Snowflake优势

实际选型建议

  1. 高并发有序ID:优先选择Snowflake或其变种(如美团的Leaf-Segment)。
  2. ​简单临时标识:使用UUID v4(如用户临时Token)。
  3. 数据库友好场景:数据库号段模式(如分库分表的预分配ID)。
  4. 强一致性需求:结合Redis或ZooKeeper的分布式锁生成ID。

常见问题处理

  1. 时钟回拨
    • 方案:记录上次时间戳,发现回拨时抛出异常或等待时钟追上。
    • 优化:使用NTP同步服务器时间,或扩展Snowflake增加时间戳位数。
  2. 机器ID分配
    • 方案:ZooKeeper/配置中心动态分配,或按数据中心+机器ID编码。

根据业务规模、一致性要求及运维成本选择合适的策略,必要时可组合使用多种方案。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com