基於Twitter的雪花算法改造,分佈式全局惟一ID生成器

分佈式系統中咱們通常會對一些數據量大的業務進行拆分,如:訂單表,用戶表。由於數據量巨大一張表沒法承載。就會對其進行分庫分表。 但一旦涉及到分庫分表,就會引伸出分佈式系統中惟一主鍵ID的生成問題,永不遷移數據和避免熱點的文章中要求須要惟一ID的特性。php

分佈式id生成算法的有不少種,Twitter的SnowFlake就是其中經典的一種。web

本文介紹的是基於Twitter的SnowFlake的一種優化版本,默認支持的運行環境: php-fpm、shell-cli、php -S 127.0.0.1:80 模式下生成全局惟一ID算法

Twitter版SnowFlake

SnowFlake算法(簡稱雪花算法)生成64位的二進制正整數,而後轉換成10進制的數。64位二進制數由以下部分組成: shell

SnowFlake組成

優化後SnowFlake版本

基於Twitter的雪花算法改造,分佈式全局惟一ID生成器, 組成<毫秒級時間戳+機器ip+進程id+序列號>bash

長度最長爲64位bit,各bit位含義以下:服務器

  • 1位 不用。二進制中最高位爲1的都是負數,可是咱們生成的id通常都使用整數,因此這個最高位固定是0
  • 41位 用來記錄時間戳(毫秒)
    • 41位能夠表示2^{41}-1個數字,
    • 若是隻用來表示正整數(計算機中正數包含0),能夠表示的數值範圍是:0 至 2^{41}-1,減1是由於可表示的數值範圍是從0開始算的,而不是1。
    • 也就是說41位能夠表示2^{41}-1個毫秒的值,轉化成單位年則是(2^{41}-1) / (1000 * 60 * 60 * 24 * 365) = 69
  • 10位 機器IP低10位,能夠支持最多1023個機器節點
  • 10位 當前處理進程標識,10位的長度最多支持1023個機器進程
  • 2位 計數序列號,序列號即序列自增id,能夠支持同一節點的同一進程同一毫秒生成4個ID序號

優勢

一、此方案每秒可以產生409.6萬個ID,性能快
二、時間戳在高位,自增序列在低位,整個ID是趨勢遞增的,按照時間有序遞增
三、靈活度高,能夠根據業務需求,調整bit位的劃分,知足不一樣的需求
複製代碼

缺點

一、依賴機器的時鐘,若是服務器時鐘回撥,會致使重複ID生成
複製代碼

實用

經過composer包引用,引用到項目中

composer require webergiles/favorites

use WeberGiles\Favorites\Snowflake;

//生成一個全局惟一ID
echo Snowflake::uniqueId();

複製代碼
相關文章
相關標籤/搜索