snowflake雪花算法

snowflake雪花算法

雪花算法是由Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增。
请添加图片描述

为什么叫分布式ID生成器?
因为10bit-工作机器id。
雪花算法(Snowflake Algorithm)之所以适用于分布式系统,并能够被称为分布式ID生成算法,主要是因为它考虑到了分布式系统中不同节点独立生成ID的需求,通过结构化的ID格式和算法设计,确保了每个节点生成的ID既唯一又有序。

了解了原理,接下来看看实现:

package snowflake

import (
	"time"
	//这里导包,然后给这个包取个别名,这样的好处是方便调用。
	sf "github.com/bwmarrin/snowflake"
)

//定义一个sf.Node类型的全局变量,这个在雪花算法中代表一个结点或服务实例。
//每个结点有唯一的machineID
var node *sf.Node
//初始化函数,用于初始化雪花算法的节点。
//startTime字符串表示雪花算法的起始时间,这个时间是算法生成ID时参考的基点
//machineID参数是节点或服务实例的唯一标识
func Init(startTime string, machineID int64) (err error) {
	
	首先使用time.Parse解析startTime字符串位time.Time对象 st
	var st time.Time
	st, err = time.Parse("2006-01-02", startTime)
	if err != nil {
		return
	}
	//设置雪花算法的起始时间Epoch time。
	//雪花算法中,时间戳部分通常是以算法定义的起始时间为基准,然后计算当前时间与起始时间的差值,这样做可以在64位整数中,有效的利用起时间戳部分,从而在很长的时间生成一个很长的id。
	//sf.Epoch在雪花算法库中就是用来定义起始时间的变量。Epoch time是雪花算法生成ID时参考的基准时间点。
	//st.UnixNano()这个方法返回st时间对应的Unix纳秒时间戳,这个时间戳就是以纳秒为单位。
	// 除1000000是因为雪花算法中通常使用的是毫秒级的时间戳,所以这里是纳秒转毫秒。
	//所以总的来说这里是自定义的起始时间st转换为毫秒级的Unix时间戳,并将其设置为雪花算法额起始时间。经过这样的配置之后,后续生成id的时间戳部分就是基于这个自定义起始时间来计算的。
	sf.Epoch = st.UnixNano() / 1000000
	//创建一个新的雪花算法节点。machineID用于确保每个节点生成的id是唯一的
	node, err = sf.NewNode(machineID)
	return
}
//这个函数就是调用了全局变量node的Generate方法来生成一个新的ID。
//但是这个函数生成的ID是sf.ID类型,所以这里要进行一个强制类型转换成int64类型的ID。
//这样得到的ID是唯一的,并且随时间自增。
func GenID() int64 {
	return node.Generate().Int64()
}

func Parse(layout, value string) (Time, error)
这个我要解读一下,这个是go标准库的函数,用于解析时间字符串的函数,它的作用是将一个指定格式的字符串解析位time.Time类型的时间对象。
layout 参数制定了输入的时间字符串应该匹配的格式,go语言中使用一种特殊的表示方法来定义时间格式:“2006-01-02 15:04:05”。这个字符串代表的是Go的诞生时间(2006年1月2日15时4分5秒),你可以通过改变这个字符串中的日期和时间部分来定义自己的时间格式。例如,仅使用日期部分"2006-01-02"表示年-月-日格式。

value参数是实际要解析的时间字符串,它应该与layout参数指定的格式相匹配。
所以说这个函数的作用就是把starttime解析成time.Time格式。

再来看看生成ID的源码:

