首先要知道自增主键出现的问题
在高并发的情况下加入事务执行失败回滚,会跳过当前插入ID,使ID不连续
所有数据库中的自增字段或者自增序列都要记录日志,会产生磁盘IO,会成为性能瓶颈
假如数据库使用的是Range分片,自增ID可能会集中写入集群中的一个节点,出现数据访问热地世,性能退化成单机写入
答案 1
最佳答案
解决方案
* 随机主键UUID方案(32 个的 16 进制数字,16^32 = 2^128 就是128位),虽然可以保证每次随机都不一样,但缺点是键值长度过长,存储和计算的代价增加,uuid只能保证不重复,但数据页可能会分裂,影响查询性能
* 号段模式,每个业务批量获取数据库中的号段,比如一次获取1000个,然后内存生成1000个自增ID,使用完再获取1000个;只需要插入一条记录,步长设置为1000,注意使用乐观锁(维护版本号),记录字段有业务类型、当前最大可用id、号段步长,version号;缺点服务重启时重新申请号段,不够随机有被猜到的风险
* 在TiDB 里提供了一种AutoRandom的算法,生成64位整型随机ID,1bit符号位、5bit事务开始时间,58bit自增序列号,还是有可能出现尾部热点
* 雪花算法Snowflake,时间戳精确到毫秒,10位长度机器码最大规模1024个节点(2^10), 12位序列代表1毫秒能产生的id数量最多4096个。所以 TPS 可以达到 419 万左右(2^22*1000), 每秒那么多大多系统都够了
注意雪花算法,对时间的要求比较高,如果时间不同步,时钟回拨时 ID 有可能出现重复