一:概述
- SnowFlake 算法
- 是 Twitter 開源的分布式 id 生成算法。
- 應用場景
- 高性能的產生不重復ID,支持集群的橫向擴展。
二:原理
- 其核心思想就是:
- 使用一個 64 bit 的 long 型的數字作為全局唯一 id。
- 在分布式系統中的應用十分廣泛,且ID 引入了時間戳,基本上保持自增的。
- 產生公式
- | 0(最高位預留) | 時間戳(41位) | 機器ID(10位) | 隨機序列(12位) |
- 形成 64位bit
三:實現解析
- 0(最高位預留)
- 因為二進制里第一個 bit 為如果是 1,那么都是負數,但是我們生成的 id 都是正數,所以第一個 bit 統一都是 0。
- 時間戳(41位)
- 41 bits 的 Timestamp,每次要生成一個新 ID 的時候,都會獲取一下當前的 Timestamp,保證每個timestamp都是不同的。
- 機器ID(10位)
- 10 bits 的機器號, 在 ID 分配 Worker 啟動的時候,從一個 集群獲取 (保證所有的 Worker 不會有重復的機器號)。
- 隨機序列(12位)
- 12 bit 隨機數。
- 組成 64 位 bits,成為 10 進制的 16 位 unique Id
四:代碼簡單實現
-
<?php /** * 雪花算法 * 其核心思想就是: * 使用一個 64 bit 的 long 型的數字作為全局唯一 id。 * 在分布式系統中的應用十分廣泛,且ID 引入了時間戳,基本上保持自增的。 * 產生公式 * | 0(最高位預留) | 時間戳(41位) | 機器ID(10位) | 隨機序列(12位) | */ class IdCreate { const max12bit = 4095; public static function createOnlyId() { // 獲取微秒時間戳(42位),截取並轉化為 41位二進制 $microtime = decbin(floor(microtime(true) * 1000)); // 10bit 的機器號,由集群產出 $machineId = self::machine(); // 12bit 的隨機數 $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT); // 拼接 $base = '0' . $microtime . $machineId . $random; // 十進制 返回 return bindec($base); } /** * 集群 * @param int $machineId * @return string */ public static function machine($machineId = 0) { return str_pad($machineId, 10, "0", STR_PAD_LEFT); } } $cast_id = IdCreate::createOnlyId(); var_dump($cast_id);