Snowflake 介绍和使用

 

一、介绍

Snowflake 是 Twitter 内部的一个 ID 生算法,可以通过一些简单的规则保证在大规模分布式情况下生成唯一的 ID 号码。其组成为:

  • 第一个 bit 为未使用的符号位。
  • 第二部分由 41 位的时间戳(毫秒)构成,他的取值是当前时间相对于某一时间的偏移量。
  • 第三部分和第四部分的 5 个 bit 位表示数据中心和机器ID,其能表示的最大值为 2^5 -1 = 31。
  • 最后部分由 12 个 bit 组成,其表示每个工作节点每毫秒生成的序列号 ID,同一毫秒内最多可生成 2^12 -1 即 4095 个 ID。

需要注意的是:

  • 在分布式环境中,5 个 bit 位的 datacenter 和 worker 表示最多能部署 31 个数据中心,每个数据中心最多可部署 31 台节点
  • 41 位的二进制长度最多能表示 2^41 -1 毫秒即 69 年,所以雪花算法最多能正常使用 69 年,为了能最大限度的使用该算法,你应该为其指定一个开始时间。

雪花算法生成的 ID 并不能保证唯一,如当两个不同请求同一时刻进入相同的数据中心的相同节点时,而此时该节点生成的 sequence 又是相同时,就会导致生成的 ID 重复。

二、安装和使用(php)

1.安装

composer require godruoyi/php-snowflake -vvv

2.使用

2.1 简单使用
 

$snowflake = new \Godruoyi\Snowflake\Snowflake; $snowflake->id();

//指定机器id(减小生成相同id的概率)

$snowflake = new \Godruoyi\Snowflake\Snowflake($datacenterId, $workerId); $snowflake->id();

//指定开始时间

$snowflake = new \Godruoyi\Snowflake\Snowflake; $snowflake->setStartTimeStamp(strtotime('2019-08-08')*1000); $snowflake->id();

2.2 高级使用(在laravel中使用)

①.服务提供者中进行注册
/App\Providers\AppServiceProvider

use Godruoyi\Snowflake\Snowflake;
use Godruoyi\Snowflake\LaravelSequenceResolver;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('snowflake', function () {
            return (new Snowflake())
                ->setStartTimeStamp(strtotime('2019-08-08')*1000)
                ->setSequenceResolver(
                    new LaravelSequenceResolver($this->app->get('cache')->store()
                ));
        });
    }
}
②.在model中使用 


<?php

namespace App\Models;

use Aiadtech\Utils\Snowflake\Traits\LaravelModelTrait;
use Illuminate\Database\Eloquent\Model as BaseModel;
use DateTimeInterface;
use DateTime;

/**
 * @mixin \Illuminate\Database\Eloquent\Builder
 * @method static bool insert(array $values)
 * @method static static where(string $column, $operator = null, $value = null, $boolean = 'and')
 * @method static static whereIn($column, $values, $boolean = 'and', $not = false)
 * @method static static whereDate(string $column, $operator, $value = null, $boolean = 'and')
 * @method static static whereBetween(string $column, array $values, $boolean = 'and', $not = false)
 */
class Model extends BaseModel
{
    use LaravelModelTrait;

    const CREATED_AT = 'create_time';

    const UPDATED_AT = 'update_time';

    public $incrementing = false;

    /**
     * 为数组 / JSON 序列化准备日期。
     *
     * @param DateTimeInterface $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date): string
    {
        return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
    }

    /**
     * @param $raw_time
     * @return string
     * @throws \Exception
     */
    public function getCreateTimeAttribute($raw_time): string
    {
        return $this->dateTimeFormat($raw_time);
    }

    /**
     * 格式化更新时间
     * @param $raw_time
     * @return string
     * @throws \Exception
     */
    public function getUpdateTimeAttribute($raw_time): string
    {
        return $this->dateTimeFormat($raw_time);
    }

    /**
     * 格式化时间
     * @param $raw_time
     * @param string $format
     * @return string
     * @throws \Exception
     */
    public function dateTimeFormat($raw_time, string $format = 'Y-m-d H:i:s'): string
    {
        return (new DateTime($raw_time))->format($format);
    }

}
③.注意事项

在保存数据的时候使用save()方法或者create()方法,会自动填充id,

数据表结构中,id字段要设置为biginteger 主键,非自增。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值