https://blog.csdn.net/liwenbo_csu/article/details/51313555

原文

Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。

Snowflake算法核心

把时间戳,工作机器id,序列号组合在一起。

 

snowflake-64bit

 

除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。下文会具体分析。



结构为:

0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---0000000000 00

 
 

在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。

这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。


**
 * ID 生成策略
 * 毫秒级时间41位+机器ID 10位+毫秒内序列12位。
 * 0           41     51     64
+———–+——+——+
|time       |pc    |inc   |
+———–+——+——+
 * 最高位bit标记为不可用
 *  前41bits是以微秒为单位的timestamp。
 *  接着10bits是事先配置好的机器ID。
 *  最后12bits是累加计数器。
 *  macheine id(10bits)标明最多只能有1024台机器同时产生ID,sequence number(12bits)也标明1台机器1ms中最多产生4096个ID,
 *
 */
class SnowFlake{
    private static epoch=1462264156000;publicfunctioncreateID( e p o c h = 1462264156000 ; p u b l i c f u n c t i o n c r e a t e I D ( machineId){
        /*
        * Time - 41 bits
        */
        time=floor(microtime(true)1000);/Substractcustomepochfromcurrenttime/ t i m e = f l o o r ( m i c r o t i m e ( t r u e ) ∗ 1000 ) ; / ∗ ∗ S u b s t r a c t c u s t o m e p o c h f r o m c u r r e n t t i m e ∗ / time -= SnowFlake:: epoch;/flagnumber1bitscannotchange,beacauseisshoulebeapositivenumber/ e p o c h ; / ∗ ∗ f l a g n u m b e r − 1 b i t s − c a n n o t c h a n g e , b e a c a u s e i s s h o u l e b e a p o s i t i v e n u m b e r ∗ / suffix = 0;
        
        /*
        * Create a base and add time to it
        */
        base=decbin(pow(2,40)1+ b a s e = d e c b i n ( p o w ( 2 , 40 ) − 1 + time);
  // base=sprintf(" b a s e = s p r i n t f ( " time));
        /*
        * Configured machine id - 10 bits - up to 512 machines
        */
        machineid=decbin(pow(2,9)1+ m a c h i n e i d = d e c b i n ( p o w ( 2 , 9 ) − 1 + machineId);
// machineid=sprintf(" m a c h i n e i d = s p r i n t f ( " machineId));
        /*
        * sequence number - 12 bits - up to 2048 random numbers per machine
        */
        random=mtrand(1,pow(2,11)1); r a n d o m = m t r a n d ( 1 , p o w ( 2 , 11 ) − 1 ) ; random = decbin(pow(2,11)-1 + $random);
// random=mtrand(1,pow(2,12)1);// r a n d o m = m t r a n d ( 1 , p o w ( 2 , 12 ) − 1 ) ; / / random = sprintf("%012s", decbin( random));/ r a n d o m ) ) ; / ∗ ∗ 拼 装 base
        */
        base= b a s e = suffix. base. b a s e . machineid. random;/baselong/ r a n d o m ; / ∗ ∗ 讲 二 进 制 的 b a s e 转 换 成 l o n g ∗ / base = bindec( base); b a s e ) ; id = sprintf('%.0f', base);return b a s e ) ; r e t u r n id;
    }
}


我这里的PHP代码序列号是随机产生的,因为我们的业务还不达不到需要有序生成的必要, 而且对于PHP来说要序列化生成必须把这个序列存储到缓存里面去。

详细代码可参考:https://github.com/twitter/snowflake

        </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值