func (n *Node) Generate() ID {
	//加锁,这就是保证生成ID的过程线程安全
	n.mu.Lock()
	//计算当前时间戳与起始时间之前的差值,单位是纳秒,然后再除1000000转毫秒级
	now := time.Since(n.epoch).Nanoseconds() / 1000000
	//处理序列号
	//如果当前的毫秒时间戳now与上一次生成ID时的时间戳n.time相同,则序列号+1,保证再统一毫秒内生成的ID是唯一的。序列号通过n.stepMask进行位与操作,确保序列号的范围有效如果序列号用尽(即n.step变为0),则通过循环等待直到下一毫秒。
	if now == n.time {
		n.step = (n.step + 1) & n.stepMask
		//这里就是如果序列号用尽即n.step==0,就循环等待直到下一毫秒。
		if n.step == 0 {
			for now <= n.time {
				//到了下一毫秒这里再更新时间戳
				now = time.Since(n.epoch).Nanoseconds() / 1000000
			}
		}
	} else {
		//每次判断过后序列号都要从置为0
		n.step = 0
	}
	//更新时间戳
	n.time = now
	//这里是根据雪花算法的位数规则,进行唯一,将时间戳,结点id和序列号组成一个64位的ID,时间戳部分通过左移n.timeShift位,结点id通过左移n.nodeShift位,序列号直接加在最低位。
	r := ID((now)<<n.timeShift |
		(n.node << n.nodeShift) |
		(n.step),
	)
	
	//解锁并返回ID。
	n.mu.Unlock()
	return r
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/407529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opengl 学习纹理

一.纹理是什么&#xff1f; 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节&#xff1b;类似于图像一样&#xff0c;纹理也可以被用来储存大量的数据&#xff0c;这些数据可以发送到着色器上。 采样是指用纹理坐标来获取纹…

代码随想录算法训练营第50天|123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

文章目录 123.买卖股票的最佳时机III思路代码 188.买卖股票的最佳时机IV思路代码 123.买卖股票的最佳时机III 题目链接&#xff1a;123.买卖股票的最佳时机III 文章讲解&#xff1a;代码随想录|123.买卖股票的最佳时机III 视频讲解&#xff1a;123.买卖股票的最佳时机III 思路 …

7分钟0基础彻底理解常用数据压缩原理---哈夫曼编码

前言 如果你之前没有做过数据压缩&#xff0c;或者想要了解数据压缩的原理&#xff0c;那么这编文章将会帮到你。这编文章将会带你彻底了解哈夫曼编码原理&#xff0c;这种编码方式常用作的图片无损压缩&#xff0c;和ZIP的等压缩存储。 思考&#xff0c;计算机的存储与解析获…

消息中间件篇之RabbitMQ-延时队列

一、延时队列 延迟队列&#xff1a;进入队列的消息会被延迟消费的队列。 场景&#xff1a;超时订单、限时优惠、定时发布。 延迟队列死信交换机TTL&#xff08;生存时间&#xff09;。 二、死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xf…

LVS的工作模式及其原理

1、LVS 介绍 &#xff08;1&#xff09;LVS 是Linux Virtual Server的简称&#xff0c;也就是 Linux 虚拟服务器, 是一个由章文嵩博士发起的自由软件项目&#xff0c;它的官方站点是www.linuxvirtualserver.org。现在LVS已经是 Linux标准内核的一部分&#xff0c;因此性能较高…

注册中心 Service Discovery --- Intro

注册中心 Service Discovery --- Intro 为什么需要注册中心注册中心的原理常用的注册中心注册中心的高可用 为什么需要注册中心 在微服务架构中&#xff0c;系统被拆分成了若干个独立的服务&#xff0c;因此服务之间需要进行通信和协作。为了实现服务的发现和调用&#xff0c;需…

一周学会Django5 Python Web开发-Django5二进制文件下载响应

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计25条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

CrossOver 24.0.0 for mac 震撼发布 2024最新下载安装详细图文教程

2024年2 月 23 日消息&#xff0c;CodeWeavers 近日发布了 CrossOver 24 版本更新&#xff0c;基于近期发布的 Wine 9.0&#xff0c;不仅兼容更多应用和游戏&#xff0c;还初步支持运行 32 位应用程序。 苹果在 macOS Catalina 系统中移除对 32 位软件的支持之后&#xff0c;在…

08 Redis之集群的搭建和复制原理+哨兵机制+CAP定理+Raft算法

5 Redis 集群 2.8版本之前, Redis采用主从集群模式. 实现了数据备份和读写分离 2.8版本之后, Redis采用Sentinel哨兵集群模式 , 实现了集群的高可用 5.1 主从集群搭建 首先, 基本所有系统 , “读” 的压力都大于 “写” 的压力 Redis 的主从集群是一个“一主多从”的读写分…

K线实战分析系列之三:吞没形态

K线实战分析系列之三&#xff1a;吞没形态 一、吞没形态二、看涨吞没形态三、看跌吞没形态四、吞没形态判别标准 一、吞没形态 两根或两根以上的K线形成的组合形态&#xff0c;吞没形态就是一种主要的反转形态。 这个形态由两根K线组成&#xff0c;前短后长&#xff0c;一阴一…

Python爬虫-存储到csv乱码-使用utf-8-sig编码

代码 import requests import csvdef get_data():url https://careers.tencent.com/tencentcareer/api/post/Query?timestamp1708743664770&countryId&cityId&bgIds&productId&categoryId&parentCategoryId&attrId&keywordpython&pageIn…

保姆级教程!安利一款Kali Linux 安装 + 获取 root 权限 + 远程访问!

一、什么是Kali kali是linux其中一个发行版&#xff0c;基于Debian&#xff0c;前身是BackTrack&#xff08;简称BT系统&#xff09;。kali系统内置大量渗透测试软件&#xff0c;可以说是巨大的渗透系统&#xff0c;涵盖了多个领域&#xff0c;如无线网络、数字取证、服务器、…

构建未来新零售平台的设计与实现的总结

随着科技的飞速发展和消费者需求的不断变化&#xff0c;新零售已经成为零售行业的新趋势。在这个数字化时代&#xff0c;构建一个高效、智能、一体化的新零售平台架构至关重要。本文将探讨如何设计和实现一个具备创新性和竞争力的新零售平台。 引言&#xff1a; 新零售是指利用…

十一、Qt数据库操作

一、Sql介绍 Qt Sql模块包含多个类&#xff0c;实现数据库的连接&#xff0c;Sql语句的执行&#xff0c;数据获取与界面显示&#xff0c;数据与界面直接使用Model/View结构。1、使用Sql模块 &#xff08;1&#xff09;工程加入 QT sql&#xff08;2&#xff09;添加头文件 …

面试redis篇-05双写一致

原理 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间写操作:延迟双删方案一:分布式锁,一致性要求高

C语言之mkdtemp()特定占位符:XXXXXX 用法实例(八十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

2.deeplabv3+的主干网络(mobilenet网络)

deeplabv3的论文中用了resnet网络&#xff0c;在这里用轻量级网络mobilenet替换resnet&#xff0c;下面分别是两个网络的代码。 1.mobilenet网络 代码如下&#xff1a; import math import os import cv2 import numpy as np import torch import torch.nn as nn import tor…

STM32_DS18B20_1_芯片简介及初始化配置

DS18B20介绍 DS18B20数字温度计提供9位到12位摄氏度的温度测量&#xff0c;并具有非易失性&#xff0c;用户可编程的上下触发点的报警功能。DS18B20通过1线总线进行通信&#xff0c;根据定义&#xff0c;该总线只需要一条数据线&#xff0c;即可与中央微处理器进行通信…

NestJS入门7:增加异常过滤器

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 NestJS入门4&#xff1a;MySQL typeorm 增删改查 NestJS入门5&#xff1a;加入Swagger NestJS入门6&#xff1a;日志中间件 本文代码基于上一篇文章《…

Flink join详解(含两类API及coGroup、connect详解)

Flink SQL支持对动态表进行复杂而灵活的连接操作。 为了处理不同的场景&#xff0c;需要多种查询语义&#xff0c;因此有几种不同类型的 Join。 默认情况下&#xff0c;joins 的顺序是没有优化的。表的 join 顺序是在 FROM 从句指定的。可以通过把更新频率最低的表放在第一个、…