实现
分布式唯一ID采用Twitter公司开源的雪花算法
- 由左至右的位含义
- 1位保留未使用
- 41位为毫秒级时间(41位的长度可以使用69年左右)
- 5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点)
- 12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。经测试snowflake每秒能够产生26万个ID。
风险点
- 时间戳问题:服务器时间同步可能存在回调,回调可能会导致ID冲突
- 溢出问题:41位时间戳、12位序列号、10位机器码,可能会溢出
- 数据库手工新增数据风险点:手工insert数据库数据可能会与算法生成的产生冲突
- 部分语言不支持超出53bit整数问题:JavaScript不支持超出53bit的整数,目前前端使用字符串保存分布式id。Twitter官方提供的方案:https://developer.twitter.com/en/docs/basics/twitter-ids
踩坑
数据主键使用分布式id未生效
- 检查主键是否bigint类型
- 检查mapper中是否存在后置动作回塞主键为LAST_INSERT_ID,如果存在需要删除,或者生成mapper前删除generatorConfig.xml配置中table配置处的generatedKey配置重新生成mapper
<table tableName="my_table" domainObjectName="MyTable" delimitIdentifiers="true">
<generatedKey column="id" sqlStatement="MYSQL" identity="true" type="post"/>
</table>