基于雪花算法生成用户id

8.1 为啥这样做

1.全局唯一性,不会出现重复的id。
	如果通过id自增来保证id不重复,则该表 无法分表操作
        例如 服务器A的数据库的user表 数据如下
        1 小明 男
        2 小红 女
        2 张三 男
        此时 进行分表 服务器B,C的数据库中创建user表 分别存储第2,3条数据
        B
        1 小红 女
        C
        1 张三 男
        此时存在问题,id重复
2.生成的id是随时间递增的,在执行sql操作时,会提高效率
3.每毫秒产生2^12-1个序列号,在高并发环境下表现良好

8.2 介绍雪花算法

雪花算法优点:

1.高并发分布式环境下生成不重复id
2.id随时间自增,在执行sql操作时,会提高效率

雪花算法缺点:

依赖于服务器时间,服务器时钟回拨时可能会生成重复id。
解决方法:通过记录最后一个生成id时的时间戳,每次生成id之前比较当前服务器时间是否回拨,避免生成重复id。
时钟回拨:硬件时钟可能会因为各种原因发生不准的情况,网络中提供了ntp服务来做时间校准,做校准时就会发生时钟的跳跃或者回拨。

64位整数组成的分布式ID

使用github.com/sony/sonyflake库的雪花算法

注意:下图中第三块和第四块标记反了,第三块为Machine ID(机器id) 第四块为Sequence ID(序列id)
在这里插入图片描述

1bit: 符号位,固定为0,没有实际作用
39bit: 表示 时间戳,单位是 10毫秒。用来代表创建ID的时刻与起始时刻的偏移量。起始时刻在雪花算法初始化时就指定 
8bit: 机器id。分布式部署时,可能有多台服务器都可以生成ID,使用机器id来表示唯一的服务器
16bit: 序列id,用来记录 同一毫秒产生的不同id 每毫秒可用生成2^16-1个id

8.3 代码

pkg/snowflake/snowflake.go

package snowflake

import (
	"fmt"
	"time"
	"web_app/setting"

	"github.com/sony/sonyflake"
)

var (
	sonyFlake     *sonyflake.Sonyflake // 实例
	sonyMachineID uint16               // 机器ID
)

func getMachineID() (uint16, error) { // 返回全局定义的机器ID
	return sonyMachineID, nil
}

// 需传入 指定日期 和 当前的机器ID
func Init(cfg *setting.SnowFlakeConfig) (err error) {
	sonyMachineID = cfg.MachineId
	//time.Parse(日期格式,具体日期) 参数类型 均为string
	t, _ := time.Parse("2006-01-02", cfg.InitTime) // 初始化一个开始的时间

	/**
	type Settings struct {
		StartTime      time.Time
		MachineID      func() (uint16, error)
		CheckMachineID func(uint16) bool
	}
	*/
	settings := sonyflake.Settings{ // 生成全局配置
		StartTime: t,
		//MachineID 字段 是函数类型
		MachineID: getMachineID, // 指定机器ID
	}
	sonyFlake = sonyflake.NewSonyflake(settings) // 用配置生成sonyflake节点
	return
}

// GetID 返回生成的id值
//数据表中 bigint(20) 啥意思 就是该字段的值 最大是一个20位的数
//对应go中 类型为 uint64 也就是 该数用2进制表示 是64位2^64 的值 是一个无符号的20位的数
func GetID() (id uint64, err error) { // 拿到sonyflake节点生成id值
	if sonyFlake == nil {
		err = fmt.Errorf("snoy flake not inited")
		return
	}

	id, err = sonyFlake.NextID()
	return
}

config.yaml中雪花算法配置信息

#雪花算法
snowflake:
  init_time: "2022-7-28"
  machine_id: "1"

setting.go中雪花算法 配置信息结构体

//雪花算法配置
type SnowFlakeConfig struct {
	InitTime  string `mapstructure:"init_time"`
	MachineId uint16 `mapstructure:"machine_id"`
}

main.go中调用雪花算法

//7. 使用雪花算法 生成用户id
if err := snowflake.Init(setting.Conf.SnowFlakeConfig); err != nil {
    fmt.Printf("init snowflake failed, err :%v\n", err)
    return
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值