当前位置: 首页 > article >正文

PHP实现雪花算法生成唯一ID

引言

雪花算法是Twitter开源的分布式ID生成算法,可以产生64位的ID。其中第一位是固定的正数标识,41位用于存储时间戳,剩下的为机器ID和序列号。通过时间戳、机器ID和序列号的组合,确保每个ID都是唯一的。

PHP代码

1、定义雪花算法类

class Snowflake
{
    private int $datacenterId; // 数据中心ID
    private int $machineId;    // 机器ID
    private int $sequence = 0; // 序列号
    private int $lastTimestamp = -1; // 上一个时间戳

    private const DATA_CENTER_ID_BITS = 5; // 数据中心ID所占位数
    private const MACHINE_ID_BITS = 5;      // 机器ID所占位数
    private const SEQUENCE_BITS = 12;        // 序列号所占位数

    private const MAX_DATA_CENTER_ID = -1 ^ (-1 << self::DATA_CENTER_ID_BITS);
    private const MAX_MACHINE_ID = -1 ^ (-1 << self::MACHINE_ID_BITS);
    
    private const TIMESTAMP_LEFT_SHIFT = self::SEQUENCE_BITS + self::MACHINE_ID_BITS + self::DATA_CENTER_ID_BITS;
    private const SEQUENCE_LEFT_SHIFT = self::MACHINE_ID_BITS + self::DATA_CENTER_ID_BITS;

    private int $epoch; // 起始时间戳

    public function __construct(int $datacenterId, int $machineId)
    {
        if ($datacenterId < 0 || $datacenterId > self::MAX_DATA_CENTER_ID) {
            throw new Exception("数据中心ID超出范围");
        }

        if ($machineId < 0 || $machineId > self::MAX_MACHINE_ID) {
            throw new Exception("机器ID超出范围");
        }

        $this->datacenterId = $datacenterId;
        $this->machineId = $machineId;
        $this->epoch = 1609430400000; // 自定义起始时间(例如2021年1月1日)
    }

    public function nextId(): int
    {
        $timestamp = $this->currentTimeMillis();

        if ($timestamp < $this->lastTimestamp) {
            throw new Exception("错误:系统时钟发生回拨");
        }

        if ($this->lastTimestamp === $timestamp) {
            $this->sequence = ($this->sequence + 1) & ((1 << self::SEQUENCE_BITS) - 1);
            if ($this->sequence === 0) {
                $timestamp = $this->waitNextMillis($timestamp);
            }
        } else {
            $this->sequence = 0;
        }

        $this->lastTimestamp = $timestamp;

        return (($timestamp - $this->epoch) << self::TIMESTAMP_LEFT_SHIFT) |
               ($this->datacenterId << self::SEQUENCE_LEFT_SHIFT) |
               ($this->machineId << self::SEQUENCE_BITS) |
               $this->sequence;
    }

    private function waitNextMillis(int $lastTimestamp): int
    {
        $timestamp = $this->currentTimeMillis();
        while ($timestamp <= $lastTimestamp) {
            $timestamp = $this->currentTimeMillis();
        }
        return $timestamp;
    }

    private function currentTimeMillis(): int
    {
        return (int)(microtime(true) * 1000);
    }
}

2、创建实例生成ID

// 创建雪花算法实例
$datacenterId = 1; // 数据中心ID
$machineId = 1;    // 机器ID
$snowflake = new Snowflake($datacenterId, $machineId);

// 生成用户ID的示例
for ($i = 0; $i < 10; $i++) {
    $userId = $snowflake->nextId();
    echo "生成的用户ID: $userId"."<br/>";
}

3、查看生成结果

生成的用户ID: 507485100926047232
生成的用户ID: 507485100926047233
生成的用户ID: 507485100926047234
生成的用户ID: 507485100926047235
生成的用户ID: 507485100926047236
生成的用户ID: 507485100926047237
生成的用户ID: 507485100926047238
生成的用户ID: 507485100926047239
生成的用户ID: 507485100926047240
生成的用户ID: 507485100926047241

结论

这段代码是一个比较完整的雪花算法实现,能够在分布式系统中生成高效、唯一的ID。通过合理的位移和位数分配,确保了在高并发情况下生成的ID也不会重复。

实际部署中,只需修改$datacenterId = 1; // 数据中心ID 以及 $machineId = 1; // 机器ID,即可实现分布式生成不重复的ID。


http://www.kler.cn/a/375475.html

相关文章:

  • 数据分析思维(五):分析方法——假设检验分析方法
  • vulnhub靶场【WhowWantsToBeKing】之1
  • 图片懒加载
  • GTID详解
  • 【信息系统项目管理师】高分论文:论信息系统项目的成本管理(车站设备智能化管理平台)
  • VLM--CLIP作分类任务的损失函数
  • 【银河麒麟高级服务器操作系统】虚拟机lvm分区丢失现象分析及解决建议
  • 初始JavaEE篇——多线程(7):定时器、CAS
  • <meta property=“og:type“ content=“website“>
  • 高级java每日一道面试题-2024年10月26日-JVM篇-JVM的类加载机制是什么?
  • 【机器学习】26. 聚类评估方法
  • Ubuntu 系统、Docker配置、Docker的常用软件配置(下)
  • Docker-in-Docker(DinD)
  • 4:arm汇编语言4:bits/byte的介绍(ASCII码)与二进制补位
  • 【数据结构】guard
  • PyMOL中常用的命令列表
  • 代理人工智能如何应对现代威胁的速度和数量
  • 重载与重写的区别
  • wireshark复制数据
  • 极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
  • 高清解压视频素材从哪儿下载?推荐5个高清推文素材资源网站
  • Unity3D Shader实现法线贴图功能详解
  • 【论文阅读】FUNNELRAG:一个从粗到精的逐级检索范式
  • 静态水印+动态水印,开启超强PPT版权保护!
  • 基于Material Design风格开源、免费的WinForms UI控件库
  • DNF 主从服务器的搭建