webingpro/id-generator

使用 PHP 快速生成 id 的类

dev-master 2019-08-27 03:03 UTC

This package is auto-updated.

Last update: 2024-09-27 14:16:30 UTC


README

一个用于快速生成唯一 id 的类。它基于 Twitter 的 snowflake,采用更直接的方法,可能效率略低。

生成的 ID 格式

示例 60664889587010008

格式:由 17 位数字组成的整数。 [XXXXXXXX][YYY][WW][ZZZZ] 其中

  • [XXXXXXXX]: 前面的 8 位数字是自定义时间戳,如果保持默认设置,则此值将是 CURRENT_UNIX_TIMESTAMP - 1506204000
  • [YYY]: 下面的 3 位数字是生成 id 时的时间(毫秒)
  • [WW]: 下面的 2 位数字是进程标识符,您可以运行 id 生成器的并行实例,但为了避免冲突,每个进程应具有唯一的 ID
  • [ZZZZ]: 最后的 4 位数字是顺序号,因此您可以生成每个毫秒的 9999 个 id,如果您有足够的计算能力,那么当您生成第 10000 个 id 时,IdGnerator 将等待 1 毫秒,从而避免重复。

何时需要这个?

以下是一些此类库可能有用的场景

  • 您有多个代码库/数据库,并需要确保它们之间具有唯一 id。例如,多个物理 mysql 分片。或者您的一部分数据存储在 mysql 中,另一部分存储在 mongodb 中。
  • 您正在迁移到不提供 id 生成器功能的数据库,如 Cassandra。
  • 您需要生成一个大的 SQL 插入序列,为了避免性能瓶颈,您不能插入每一行,获取其 id,然后将其用于所需的关系。在这种情况下,您可以在之前使用该库生成 id,并一次性生成整个 SQL 脚本。

可能的替代方案和动机

对于这些问题有很多替代方案,例如使用其他 GUID/UUID 方案。但我想要与 Twitter 的 snowflake 相同的东西

  • 一个 INTEGER id:因为它在 Mysql 上的索引比 UUID 字符串好得多。
  • 可排序的 id:生成的 id 在同一进程中可排序,并且即使您使用多个并行进程,它们也会大致排序。
  • 额外:这不是设计选择,但它对我已经很有用,因为它基于时间。我忘记在我的数据库中添加一些 created_on 列,由于我的 id 基于时间,我可以使用其前 8 位数字将其转换回 UNIX_TIMESTAMP,并具有数据 created_on 历史值。

您还可以使用 Twitter 的Flickr 的 解决方案,它们都很棒。我的实现是否在某种程度上优于它们?可能不是。我决定编写它的主要原因是

  1. 我可以。
  2. 我想找到一个好的用例来研究如何在 PHP 中使用套接字。

性能

在我的本地环境(8gb RAM,SSD,Intel® Core™ i7-7500U CPU @ 2.70GHz × 4)中,它可以通过 TCP 以每秒每进程约 20,000 个 id 的速度生成 id,直接在源代码中使用该库允许您以每秒数十万个 id 的速度生成 id。

安装

您可以通过仅下载src文件夹中的类文件来安装它,或者您可以使用composer来安装。Composer包名:webingpro/id-generator

使用方法

作为库

您可以直接在源代码中使用以下一行代码

$id = IdGenerator\IdGenerator::getId();

作为服务

如果您有多个代码库需要在它们之间生成唯一的ID,您可能应该使用此服务。

该服务将监听TCP端口,然后您需要通过套接字与该服务进行通信。已经有一个PHP客户端,但编写其他语言的客户端应该很简单。

测试服务

  1. 要启动服务,请在终端运行以下命令
    php src/IdGenerator/Socket/Server.php port=4317 host=127.0.0.1 workerId=01

  2. 如果一切正常,您应该看到以下消息

 IdGenerator Listening to 127.0.0.1:4317 
  1. 要测试服务,请打开一个新的终端标签并输入
telnet 127.0.0.1 4317
  1. 一旦通过telnet连接到服务,您可以使用以下命令
GET_ID //To return new ids
QUIT //To close the connection

Example

如何正确使用此服务?

如果您想将此作为服务在生产环境中使用,您可能需要使用类似supervisord的东西来控制生成的进程,并确保在出现问题时它们会被重新初始化。

此存储库根目录下有一个supervisord的示例配置文件。

一旦使用supervisord或其他类似工具启动服务,如果您使用PHP,您可以使用提供的Client类。

示例

<?php
use IdGenerator\Socket\Client;

require("vendor/autoload.php"); //Require either the composer autoloader or the Client class file
$client = new Client("127.0.0.1","4317"); //Make sure to point to the correct host and port
$id = $client->getId();
var_dump($id);

在提供的PHP客户端中,如果客户端无法连接到服务,它将抛出一个警告并使用IdGenerator对象在本地生成ID。这样做时,本地IdGenerator的工作ID将是"00",除非您通过在代码中定义常量:ID_GENERATOR_MACHINE_ID来更改它。

许可证MIT

在此软件及其相关文档文件(“软件”)的副本由任何人士获得时,特此免费授予,无任何费用,以使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许获得软件的人士进行此类行为,但受以下条件的约束

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

软件按“原样”提供,不提供任何形式的保证,无论是明示的还是隐含的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者不对任何索赔、损害或其他责任负责,无论是在合同、侵权或其他法律行为中产生的,与软件或其使用或其他方式相关。