Twitter的雪花在分布式生成唯一UUID应用还是蛮广泛的,基于雪花的一些变种的算法网上也有不少。使用雪花生成UUID很多都是在分布式场景下使用,我看了下网上有其中有几篇PHP实现的都没有考虑到线程安全。现在PHP有了Swoole的锁和协程的加持,对于我们开发线程安全和高并发模拟还是很方便的,这里用PHP结合Swoole来学习下实现最简单的雪花。
<强>先来看以下雪花的结构:强>
生成的数值是64位,分成4个部分:
-
<李>第一个比特为符号位,最高位为0表示正数李>
<李>第二部分41个钻头用于记录生成ID时候的时间戳,单位为毫秒,所以该部分表示的数值范围为2 ^ 41 - 1(69年),它是相对于某一时间的偏移量李>
<李>第三部分的10个点表示工作节点的ID,表示数值范围为2 ^ 10 - 1,相当于支持1024个节点李>
<李>第四部分12个点表示每个工作节点没毫秒生成的循环自增id、最多可以生成2 ^ 12 1个id、超出归零等待下一毫秒重新自增。
李>
& lt; & # 63; php 类雪花 { const时代=1543223810238;//起始时间戳,毫秒 const SEQUENCE_BITS=12;//序号部分12位 const SEQUENCE_MAX=1 ^ (1 & lt; & lt;自我:SEQUENCE_BITS);//序号最大值 const WORKER_BITS=10;//节点部分10位 const WORKER_MAX=1 ^ (1 & lt; & lt;自我:WORKER_BITS);//节点最大数的值 const TIME_SHIFT=self:: WORKER_BITS + self:: SEQUENCE_BITS;//时间戳部分左偏移量 const WORKER_SHIFT=self:: SEQUENCE_BITS;//节点部分左偏移量 保护时间戳美元;//上次ID生成时间戳 保护workerId美元;//节点ID 保护美元序列;//序号 保护锁定美元;//Swoole互斥锁 公共函数__construct (workerId美元) { if ($ workerId & lt;0 | | $ workerId比;自我::WORKER_MAX) { trigger_error(“工人ID超出范围”); 退出(0); } $ this→timestamp=0; $ this→workerId=$ workerId; $ this→序列=0; $ this→锁=new swoole_lock (SWOOLE_MUTEX); }/* * *生成ID * @return int */公共函数getId () { $ this→→锁锁();//这里一定要记得加锁 现在美元=$这个→(); if ($ this→时间戳==现在美元){ + + $ this→序列; if ($ this→序列比;自我::SEQUENCE_MAX) {//当前毫秒内生成的序号已经超出最大范围,等待下一毫秒重新生成 现在虽然($ & lt;=$这→时间戳){ 现在美元=$这个→(); } } 其他}{ $ this→序列=0; } 现在美元这→时间戳=$;//更新ID生时间戳 $ id=((现在美元- self::时代)& lt; & lt;自我:TIME_SHIFT) | ($ this→workerId & lt; & lt;自我::WORKER_SHIFT) | $ this→序列; $ this→→锁解锁();//解锁 返回$ id; }/* * *获取当前毫秒 * @return字符串 */现在公共函数() { 返回sprintf (“%。0 f”(true) * 1000); } } >之前其实逻辑并不复杂,解释一下代码中的位运算:
1 ^ (1 & lt; & lt;自我::SEQUENCE_BITS) 就是1的二进制表示为1的补码,其实等同于: 2 * * self:: SEQUENCE_BITS - 1 >之前最后部分左移后或运算:
((现在美元- self::时代)& lt; & lt;自我:TIME_SHIFT) | ($ this→workerId & lt; & lt;自我::WORKER_SHIFT) | $ this→序列; >之前这里主要是对除了第一位符号位以外的三个部分进行左移相应的偏移量使其归位,并通过或运算重新整合成上面雪花的结构,比如我们用3部分4位来演示一下该归并操作:
0000 0000 0010,——左移0位——比;0000 0000 0010
引用>
0000 0000 0100,——左移4位,在0000 0100 0000,或操作,在1000 0100 0010
0000 0000 1000,——左移8位,比;1000 0000 0000
到此这篇关于PHP实现雪花生成分布式唯一ID的文章就介绍到这了,更多相关PHP雪花生成分布式唯一ID内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
PHP实现雪花生成分布式唯一ID的方法示例