Python 实现雪花算法

news/2024/5/9 15:12:36/文章来源:https://www.cnblogs.com/Blogwj123/p/16614304.html

Python 实现雪花算法

雪花算法:雪花算法是一种分布式全局唯一ID,一般不需要过多的深入了解,一般个人项目用不到分布式之类的大型架构,另一方面,则是因为,就算用到市面上很多 ID 生成器帮我们完成了这项工作。

介绍:Twitter 于 2010 年开源了内部团队在用的一款全局唯一 ID 生成算法 Snowflake,翻译过来叫做雪花算法。Snowflake 不借助数据库,可直接由编程语言生成,它通过巧妙的位设计使得 ID 能够满足递增属性,且生成的 ID 并不是依次连续的。

参考文章:https://www.cnblogs.com/oklizz/p/11865750.html

1.原理及介绍

Snowflake 是 Twitter 提出的一个算法,其目的是生成一个64位的整数;

64位的分布图如下图所示:

雪花算法

  • 1 bit:一般是符号位,不做处理。
  • 41bit : 用来记录时间戳,这里可以记录69年,如果设置好起始时间,比如今年是 2022 ,那么可以用到 2091 年,到时候怎么办,这个系统要是能够使用 69 年,估计系统早已经优化过很多次了。
  • 10bit : 用来记录机器ID,总共可以记录1024台机器,一般用前5位代表数据中心,后面5位是某个数据中心的机器ID。(注:位数可以根据情况进行设定。)
  • 12bit:循环用来对同一个毫秒内产生的不同的 ID,12位可以最多记录4095(212-1)次,多余的需要在下一毫秒进行处理。

上面是一个将64bit划分标准,当然也不一定这么做,可以根据不同的业务的具体场景进行行划分,例如:

  1. 服务目前QPS10万,预计几年之内会发展到百万。

  2. 当前机器三地部署,上海,北京,深圳都有。

  3. 当前机器10台左右,预计未来会增加至百台。

这个时候我们根据上面的场景可以再次合理的划分62 bit,QPS 几年之内会发展到百万,那么每毫秒就是千级的请求,目前 10 台机器那么每台机器承担百级的请求,为了保证扩展,后面的循环位可以限制到 1024,也就是2^10,那么循环位10位就足够了

机器三地部署我们可以用3bit总共8来表示机房位置,当前的机器10台,为了保证扩展到百台那么可以用7bit 128来表示,时间位依然是41bit,那么还剩下64-10-3-7-41-1 = 2bit,还剩下2bit可以用来进行扩展。

复制

时钟回拨:因为机器的原因会发生时间回拨,雪花算法是强依赖时间的,如果发生时间回拨,有可能会发生重复ID,在我们上面的nextId中我们用当前时间和上一次时间进行判断,如果当前时间小于上一次的时间,那么肯定是发生了回拨,算法会直接抛出异常。

2.实现

2.1 知识补充

  • python中为位运算

    运算符 描述 实例
    << 左移运算符:运算数的各二进位全部左移若干位,
    <<右边的数字指定了移动的位数,高位丢弃(前面无效的0),低位补0.
    60 << 2 = 240
    >> 右移运算符:把>>左边的的运算数的各二进位全部
    右移若干位,运算符右边的数字指定了右移的位数。
    低位丢弃(无效的0),高位补0.
    60>>2 = 15
    ^ 按位异或运算符:当两两对应的二进位相异时,结果取1. 01^11 = 10
    a = 60 # 60 的二进制位数是: 0011 1100 (111100)print(a << 2) # 0011 1100 左移两位 1111 0000 = 240print(a >> 2) # 0011 1100 右移两位 0000 1111 = 15
    

    image-20220819153440572

    # ^ 二进制之间的异或运算,当两值不同的时候为 1.
    8 ^ 16 = 24
    # 0000 1000   8 
    # 0001 0000	  16
    # 0001 1000   24   结果
    

    image-20220819154645947

  • 回顾 bin 函数

    bin()函数的返回值要从Ob之后开始阅读。

    image-20220819151336024

2.2 算法实现

