【IT老齐047】避坑UUID主键
场景
财政部金财工程平台在代理行日终结算时,经常出现磁盘的IO异常,导致经常出现高延迟
对比发现在大量数据新增时磁盘IO居高不下,多次测试后发现是UUID主键在搞鬼
UUID
- 基于时间的UUID
- 能保证不同设备UUID是唯一的
- 在同一设备上生成UUID可能重复
- DCE安全的UUID
- DCE(身份验证和安全服务)
- 涉及侵犯用户隐私
- 有损时间戳导致精度丢失
- 基于命名空间的UUID (MD5、SH1)
- 在相同的命名空间下可能会出现UUID冲突
- 基于随机数的UUID
- 完全随机生成,会存在极小概率重复的情况
- 与外部环境无关,不涉及环境信息
- 生成内容无序无规律
- 目前的主流做法
UUID主键
- 优点
- 全局唯一
- 信息安全
- 缺点
- 索引效率低
- 新增效率低
页分裂
UUID是无序的,当UUID可能在索引中间某一页插入数据时
新增记录所在的数据页已满,数据库需要申请一个新的数据页存储数据。这种现象被称为“页分裂”。
页分裂确保后一个数据页中的所有的 ID 值一定比数据页中的 ID 值大在大并发环境环境下增加了磁盘IO的压力,无序ID才是罪魁祸首查找插入点时,顺序id数据会插入到最大id的页,这页往往也存在于cache中。而随机ID还需要重新去找对应页,这些页可能是冷数据,存在于磁盘上,查找需要把这部分数据交换到内存,所以造成磁盘io高.
解决方法
- 改为有序的数字主键生成策略(美团Leaf / 推特Snowflake)
- 13位时间戳(毫秒)+一位域(默认是0)+2位自增值(redis基于当前毫秒时间戳的incr生成,超出99睡眠1毫秒递归调用自己获取)