前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它 。
SnowFlake算法
据国家大气研究中心的查尔斯·奈特称,一般的雪花大约由10^19个水分子组成 。在雪花形成过程中,会形成不同的结构分支,所以说大自然中不存在两片完全一样的雪花,每一片雪花都拥有自己漂亮独特的形状 。雪花算法表示生成的id如雪花般独一无二 。核心思想:分布式,唯一 。
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID 。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0 。
算法具体介绍雪花算法是 64 位 的二进制,一共包含了四部分:
- 1位是符号位,也就是最高位,始终是0,没有任何意义,因为要是唯一计算机二进制补码中就是负数,0才是正数 。
- 41位是时间戳,具体到毫秒,41位的二进制可以使用69年,因为时间理论上永恒递增,所以根据这个排序是可以的 。
- 10位是机器标识,可以全部用作机器ID,也可以用来标识机房ID + 机器ID,10位最多可以表示1024台机器 。
- 12位是计数序列号,也就是同一台机器上同一时间,理论上还可以同时生成不同的ID,12位的序列号能够区分出4096个ID 。
文章插图
优化由于41位是时间戳,我们的时间计算是从1970年开始的,只能使用69年,为了不浪费,其实我们可以用时间的相对值,也就是以项目开始的时间为基准时间,往后可以使用69年 。获取唯一ID的服务,对处理速度要求比较高,所以我们全部使用位运算以及位移操作,获取当前时间可以使用System.currentTimeMillis() 。
时间回拨问题在获取时间的时候,可能会出现时间回拨的问题,什么是时间回拨问题呢?就是服务器上的时间突然倒退到之前的时间 。
- 人为原因,把系统环境的时间改了 。
- 有时候不同的机器上需要同步时间,可能不同机器之间存在误差,那么可能会出现时间回拨问题 。
- 回拨时间小的时候,不生成 ID,循环等待到时间点到达 。
- 上面的方案只适合时钟回拨较小的,如果间隔过大,阻塞等待,肯定是不可取的,因此要么超过一定大小的回拨直接报错,拒绝服务,或者有一种方案是利用拓展位,回拨之后在拓展位上加1就可以了,这样ID依然可以保持唯一 。但是这个要求我们提前预留出位数,要么从机器id中,要么从序列号中,腾出一定的位,在时间回拨的时候,这个位置 +1 。
- 百度UIDGenerator:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md
- UidGenerator是JAVA实现的, 基于Snowflake算法的唯一ID生成器 。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于Docker等虚拟化环境下实例自动重启、漂移等场景 。在实现上, UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题. 最终单机QPS可达600万 。
- 美团Leaf:https://tech.meituan.com/2019/03/07/open-source-project-leaf.html
- leaf-segment 方案
- 优化:双buffer + 预分配
- 容灾:MySQL DB 一主两从,异地机房,半同步方式
- 缺点:如果用segment号段式方案:id是递增,可计算的,不适用于订单ID生成场景,比如竞对在两天中午12点分别下单,通过订单id号相减就能大致计算出公司一天的订单量,这个是不能忍受的 。
- leaf-snowflake方案
- 使用Zookeeper持久顺序节点的特性自动对snowflake节点配置workerID
- 1.启动Leaf-snowflake服务,连接Zookeeper,在leaf_forever父节点下检查自己是否已经注册过(是否有该顺序子节点) 。
- 2.如果有注册过直接取回自己的workerID(zk顺序节点生成的int类型ID号),启动服务 。
推荐阅读
- 铁路12306提醒!抢票时,请认准官方APP候补功能
- 面试官问 HTTPS 是怎么从 HTTP 转过来的,我有点懵
- 屏下摄像头|最完美全面屏!中兴Axon 40 Ultra官方渲染图公布:屏幕开孔全部“消失”
- 冰箱|银河护卫队冰箱门被怒关近两千万次 官方:我们故意的
- yeezy官方尺码对照表39.5?yeezy官方尺码对照表v2
- 高铁乘务员面试要求
- coo的定位是什么?首席运营官的工作职责是什么
- 高校|时尚心理学:见工面试怎样穿?心理学家透露穿这个颜色录取率最高
- 大学生|假如有5杯水,却来了6个领导,应该怎么分?国企面试题难倒众人
- 00后|00后毕业生简历太狂野了?谷爱凌的朋友!面试官:被简历笑出腹肌
- 使用Zookeeper持久顺序节点的特性自动对snowflake节点配置workerID
- leaf-segment 方案