import time
import loggingfrom exceptions import InvalidSystemClock # 继承的Excpetion即可。# 64 位 id 的划分,通常机器位和数据位各为 5 位
WORKER_ID_BITS = 5 # 机器位
DATACENTER_ID_BITS = 5 # 数据位
SEQUENCE_BITS = 12 # 循环位# 最大取值计算,计算机中负数表示为他的补码
MAX_WORKER_ID = -1^(-1 << WORKER_ID_BITS) # 2**5 -1 =31
MAX_DATACENTER_ID = -1 ^(-1 << DATACENTER_ID_BITS)# 移位偏移计算
WORKER_ID_SHIFT = SEQUENCE_BITS
DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS
TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS# X序号循环掩码
SEQUENCE_MASK = -1^(-1 << SEQUENCE_BITS)# Twitter 元年时间戳
TWEPOCH = 1288834974657logger = logging.getLogger('雪花算法')class IdWorker(object):'''用于生成IDS.'''def __init__(self,datacenter_id,worker_id,sequence=0):'''初始化方法:param datacenter_id:数据id:param worker_id:机器id:param sequence:序列码'''if worker_id > MAX_WORKER_ID or worker_id <0:raise ValueError('worker_id 值越界')if datacenter_id >MAX_DATACENTER_ID or datacenter_id < 0:raise ValueError('datacenter_id 值越界')self.worker_id = worker_idself.datacenter_id = datacenter_idself.sequence = sequenceself.last_timestamp = -1 # 上次计算的时间戳def _gen_timestamp(self):'''生成整数时间戳。:return:'''return int(time.time()*1000)def get_id(self):'''获取新的ID.:return:'''# 获取当前时间戳timestamp = self._gen_timestamp()# 时钟回拨的情况if timestamp < self.last_timestamp:logging.error('clock is moving backwards. Rejecting requests util {}'.format(self.last_timestamp))raise InvalidSystemClockif timestamp == self.last_timestamp:# 同一毫秒的处理。self.sequence = (self.sequence+1) & SEQUENCE_MASKif self.sequence == 0:timestamp =self._til_next_millis(self.last_timestamp)else:self.sequence = 0self.last_timestamp =timestampnew_id = (((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT)|(self.datacenter_id << DATACENTER_ID_SHIFT)|(self.worker_id << WORKER_ID_SHIFT))|self.sequencereturn new_iddef _til_next_millis(self,last_timestamp):'''等到下一毫秒。:param last_timestamp::return:'''timestamp = self._gen_timestamp()while timestamp <= last_timestamp:timestamp = self._gen_timestamp()return timestampif __name__ == '__main__':worker = IdWorker(1,2,0)print(worker.get_id())

image-20220819210716468

2.3 第三方包的使用

pip install pysnowflake

启动服务

snowflake_start_server --worker=1

image-20220819212353337

编写程序,获取id

from snowflake import clientprint(client.get_guid())

image-20220819212502856

继续努力,终成大器!

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

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

相关文章

Python小游戏——外星人入侵(保姆级教程)第一章 06让飞船移动

Python小游戏——外星人入侵(保姆级教程) 第一章:武装飞船 06:让飞船移动 下面来让玩家能够左右移动飞船。我们将编写代码,在用户按左或右箭头键时做出响应。我们将首先专注于向右移动,再使用同样的原理来控制向左移动。通过这样做,你将学会如何控制屏幕图像的移动。系列…

web安全 - xss攻击与防御

xss(Cross-Site Scripting), 跨站脚本攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。 利用恶意脚本攻击者可以获取用户的敏感信息,Cookie, SessionID等,进而危害数据安全。 1. xss 类型 1. 存储型xss: 恶意脚本来源于数据库 由于恶意代码存储在服务器…

[NOIP2001 提高组] 一元三次方程求解

题目链接:https://www.luogu.com.cn/problem/P1024 试题分析: 三个答案都在[-100,100]范围内,两个根的差的绝对值>=1,保证了每一个大小为1的区间里至多有1个解,也就是说当区间的两个端点的函数值异号时区间内一定有一个解,同号时一定没有解。那么我们可以枚举互相不重叠…

oracle时间对比报错:ORA-01861 文字与格式字符串不匹配

