【分布式利器:分布式ID】7、分布式数据库方案:TiDB/OceanBase全局ID实战

系列导读

上一篇的中间件方案适合复用现有Redis/ZooKeeper的场景,但如果你的系统已经部署了分布式数据库(如TiDB、OceanBase),就没必要再引入其他方案了------分布式数据库原生支持"全局自增ID",底层通过分布式协议(如Paxos、Raft)保证唯一性和有序性,无需额外开发,无缝集成业务。

本文详解TiDB和OceanBase的全局ID实现,帮你快速落地核心业务的分布式ID。

一、适用场景

  • 已使用分布式数据库(TiDB、OceanBase、CockroachDB);
  • 核心业务(金融交易、电商核心订单、支付流水);
  • 需ID唯一有序、高可用、高吞吐;
  • 不想额外开发分布式ID逻辑,追求"零成本集成";
  • 代表业务:银行转账流水、电商核心订单、保险保单号。

二、核心原理:分布式数据库的全局序列机制

分布式数据库之所以能支持全局ID,是因为底层通过"全局序列服务"协调多节点的ID生成:

  1. 全局序列服务:分布式数据库内置独立的序列服务(如TiDB的PD集群、OceanBase的RootService),负责生成全局唯一的自增ID;
  2. 分布式协议保证:通过Paxos/Raft协议确保序列服务的高可用和数据一致性,避免ID重复;
  3. 本地缓存优化:数据库节点会预申请一段ID号段缓存到本地,减少对全局序列服务的访问,提升性能。

简单说:分布式数据库的全局ID,本质是"号段模式的内置实现",你无需关心底层细节,直接用类似单机自增ID的方式使用即可。

三、方案1:TiDB全局ID(AUTO_RANDOM/AUTO_INCREMENT)

TiDB是PingCAP开源的分布式数据库,兼容MySQL协议,提供两种全局ID方案:AUTO_RANDOM(无序)和AUTO_INCREMENT(有序)。

1. 方案1.1:AUTO_RANDOM(无序,高性能)

  • 原理:生成64位无序ID,底层通过预分配号段实现,性能极高(QPS万级+);
  • 优点:无序性避免热点写入(如TiDB分表场景,ID无序分布到不同分片);
  • 缺点:ID无序,不支持排序和分页;
  • 适用场景:无需有序的业务(如用户ID、文件ID)。
实战SQL(创建表时指定AUTO_RANDOM)
sql 复制代码
-- 创建用户表,id字段用AUTO_RANDOM(全局唯一无序)
CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_RANDOM(5) COMMENT '全局唯一用户ID(无序)',
  `username` varchar(32) NOT NULL COMMENT '用户名',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

-- 插入数据(无需指定id字段,TiDB自动生成)
INSERT INTO `user` (`username`) VALUES ('zhangsan'), ('lisi');

-- 查询结果(id为无序的64位整数)
SELECT * FROM `user`;
/*
id                  | username | create_time
--------------------|----------|---------------------
101580745387390977  | zhangsan | 2024-05-20 10:00:00
101580745387390978  | lisi     | 2024-05-20 10:01:00
*/

关键说明

  • AUTO_RANDOM(5):括号内的数字是"分片位"(0~20),用于控制ID在TiDB分表中的分布,默认5位;
  • 不支持更新ID字段,也不支持手动插入ID(需开启allow_auto_rand_insert参数)。

2. 方案1.2:AUTO_INCREMENT(有序,支持分页)

  • 原理:生成有序的全局自增ID,底层基于TiDB的PD集群(全局序列服务),支持预分配号段;
  • 优点:ID有序递增,支持排序和分页;
  • 缺点:高并发下可能出现热点分片(如ID递增集中在某一个分片);
  • 适用场景:需有序的核心业务(如订单ID、交易流水号)。
实战SQL(创建表时指定AUTO_INCREMENT)
sql 复制代码
-- 创建订单表,id字段用AUTO_INCREMENT(全局唯一有序)
CREATE TABLE `order` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '全局唯一订单ID(有序)',
  `user_id` bigint NOT NULL COMMENT '用户ID',
  `amount` decimal(10,2) NOT NULL COMMENT '订单金额',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

