>  기사  >  php教程  >  PHP에서 고유 ID를 생성하는 SnowFlake 알고리즘

PHP에서 고유 ID를 생성하는 SnowFlake 알고리즘

高洛峰
高洛峰원래의
2016-12-28 15:33:501363검색

서문: 최근에는 CMS 시스템을 구축해야 했고, 기능이 상대적으로 간단하고 요구 사항이 유연하기 때문에 WP와 같은 성숙한 시스템을 포기하고 직접 비교적 간단한 시스템을 구축했습니다. 기사 세부정보 페이지 URL을 의사 정적 URL 형식, 즉 xxx.html로 만들고 싶어 xxx에서 자동 증가 기본 키를 직접 사용하는 것을 고려했지만 이로 인해 기사 수가 노출될 수도 있다고 생각합니다. 초기값을 높게 설정할 수도 있지만 여전히 가능하다고 하는데, ID 차이를 기준으로 일정 기간 내 기사 수를 계산하므로 고유한 ID를 생성할 수 있는 알고리즘이 필요합니다.

고려된 방법은

타임스탬프를 직접 사용하거나, 이를 파생한 일련의 방법

Mysql 자체 uuid

위의 두 가지 방법 찾을 수 있으니 자세한 설명은 생략하겠습니다

결국 트위터의 SnowFlake 알고리즘을 선택했습니다

이 알고리즘의 장점은 매우 간단하고 약 400만 개의 서로 다른 16개를 생성할 수 있다는 것입니다. 초당 메시지 수(10진수)

원리는 매우 간단합니다

ID는 64비트로 구성됩니다

첫 번째 비트는 비어 있습니다

41비트. 밀리초를 저장하는 데 사용됩니다. 레벨 타임스탬프

10비트는 컴퓨터 ID를 저장하는 데 사용됩니다.

12비트는 자동 증가 ID를 저장하는 데 사용됩니다.

최상위 비트는 제외 사용할 수 없는 것으로 표시되면 나머지 세 비트 그룹이 사용됩니다. 특정 비즈니스 요구 사항에 따라 모두 부동될 수 있습니다. 기본적으로 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이 되도록 개선했습니다. 때로는 필요하지 않을 수도 있으므로 비트가 제거됩니다.

PHP에서 고유 ID를 생성하는 SnowFlake 알고리즘과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.