雪花演算法

ssrheart發表於2024-06-07

一:概述

  - 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);

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026630/viewspace-2945122/,如需轉載,請註明出處,否則將追究法律責任。

相關文章