snowflow php实现
Snowflake算法简介
Snowflake是Twitter开源的一种分布式ID生成算法,用于在分布式系统中生成唯一ID。其核心思想是将ID划分为多个部分(时间戳、机器ID、序列号),确保高并发下不重复。
PHP实现Snowflake算法
定义常量与类结构
class Snowflake {
private $epoch; // 起始时间戳(毫秒)
private $machineId; // 机器ID
private $sequence = 0; // 序列号
private $lastTimestamp; // 上次生成ID的时间戳
// 位数分配(默认配置)
const TIMESTAMP_BITS = 41;
const MACHINE_ID_BITS = 10;
const SEQUENCE_BITS = 12;
}
初始化方法
public function __construct($machineId, $epoch = 1609459200000) {
$this->machineId = $machineId;
$this->epoch = $epoch;
$maxMachineId = (1 << self::MACHINE_ID_BITS) - 1;
if ($machineId > $maxMachineId) {
throw new Exception("Machine ID超出范围");
}
}
生成ID核心逻辑
public function generate() {
$timestamp = $this->currentTimestamp();
if ($timestamp < $this->lastTimestamp) {
throw new Exception("时钟回拨");
}
if ($timestamp == $this->lastTimestamp) {
$this->sequence = ($this->sequence + 1) & ((1 << self::SEQUENCE_BITS) - 1);
if ($this->sequence == 0) {
$timestamp = $this->waitNextMillis($this->lastTimestamp);
}
} else {
$this->sequence = 0;
}
$this->lastTimestamp = $timestamp;
return (($timestamp - $this->epoch) << (self::MACHINE_ID_BITS + self::SEQUENCE_BITS))
| ($this->machineId << self::SEQUENCE_BITS)
| $this->sequence;
}
辅助方法
private function currentTimestamp() {
return round(microtime(true) * 1000);
}
private function waitNextMillis($lastTimestamp) {
$timestamp = $this->currentTimestamp();
while ($timestamp <= $lastTimestamp) {
usleep(1000);
$timestamp = $this->currentTimestamp();
}
return $timestamp;
}
使用示例
$snowflake = new Snowflake(1); // 机器ID设为1
$id = $snowflake->generate();
echo $id; // 输出64位唯一ID
注意事项
- 机器ID分配:需确保不同服务的
machineId唯一,可通过配置文件或数据库分配。 - 时钟回拨处理:实际部署时需增加更健壮的时钟同步机制。
- 性能优化:高并发场景下建议结合队列或批量生成策略。
扩展方案
- 集成Redis:将
lastTimestamp和sequence存储到Redis,实现多实例协同。 - 缩短位数:调整各部分的位数分配(如减少
MACHINE_ID_BITS)以适应业务需求。