前段时间写一个简单的需求时碰到的,在使用传入的时间参数与oracle数据库里存的时间进行比较时报错,具体错误如下:在Oracle中,需要使用to_date 格式化时间,再进行对比SELECT * FROM XXXXXXX t WHERE t.DATE BETWEEN to_date(2021-07-08 00:00:00,yyyy-mm-dd hh24:mi:ss…

大家都能看得懂的源码 - 封装一个管理 url 状态的 hook

本文是深入浅出 ahooks 源码系列文章的第十一篇,该系列已整理成文档-地址。觉得还不错,给个 star 支持一下哈,Thanks。 本文来讲下 ahooks 中的 useUrlState。通过 url query 来管理 state 的 Hook。useUrlState 的特殊 在之前的架构篇中我们就提到,ahooks 这个项目是一个 …

Element Ui使用技巧——Form表单的校验规则rules详细说明;element的 form 表单rules详细用法

介绍 Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator文档中提及的用法有2种: 官方form 表单文档 https://element.eleme.io/#/zh-CN/component/form 1.对整个…

ssh连接windows10拒绝连接-SSH入站-windows开启SSH

第一步:ssh使用的22端口,首先确认windows10的22端口是否开启。--开启步骤 1.控制面板-->Windws Defender 防火墙-->高级设置-->入站规则-->新建规则2.选择端口-->下一步3.选择TCP-->输入开放的端口-->下一步4.允许连接-->下一步5.勾选 域、专用、公用…

测试右移-后台服务监控告警实践

前言 前段时间,公司上线了“大屏”项目,用于对接展示一些业务平台的数据。但是在上线后使用过程中,产品或业务经常反馈前台页面没有数据。出现这种情况后,开发人员会去排查问题,解决后再通知产品或业务人员解决修复情况。虽然研发每次都能在较短的时间内响应并解决问题,但…

windows许可证即将过期?快来小编告诉你解决方法

https://baijiahao.baidu.com/s?id=1598094917004791962&wfr=spider&for=pc很多使用win10系统的用户都有遇到过电脑提示你的windows许可证即将过期的问题,遇到许可证即将过期要怎么办呢?小编这里给大家介绍一下这个问题的解决方法。Windows系统都需要激活后才能使用…

TypeScript 数组中查找最小、最大n个元素

TypeScript 数组中查找最小、最大n个元素var typeArr:number[]=[1,10,50,6,80,9,100];//最小元素private minArr(arr:number[]){let minArray:number[]=[];//3 就是返回多少个for (let i = 0; i < 3; i++) {let min = arr[0]; for (let j = 0; j < arr.length…

多列转两列(Power Query)

问题:多列转一列,如下图,左表转成右表let源 = Excel.CurrentWorkbook(){[Name="表2"]}[Content],拆分列 = Table.ToColumns(源),列分组 = List.Split(拆分列, 2),列合并 = List.Transform(列分组, each Table.FromColumns(_)),升表头 = List.Transform(列合并, ea…

Android开发

1.知识点解析 1.1 dimen1.尺寸资源;2.在工程的res\layout\目录下创建一个test_dimen.xml布局文件。3.在该布局文件中添加一个TextView和一个Button。4.TextView的宽和高引用尺寸资源来设置,android:width="@dimen/text_width"5.dimen定义:<resources><di…

项目管理 WBS 分解法 All In One

项目管理 WBS 分解法 All In One Work Breakdown Structure 工作分解结构项目管理 WBS 分解法 All In OnePMPWork Breakdown Structure / 工作分解结构WBS工作分解结构跟因数分解是一个原理,就是把一个项目,按一定的原则分解,项目分解成任务,任务再分解成一项项工作,再把一…

如何在电脑桌面上显示待办任务清单?

如果你每天的待办工作任务都是很多的,那么你应该如何保证自己能够把每条待办任务管理的井井有条,并且按时完成每项工作任务呢?相信这是很多职场人士都面临的一个难题,每天的工作时间都是固定的,但工作任务却是又多又繁杂,所以就需要大家通过管理待办任务来提高办公效率。…

Stream流-流式思想概述和获取流

流式思想概述 整体来看,流式思想类似于工厂车间的“生产流水线”。 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个“模型”步骤 方案,然后再按照方案去执行他 这张图中展示了过滤、映射、跳过、计数等多步操作,这是一种集合…

仓库的种类和彼此关系与Maven标准目录结构

仓库的种类和彼此关系 仓库分为三类:本地仓库,远程仓库,中央仓库 三类仓库直间的关系:在默认情况下启动一个Maven工程会从本地仓库找jar包,如果本地没有在连网状态下会从中央仓库下载jar包在公司中启动一个Maven工程会从本地仓库找jar包,本地没有会去远程仓库下jar包,如…

Fecify 自建私有化saas跨境商城系统

作为跨境的运营者,有多站需求的用户,可以通过wp,magento,fecmall等搭建多个跨境独立站,需要每个独立站单独安装,安装模板插件,配置等等,后续的管理维护比较繁琐,大多数的开源性能低下,插件安装冲突,模板调整问题等等,对于没有技术的个人和小公司,掌控难度高,很多…

# 【博学谷学习记录】超强总结,用心分享 | RabbitMQ消息的可靠性

RabbitMQ消息的可靠性消息队列在使用过程中,如何确保RabbitMQ消息的可靠性,如何确保发送的消息至少被消费一次?1.生产者消息确认 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。这种机制必须给每个消息指定一个唯一ID。消息发送到MQ以后,会返回一个结…

Learn Dijkstra For The Last Time

博客链接:https://www.codein.icu/learn-dijkstra/ Introduction Dijkstra 算法是用于求解非负权图单源最短路的经典算法。 市面上的大部分教程都仅仅停留在「如何实现 Dijkstra 算法」的层面。从应用角度,这当然无可厚非。但理解算法本身,也不失为一件乐事。 问自己这样几个…

自己de搭建博客记录

鸽子啊鸽子一去不复返自己de搭建博客记录因为奇奇怪怪的原因所以开始学着自己搭建一个博客了 但是估计搭好了也不会常更新,连博客园都咕了一个月了 先水水免得自己忘记了,要学的还有挺多 突然发现博客阅读量猛涨,看了下貌似是N2的插件文章被爬到各种奇怪网站了-1 参考资料 参…