-- 插入数据(无需指定id字段,TiDB自动生成)
INSERT INTO `order` (`user_id`, `amount`) VALUES (1-- 补全TiDB订单表插入SQL
INSERT INTO `order` (`user_id`, `amount`) VALUES (101580745387390977, 99.90), (101580745387390978, 199.50);

-- 查询结果(id为全局有序递增)
SELECT * FROM `order`;
/*
id  | user_id             | amount  | create_time
-----|---------------------|---------|---------------------
1    | 101580745387390977  | 99.90   | 2024-05-20 10:05:00
2    | 101580745387390978  | 199.50  | 2024-05-20 10:06:00
*/

关键配置(优化有序ID性能)

TiDB的AUTO_INCREMENT默认由PD集群分配号段(默认步长=1000),可通过参数调整:

sql 复制代码
-- 修改TiDB全局参数,调整号段步长(适用于高并发场景)
SET GLOBAL tidb_auto_increment_step = 2000; -- 号段步长=2000
SET GLOBAL tidb_auto_increment_offset = 1; -- 起始偏移量=1

四、方案2:OceanBase全局ID(GLOBAL_SEQUENCE)

OceanBase是蚂蚁集团开源的分布式数据库,提供"全局序列(GLOBAL_SEQUENCE)"功能,支持自定义步长、起始值、缓存策略,灵活性更高。

1. 核心原理

  • 全局序列服务:OceanBase的RootService(根服务)负责生成全局唯一序列,通过Paxos协议保证高可用;
  • 缓存优化:数据库节点会预缓存一段序列(默认缓存1000个ID),减少网络开销;
  • 灵活配置:支持自定义起始值、步长、缓存大小,适配不同业务场景。

2. 实战用法(3种方式)

2.1 方式1:创建独立全局序列,手动调用

适用于需要手动控制ID生成的场景(如批量生成ID):

sql 复制代码
-- 1. 创建全局序列(订单ID序列)
CREATE GLOBAL SEQUENCE order_seq
START WITH 10000001 -- 起始值
INCREMENT BY 1 -- 步长
CACHE 2000 -- 节点缓存2000个ID
CYCLE OFF; -- 不循环(到达最大值后报错)

-- 2. 调用序列生成ID
SELECT nextval('order_seq'); -- 生成下一个ID(10000001)
SELECT currval('order_seq'); -- 获取当前ID(10000001)

-- 3. 插入订单表时使用
INSERT INTO `order` (`id`, `user_id`, `amount`)
VALUES (nextval('order_seq'), 101580745387390977, 299.00);
2.2 方式2:序列作为字段默认值(推荐)

插入数据时无需手动调用,字段自动获取序列值:

sql 复制代码
-- 创建订单表,id字段默认使用全局序列
CREATE TABLE `order` (
  `id` bigint NOT NULL DEFAULT nextval('order_seq') COMMENT '全局唯一订单ID(有序)',
  `user_id` bigint NOT NULL COMMENT '用户ID',
  `amount` decimal(10,2) NOT NULL COMMENT '订单金额',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

-- 插入数据(无需指定id字段)
INSERT INTO `order` (`user_id`, `amount`)
VALUES (101580745387390978, 399.90);

-- 查询结果(id自动从序列获取,有序递增)
SELECT * FROM `order`;
/*
id        | user_id             | amount  | create_time
-----------|---------------------|---------|---------------------
10000002   | 101580745387390978  | 399.90  | 2024-05-20 10:10:00
*/
2.3 方式3:创建表时内置序列(简化操作)

无需单独创建序列,直接在表字段中定义:

sql 复制代码
CREATE TABLE `pay_flow` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '支付流水ID',
  `order_id` bigint NOT NULL COMMENT '订单ID',
  `pay_amount` decimal(10,2) NOT NULL COMMENT '支付金额',
  `pay_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_order_id` (`order_id`)
) ENGINE=InnoDB 
DEFAULT CHARSET=utf8mb4 
COMMENT='支付流水表'
-- 内置全局序列配置
AUTO_INCREMENT = 20000001 -- 起始值
AUTO_INCREMENT_CACHE = 1500 -- 缓存大小
AUTO_INCREMENT_INCREMENT = 1; -- 步长

五、TiDB vs OceanBase全局ID方案对比

特性 TiDB全局ID(AUTO_RANDOM/AUTO_INCREMENT) OceanBase全局ID(GLOBAL_SEQUENCE)
有序性 AUTO_RANDOM无序,AUTO_INCREMENT有序 支持有序(默认),可配置无序
灵活性 配置项较少(步长、分片位) 高(自定义起始值、步长、缓存大小)
性能 高(QPS万级+) 高(QPS万级+,缓存可优化)
易用性 高(兼容MySQL语法,无需额外学习) 中(需学习序列创建语法)
热点优化 AUTO_RANDOM支持分片均匀分布 支持序列分片,避免热点
适用场景 电商订单、用户ID、中小型核心业务 金融交易、保险保单、大型核心业务

六、避坑指南:分布式数据库全局ID关键问题

1. TiDB避坑

  • 坑1:AUTO_INCREMENT导致热点分片(高并发下ID集中在一个分片);
    解决方案:
    • 高并发场景用AUTO_RANDOM(无序分布);
    • 调整tidb_auto_increment_step(步长=分片数),让ID均匀分布到多个分片。
  • 坑2:TiDB主从切换导致ID重复;
    解决方案:TiDB的AUTO_INCREMENT由PD集群统一分配,主从切换不影响ID唯一性,无需额外处理。

2. OceanBase避坑

  • 坑1:序列缓存过大导致ID断层;
    解决方案:
    • 缓存大小(CACHE)根据业务并发调整(低并发=100,高并发=2000);
    • 重要业务(如金融)设置CACHE 1(无缓存,每次从RootService获取,避免断层)。
  • 坑2:序列循环导致ID重复;
    解决方案:创建序列时指定CYCLE OFF(默认),避免ID循环复用。

七、优点&缺点(分布式数据库全局ID方案)

  • 优点:
    1. 零开发成本:数据库原生支持,无需额外编写代码或引入组件;
    2. 高可用:依赖分布式数据库的集群协议(Paxos/Raft),无单点故障;
    3. 高性能:支持号段缓存,QPS可达万级+;
    4. 有序性:支持有序ID,适配排序、分页需求。
  • 缺点:
    1. 依赖分布式数据库:未使用分布式数据库的系统无法复用;
    2. 迁移成本高:切换数据库时需重新适配全局ID逻辑;
    3. 配置复杂:需熟悉分布式数据库的序列参数,优化性能。

实战Tips

  1. 选型优先:已使用TiDB/OceanBase的核心业务,优先用数据库内置全局ID,避免重复开发;
  2. 有序vs无序:需排序分页用AUTO_INCREMENT(TiDB)或GLOBAL_SEQUENCE(OceanBase),无需有序用AUTO_RANDOM(TiDB);
  3. 缓存优化:高并发场景增大号段缓存(TiDB步长、OceanBase CACHE),减少数据库节点与序列服务的通信;
  4. 监控告警:监控序列剩余缓存量,避免缓存耗尽导致性能下降。

下一篇预告

至此,分布式ID的7种核心方案已全部拆解完毕!最后一篇我们将做"终极总结"------整理全方案对比表,给出"低并发→中高并发→超高并发"的选型决策逻辑,附上生产环境避坑清单,帮你快速"按场景对号入座",不再为分布式ID选型发愁!

你在项目中用的哪种分布式数据库?评论区聊聊~

相关推荐
java1234_小锋1 小时前
Kafka中的消费者偏移量是如何管理的?
分布式·kafka
我科绝伦(Huanhuan Zhou)1 小时前
深入解析Oracle 10046事件与数据库初始化引导机制
数据库·oracle
踢球的打工仔1 小时前
mysql模糊搜索,排序,分组
数据库·mysql
笨蛋少年派1 小时前
Kafka分布式流处理平台简介
分布式·kafka
一只栖枝1 小时前
MySQL OCP不培训,自学怎么学?
数据库·mysql·备考·考证·ocp
safestar20121 小时前
扒开MySQL的引擎盖:InnoDB如何用B+树、缓冲池和日志系统扛起高并发
数据库·b树·mysql
VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue房屋租赁管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
u***B7921 小时前
【分布式文件存储系统Minio】2024.12保姆级教程
分布式
全栈工程师修炼指南1 小时前
Categraf | 国产化采集器实现:SQL Server 数据库指标采集、可视化、异常告警全流程
数据库