互联网笔记

Snowflake Algorithm

Snowflake Algorithm
2023-02-09 · 2 min read
开发 PHP

实现雪花算法(Snowflake Algorithm)的步骤

  1. 确定时间戳占多少位:由于雪花算法的最小时间单位为毫秒,假如要标识的时间跨度为41年,可以确定能用到的时钟位数是41 (2^41-1)/1000/60/60/24/365=41,也就是说64bit的ID中时间戳部分需要占据42位。

  2. 确定机器标识占多少位:机器标识需要在集群中唯一,这里对numOfWorkingIds设置为2^10-1=1023,即可分配1024台服务器,机器标识部分占用10位。

  3. 确定序列号占多少位:序列号可以设置最大值,这里设置序列号最大值为4095 ,即2^12-1, 则此部分占 12 位,最后剩下 2 个 bit 。

PHP 代码

const tokenBits = {
    timestamp: 41,
    workerId: 10,
    sequence: 12
}
 
class Snowflake {  
    public static function generate() {
        // get current timestamp
        $timestamp = floor(microtime(true) * 1000);
 
        // the id starts with the timestamp
        $baseId = bcadd(bcmul($timestamp, '1' . str_repeat('0', tokenBits['timestamp'])), 0);
 
        // add a random worker id
        $baseId = bcadd(bcmul(str_pad(mt_rand(1, 1023), tokenBits['workerId'], '0', STR_PAD_LEFT), bcpow('2', tokenBits['timestamp'])), $baseId);
 
        // add a sequence counter we start from 0
        $baseId = bcadd(bcmul(str_pad($sequence, tokenBits['sequence'], '0', STR_PAD_LEFT), bcpow('2', tokenBits['timestamp'] + tokenBits['workerId'])), $baseId);
 
        return $baseId;
    }
}