本文主要内容如下:
文章插图
前言
最近生产环境遇到一个问题:
现象:创建工单、订单等地方 , 全都创建数据失败 。
初步排查:报错信息为duplicate key , 意思是保存数据的时候 , 报主键 id 重复 , 而这些 id 都是由雪花算法生成的 , 按道理来说 , 雪花算法生成的 ID 是唯一 ID , 不应该出现重复的 ID 。
大家可以先猜猜是什么原因 。
有的同学可能对雪花算法不熟悉 , 这里做个简单的说明 。(熟悉的同学可以跳到第二个段落)
一、雪花算法
snowflake(雪花算法):Twitter 开源的分布式 id 生成算法 , 64 位的 long 型的 id , 分为 4 部分:
文章插图
snowflake 算法
- 1 bit:不用 , 统一为 0
- 41 bits:毫秒时间戳 , 可以表示 69 年的时间 。
- 10 bits:5 bits 代表机房 id , 5 个 bits 代表机器 id 。最多代表 32 个机房 , 每个机房最多代表 32 台机器 。
- 12 bits:同一毫秒内的 id , 最多 4096 个不同 id , 自增模式
优点:
- 毫秒数在高位 , 自增序列在低位 , 整个ID都是趋势递增的 。
- 不依赖数据库等第三方系统 , 以服务的方式部署 , 稳定性更高 , 生成ID的性能也是非常高的 。
- 可以根据自身业务特性分配bit位 , 非常灵活 。
缺点:
- 强依赖机器时钟 , 如果机器上时钟回拨(可以搜索 2017 年闰秒 7:59:60找到相关问题) , 会导致发号重复或者服务会处于不可用状态 。
闰秒就是通过给“世界标准时间”加(或减)1秒 , 让它更接近“太阳时” 。例如 , 两者相差超过0.9秒时 , 就在23点59分59秒与00点00分00秒之间 , 插入一个原本不存在的“23点59分60秒” , 来将时间调慢一秒钟 。
看了上面的关于雪花算法的简短介绍 , 想必大家能猜出个一二了 。
雪花算法和时间是强关联的 , 其中有 41 位是当前时间的时间戳 , 那么会不会和时间有关?
二、排查 2.1 雪花算法有什么问题?
既然是雪花算法的问题 , 那我们就来看下雪花算法出了什么问题:
(1)What:雪花算法生成了重复的 ID , 这些 ID 是什么样的?
(2)Why:雪花算法为什么生成了重复的 key
第一个问题 , 我们可以通过报错信息发现 , 这个重复的 ID 是 -1 , 这个就很奇怪了 。一般雪花算法生成的唯一 ID 如下所示 , 我分别用二进制和十进制来表示:
十进制表示:2097167233578045440 二进制表示:0001 1101 0001 1010 1010 0010 0111 1100 1101 1000 0000 0010 0001 0000 0000 0000
找到项目中使用雪花算法的工具类 , 生成 ID 的时候有个判断逻辑:
当当前时间小于上次的生成时间就会返回 -1 , 所以问题就出在这个逻辑上面 。(有的雪花算法是直接抛异常)
if (timestamp < this.lasttimestamp) { return -1; }
文章插图
由于每次 timestamp 都是小于 lastTimeStamp , 所以每次都返回了 -1 , 这也解释了为什么生成了重复的 key 。
2.2 时钟回拨或跳跃
那么问题就聚焦在为什么当前时间还会小于上次的生成时间 。
下面有种场景可能发生这种情况:
首先假定当前的北京时间是 9:00:00 。另外上次生成 ID 的时候 , 服务器获取的时间 lastTimestamp=10:00:00 , 而现在服务器获取的当前时间 timestamp=09:00:00 , 这就相当于服务器之前是获取了一个未来时间 , 现在突然跳跃到当前时间 。
推荐阅读
- 一次服务器非法重启后导致的故障排查记录
- 叶彤|叶彤:被称为“童年女神”,曾迷倒释小龙,嫁黑人后变化大
- 大博弈|《大博弈》口碑走高!舍得酒成剧中“团宠”,举杯间维系彼此情感
- 跷跷板“秋千”用英语该怎么说呢? 跷跷板英文
- 金敏喜|金敏喜的跌宕人生:从“男神收割机”到韩国最强小三,她图什么?
- |从这12个方面培养职场“心计”,做个有城府的人
- 护肤品|继“百雀羚”后,中国又一“平价”护肤品走红!高质低价力压兰蔻
- 买办公笔记本电脑哪个牌子好用质量好 办公用买什么笔记本电脑好
- 刘飞儿|写真一姐罕见“魔幻妆容”竟引发厌世心态?气到想做出FIFA事件?
- 周深|周深粉丝微博“吵架”,为什么那么怂,周深会被饭圈文化反噬吗?