chivincent/snowflake

此包已被弃用,不再维护。未建议替代包。

Twitter Snowflake for PHP 实现。

1.1.1 2018-03-19 03:10 UTC

This package is not auto-updated.

Last update: 2020-08-22 07:13:10 UTC


README

Build Status

Twitter Snowflake 的 PHP 实现。

安装

composer require chivincent/snowflake

使用方法

<?php

require __DIR__ . '/vendor/autoload.php';

use Chivincent\Snowflake\Snowflake;

$snowflake = new Snowflake();

// Generate single unique ID.
$snowflake(); // It will return int.
$snowflake->gen(); // It will return an array with single element.

// Generate 10 unique IDs
$snowflake->gen(10);

// Generate 1000 unique IDs
$snowflake->gen(1000);

描述

返回值是怎样的?

它是一个包含 1 或多个 64 位整数的数组,可以存储为 MySQL 的 bigint 数据类型。

如何在同一请求中保持“唯一性”?

该值由毫秒数、机器 ID 和序列号生成。

当在多台机器上使用时,应将 MACHINE_ID(0 ~ 8191) 设置为您的本地环境。

在相同毫秒内,将使用序列号来保证值的唯一性。

默认情况下,数据是如何存储在 64 位数字中的?


+---------------------------------+----------------------+-------------------+
| millisecond timestamp (41 bits) | machine id (13 bits) | sequence (9 bits) |
+---------------------------------+----------------------+-------------------+

您可以在构建 Chivincent\Snowflake\Snowflake 时重置此数据存储的机器 ID 和序列。

<?php

require __DIR__ . '/vendor/autoload.php';

use Chivincent\Snowflake\Snowflake;
use Chivincent\Snowflake\StaticSequence;

$snowflake = new Snowflake(StaticSequence::class, 14, 8);
// The machine id length is 14 bits.
// The sequence length is 8 bits.
// Note: The sum of machine id length and sequence length should be 22. 

可能重复吗?

很遗憾,这是可能的。

此包使用 static 变量来控制序列,但它可能在不同的请求中重复。

如何解决竞态条件?

创建一个实现 Chivincent\Snowflake\Sequencer 接口的序列类,您可以为生成序列定义静态方法 next,例如通过 redis 或 memcached。

示例

<?php

namespace MyAwesome\Project;

use Chivincent\Snowflake\Sequencer;

class RedisSequence implements Sequencer
{
    protected $redis;
    
    public static function next(int $timestamp): int
    {
        if (!$redis->timestampExists($timestamp)) {
            $redis->insertCurrentTimestamp($timestamp);
            return 0;
        }
        
        if ($redis->isLimit()) {
            return self::WAIT_FOR_NEXT_TIME;
        }
        
        return $redis->getNextNumber();        
    }
}

// Use your RedisSequence when Snowflake's constructor.
new Snowflake(RedisSequence::class);

许可证

此库在 MIT 许可下。