PHPで一意のIDを生成するSnowFlakeアルゴリズムの詳細説明

墨辰丷
リリース: 2023-03-28 11:00:01
オリジナル
1677 人が閲覧しました

スノーフレークアルゴリズムとは何ですか?まず最初に質問させてください。分散システム内で一意の ID を生成し、ID が自動的に増加し続けるようにするにはどうすればよいでしょうか。これは Twitter にとって最も重要なビジネス シナリオであるため、Twitter はスノーフレーク アルゴリズムを開始しました。

前書き: 最近 CMS システムを構築する必要があり、機能が比較的シンプルで要件が柔軟なので、WP のような成熟したシステムをあきらめて、比較的シンプルなシステムを自分で構築しました。記事詳細ページの URL を擬似静的 URL 形式、つまり xxx.html にしたいと考えています。xxx では、自動インクリメントされる主キーを直接使用することを検討していますが、これでは記事数がバレてしまう可能性があると感じています。初期値を高く設定できるとのことですが、それでも可能です。期間内の記事数は ID の差に基づいて計算されるため、固有の ID を生成できるアルゴリズムが必要です。

私が検討した方法には、

  1. タイムスタンプを直接使用する方法、またはそこから派生した一連の方法

  2. Mysqlに付属のuuid

上記の2つの方法が見つかるので、勝ちました説明は大したことはありません

最終的に選択したのは Twitter の SnowFlake アルゴリズムです

このアルゴリズムの利点は非常にシンプルで、1 秒あたり約 400 万の異なる 16 桁の ID (10 進数) を生成できます

原理は非常に簡単です。

IDは64ビット構成で構成されます

最初のビットは空です

41ビットはミリ秒レベルのタイムスタンプの保存に使用されます

10ビットはマシンIDの保存に使用されます

12ビットは自動インクリメントIDの保存に使用されます

例外使用不可としてマークされた最上位ビットについては、他の 3 つのグループ ビット占有は、特定のビジネス要件に応じて変動させることができます。デフォルトでは、41 ビットのタイムスタンプは 2082 年までこのアルゴリズムの使用をサポートし、10 ビットの作業マシン ID は 1023 台のマシンをサポートし、シリアル番号は 4095 個の自動インクリメント シーケンス ID の生成に 1 ミリ秒をサポートします。

以下はPHPのソースコードです
​​

<?php
namespace App\Services;

abstract class Particle {
  const EPOCH = 1479533469598;
  const max12bit = 4095;
  const max41bit = 1099511627775;

  static $machineId = null;

  public static function machineId($mId = 0) {
    self::$machineId = $mId;
  }

  public static function generateParticle() {
    /*
    * Time - 42 bits
    */
    $time = floor(microtime(true) * 1000);

    /*
    * Substract custom epoch from current time
    */
    $time -= self::EPOCH;

    /*
    * Create a base and add time to it
    */
    $base = decbin(self::max41bit + $time);


    /*
    * Configured machine id - 10 bits - up to 1024 machines
    */
    if(!self::$machineId) {
      $machineid = self::$machineId;
    } else {
      $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
    }
    
    /*
    * sequence number - 12 bits - up to 4096 random numbers per machine
    */
    $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);

    /*
    * Pack
    */
    $base = $base.$machineid.$random;

    /*
    * Return unique time id no
    */
    return bindec($base);
  }

  public static function timeFromParticle($particle) {
    /*
    * Return time
    */
    return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
  }
}

?>
ログイン後にコピー

呼び出し方法は以下の通りです

Particle::generateParticle($machineId);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳
ログイン後にコピー

ここでマシンIDが0を渡すと10ビットが削除されることがあるため改良を加えました。あまり多くのIDを使用する必要はありません

以上がこの記事の全内容ですが、皆様の勉強に少しでもお役に立てれば幸いです。


関連する推奨事項:

php の一意の番号idに生成する メソッドの概要、phpidに生成する 概要

【php】mysqlグローバルID ソリューション、phpmysqlグローバルに生成 id

php に生成 一意のid 詳細な説明

以上がPHPで一意のIDを生成するSnowFlakeアルゴリズムの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!