分库分表后ID冲突的解决方案
分库分表后,传统的自增ID会导致ID冲突,需要采用分布式ID生成方案。以下是常见的解决方案:
UUID方案
UUID(Universally Unique Identifier)是一个128位的数字,通常以36字符的字符串表示。UUID理论上不会重复,但存在以下问题:
- 无序性导致索引效率低
- 字符串存储占用空间大
- 无法保证趋势递增
// Java生成UUID示例
String uuid = UUID.randomUUID().toString();
数据库自增ID方案
使用独立的数据库实例生成自增ID,所有分库分表都从这个中央数据库获取ID。这种方案简单但存在单点故障风险。
-- 创建专门的ID生成表
CREATE TABLE id_generator (
id bigint NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
);
Redis生成ID方案
利用Redis的原子性操作INCR和INCRBY生成ID。Redis性能高,但存在持久化问题。
# Redis命令示例
127.0.0.1:6379> INCR global:id
(integer) 1
雪花算法(Snowflake)
Twitter开源的分布式ID生成算法,生成64位的ID:
- 1位符号位(始终为0)
- 41位时间戳(毫秒级)
- 10位机器ID(5位数据中心+5位机器ID)
- 12位序列号(每毫秒产生4096个ID)
// Java实现雪花算法示例
public class SnowflakeIdWorker {
private long workerId;
private long datacenterId;
private long sequence = 0L;
public synchronized long nextId() {
long timestamp = timeGen();
// 实现ID生成逻辑
return ((timestamp - 1288834974657L) << 22) |
(datacenterId << 17) |
(workerId << 12) |
sequence;
}
}
Leaf算法
美团开源的分布式ID生成系统,提供两种模式:
- 号段模式:从数据库批量获取ID段,缓存在内存中
- 雪花算法模式:优化了时钟回拨问题
滴滴TinyID
基于数据库号段模式的分布式ID生成系统,特点:
- 支持HTTP和RPC方式获取ID
- 支持批量获取ID
- 提供ID缓存,提高性能
百度UidGenerator
基于雪花算法的改进方案,特点:
- 采用RingBuffer预生成ID
- 解决时钟回拨问题
- 支持自定义workerId分配策略
选择建议
- 简单系统:考虑Redis或数据库自增ID方案
- 中等规模:Leaf号段模式或滴滴TinyID
- 大规模高并发:雪花算法或改进版(UidGenerator)
- 需要无序ID:UUID(但要注意性能影响)
各方案需要根据实际业务场景、团队技术栈和运维能力进行选择,确保在分布式环境下ID的全局唯一性。
510

被折叠的 条评论
为什么被折叠?



