您的位置:首页 > 娱乐 > 明星 > 东营小程序开发制作_编程入门先学什么好_宁波seo关键词排名_友情链接发布平台

东营小程序开发制作_编程入门先学什么好_宁波seo关键词排名_友情链接发布平台

2025/4/9 10:10:28 来源:https://blog.csdn.net/qq_74156239/article/details/146904611  浏览:    关键词:东营小程序开发制作_编程入门先学什么好_宁波seo关键词排名_友情链接发布平台
东营小程序开发制作_编程入门先学什么好_宁波seo关键词排名_友情链接发布平台

MySQL 分布式架构中的主键选择:自增ID、UUID与雪花算法

为什么MySQL分布式架构中不能使用自增主键?

在分布式架构中,自增主键存在以下问题:

  1. 主键冲突风险:多个数据库实例同时生成自增主键会导致ID重复
  2. 分片不均匀
    • 采用范围分片时会出现"尾部热点"现象,压力集中在某个分片
    • 无法实现负载均衡,新数据只能写入当前分片
  3. 数据合并困难:合并多个数据库时,自增主键会重复
  4. 性能瓶颈:自增锁在高并发场景下会成为性能瓶颈
  5. 安全性问题:自增ID容易被猜测,可能被用于恶意爬取数据

UUID作为主键的优缺点

优点

全局唯一性:几乎可以保证全球范围内的唯一性
分布式友好:无需协调即可在不同节点生成
安全性:随机生成的UUID难以被猜测

缺点

存储空间大:16字节(128位),是自增ID(通常4字节)的4倍
索引性能差
• 无序插入导致B+树频繁分裂和平衡
• 增加索引大小,降低缓存命中率
可读性差:长字符串形式不利于人工识别和调试
碎片化问题:随机插入导致磁盘碎片化

MySQL 8.0优化:可使用UUID_TO_BIN函数将UUID转换为16字节二进制并排序,性能接近自增ID

雪花算法(SnowFlake)详解

原理

雪花算法生成64位长整型ID,结构如下:

0 | 0000000 00000000 00000000 00000000 00000000 | 00000 | 00000 | 00000000 0000
  1. 1位符号位:固定为0(正数)
  2. 41位时间戳:毫秒级时间,可用69年(从1970算起)
  3. 10位机器标识
    • 5位数据中心ID(32个可能值)
    • 5位工作机器ID(32个可能值)
  4. 12位序列号:同一毫秒内的计数器(4096个值/ms/机器)

优势

  1. 全局唯一:通过时间戳+机器ID+序列号组合保证
  2. 有序递增:基于时间戳,有利于索引和排序
  3. 高性能:本地生成,每秒可生成数百万ID
  4. 不依赖第三方:算法简单,内存中完成
  5. 分布式友好:支持最多1024个节点(10位机器标识)

不足与解决方案

  1. 时钟回拨问题
    问题:服务器时间被调回导致重复ID
    解决方案
    ◦ 直接抛出异常,停止服务
    ◦ 记录最近时间戳,回拨时等待
    ◦ 使用扩展位记录时钟序列(3位时钟序列+7位机器ID)
    ◦ 采用Leaf、UidGenerator等改进方案

  2. 机器ID限制
    问题:10位仅支持1024个节点
    解决方案
    ◦ 预分配ID(适合固定节点)
    ◦ 动态分配(使用Redis/Zookeeper存储ID)
    ◦ 扩展位数(牺牲部分时间戳或序列号位)

  3. 时间戳耗尽
    问题:41位时间戳约69年后耗尽
    解决方案:调整起始时间(如使用系统上线时间而非1970)

代码示例(Java)

public class SnowflakeIdGenerator {private final long twepoch = 1577836800000L; // 自定义起始时间(2020-01-01)private final long workerIdBits = 5L;private final long datacenterIdBits = 5L;private final long maxWorkerId = -1L ^ (-1L << workerIdBits);private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);private final long sequenceBits = 12L;private final long workerIdShift = sequenceBits;private final long datacenterIdShift = sequenceBits + workerIdBits;private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final long sequenceMask = -1L ^ (-1L << sequenceBits);private long workerId;private long datacenterId;private long sequence = 0L;private long lastTimestamp = -1L;public SnowflakeIdGenerator(long workerId, long datacenterId) {// 参数校验this.workerId = workerId;this.datacenterId = datacenterId;}public synchronized long nextId() {long timestamp = timeGen();// 处理时钟回拨if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards");}if (lastTimestamp == timestamp) {sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;return ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift)| sequence;}// 其他辅助方法...
}

总结对比

特性自增IDUUID雪花算法
唯一性单机唯一全局唯一全局唯一
有序性严格有序完全无序时间有序
存储空间4-8字节16字节8字节
分布式支持不支持支持支持
生成方式数据库生成应用生成应用生成
性能影响自增锁瓶颈索引分裂时钟依赖
适用场景单机MySQL简单分布式系统高并发分布式系统

推荐选择
• 单机系统:自增ID
• 简单分布式系统:MySQL 8.0的有序UUID
• 高并发分布式系统:雪花算法或其改进版(如Leaf)

版权声明:

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

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