如何通过雪花算法用Python实现一个简单的发号器


Posted in Python onJuly 03, 2019

实现一个简单的发号器

根据snowflake算法的原理实现一个简单的发号器,产生不重复、自增的id。

1.snowflake算法的简单描述

如何通过雪花算法用Python实现一个简单的发号器

这里的snowflake算法是用二进制的,有64位。其中41位的时间戳表示:当前时间戳减去某个设定的起始时间,10位标识表示:不同的机器、数据库的标识ID等等,序列号为每秒或每毫秒内自增的id。

我做的时候没有用位运算去实现,而是做了一个十进制的,16位的(当时项目要求是16位的)。但是实现发号器的基本策略是一样的,通过时间戳和标识来防止重复,通过序列号实现自增。当然啦,重点不是发号器多少位,而是根据项目的实际情况,利用snowflake算法的原理,实现一个适合自己项目的发号器。

2.Python实现

时间戳:9位,起始时间为2018-01-01 00:00:00 ,时间戳为当前时间减去起始时间。时间戳有9为,可用时间为 999999999/(606024*365)≈31(年)。

标识ID:2位,我用的时候比较简单,只是涉及一个数据库的情况,所以用一张数据表对应一个标识ID,可用100张表。

序列号:5位,我时间戳用的是秒级的,但是5位是10万个序列号,经过测试在一秒内是完全够用的。

所以时间戳、标识ID、序列号的位数也没规定说一定要多少,根据自己项目的实际来即可。

代码如下:

import time
class MySnow:
  def __init__(self,dataID):
    self.start = int(time.mktime(time.strptime('2018-01-01 00:00:00', "%Y-%m-%d %H:%M:%S")))
    self.last = int(time.time())
    self.countID = 0
    self.dataID = dataID  # 数据ID,这个自定义或是映射

  def get_id(self):
    # 时间差部分
    now = int(time.time())
    temp = now-self.start
    if len(str(temp)) < 9: # 时间差不够9位的在前面补0
      length = len(str(temp))
      s = "0" * (9-length)
      temp = s + str(temp)
    if now == self.last:
      self.countID += 1  # 同一时间差,序列号自增
    else:
      self.countID = 0  # 不同时间差,序列号重新置为0
      self.last = now
    # 标识ID部分
    if len(str(self.dataID)) < 2:
      length = len(str(self.dataID))
      s = "0" * (2-length)
      self.dataID = s + str(self.dataID)
    # 自增序列号部分
    if self.countID == 99999: # 序列号自增5位满了,睡眠一秒钟
      time.sleep(1)
    countIDdata = str(self.countID)
    if len(countIDdata) < 5: # 序列号不够5位的在前面补0
      length = len(countIDdata)
      s = "0"*(5-length)
      countIDdata = s + countIDdata
    id = str(temp) + str(self.dataID) + countIDdata
    return id

使用方法:

snow = MySnow(dataID="00")
print(snow.get_id())

其中dataID即为标识ID,countID为自增序列号。dataID可以一个通过自定义的映射表获得,这个视实际的项目情况而定。

3.关于并发

首先,直接用这个发号器是不能进行并发操作,会产生重复的id。如果真的要进行并发,那么就要权衡一下并发和位数的哪个更重要了!

拿实际例子来说吧,比如我并发的目的是为了节省时间,让程序更快的跑完,这时候为了并发,我把dataID中拿出一位来,标识不同的子进程,这样可以防止产生重复的id。但是实际上这用了位数去换取时间,如果是id位数比较少的情况,比如16位的,dataID比较少,我个人认为这样是不值得的,有些奢侈。这时候便是位数比并发重要啦。

当时如果位数充裕,比如20位的,需要并发就并发啦。

还有一种实现并发的方法,就是给发号器加锁,发号的时候加锁,发完了解锁。这个我没有试过,有兴趣的可以试一下哈哈。但是我有个疑惑啊,就是不断加锁和解锁切换,带来的时间和资源开销会不会很大呢。

Python 相关文章推荐
python访问sqlserver示例
Feb 10 Python
python数据结构之二叉树的统计与转换实例
Apr 29 Python
简介Python中用于处理字符串的center()方法
May 18 Python
在Linux系统上通过uWSGI配置Nginx+Python环境的教程
Dec 25 Python
Python数据类型详解(四)字典:dict
May 12 Python
python模拟表单提交登录图书馆
Apr 27 Python
在Mac上删除自己安装的Python方法
Oct 29 Python
python多线程实现TCP服务端
Sep 03 Python
opencv调整图像亮度对比度的示例代码
Sep 27 Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 30 Python
Python词云的正确实现方法实例
May 08 Python
Python+Tkinter打造签名设计工具
Apr 01 Python
Python实现个人微信号自动监控告警的示例
Jul 03 #Python
python pandas模块基础学习详解
Jul 03 #Python
python将excel转换为csv的代码方法总结
Jul 03 #Python
pandas实现to_sql将DataFrame保存到数据库中
Jul 03 #Python
python实现控制COM口的示例
Jul 03 #Python
python pandas时序处理相关功能详解
Jul 03 #Python
在linux下实现 python 监控usb设备信号
Jul 03 #Python
You might like
生成sessionid和随机密码的例子
2006/10/09 PHP
php判断类是否存在函数class_exists用法分析
2014/11/14 PHP
ThinkPHP的常用配置选项汇总
2016/03/24 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
2020/08/24 PHP
js面向对象编程之如何实现方法重载
2014/07/02 Javascript
js实现仿MSN带关闭功能的右下角弹窗代码
2015/09/04 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
postman+json+springmvc测试批量添加实例
2018/03/31 Javascript
基于jquery实现左右上下移动效果
2018/05/02 jQuery
Puppeteer 爬取动态生成的网页实战
2018/11/14 Javascript
微信小程序访问豆瓣电影api的实现方法
2019/03/31 Javascript
基于VUE实现简单的学生信息管理系统
2021/01/13 Vue.js
python服务器与android客户端socket通信实例
2014/11/12 Python
Python动态加载模块的3种方法
2014/11/22 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
教你用Python创建微信聊天机器人
2020/03/31 Python
python实现AES加密解密
2019/03/28 Python
通过cmd进入python的实例操作
2019/06/26 Python
python读取图片的几种方式及图像宽和高的存储顺序
2020/02/11 Python
Python之Django自动实现html代码(下拉框,数据选择)
2020/03/13 Python
解决Python spyder显示不全df列和行的问题
2020/04/20 Python
python3.7添加dlib模块的方法
2020/07/01 Python
英国女性运动服品牌:Sweaty Betty
2018/11/08 全球购物
应届大学生简历中的自我评价
2014/01/15 职场文书
中药专业毕业自荐书范文
2014/02/08 职场文书
小学生开学感言
2014/02/28 职场文书
中学生学雷锋活动心得体会
2014/03/10 职场文书
大队委竞选演讲稿
2014/04/28 职场文书
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
派出所副所长四风问题个人整改措施思想汇报
2014/10/13 职场文书
公务员考察材料范文
2014/12/23 职场文书
2015年六一儿童节活动方案
2015/05/05 职场文书
安全责任协议书范本
2016/03/23 职场文书
python利用while求100内的整数和方式
2021/11/07 Python