python生成唯一id,分布式唯一id,雪花算法

关于toollib

什么是唯一id
- 就是不重复唯一的
- 唯一id生成的几种方式:
    - 1)数据库自动增长序列
        - 增加数据库写压力
        - 数据库故障后会出现不可用风险
        - 会暴露数据量
        - 分库分表设计难,不易扩展
    - 2)uuid
        - 数据太长
        - 数据无序
        - 若基于mac地址生成则会暴露
    - 3)使用redis的原子操作INCR和INCRBY来实现
        - 需要增加redis组件
        - 需要配置redis和编码来生成相对麻烦
    - 4)Twitter的snowflake算法
    - 5)其他方式
什么是雪花算法
- 最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在2014年开源 scala 语言版本。
- 雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。
    - 最高位 1 位固定值 0,因为生成的 id 是正整数,如果是 1 就是负数了。
    - 往后的 41 位存储毫秒级时间戳,2^41/(1000*60*60*24*365)=69,大概可以使用 69 年。
    - 往后的 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。
    - 最后的 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复 id。
为什么要用雪花算法
- 数据是有序的,有利于查询及排序
- 数据长度相比uuid还是很有优势
- 不需要其他插件
- 可分布式(最早就是用于分布式环境下生成唯一ID的)
使用教程
    1. 安装toollib
      pip install toollib
    1. 调用方式
    • 方式1:代码式
    from toollib.guid import SnowFlake
    # 分布式需要根据ip或其他唯一标识映射机器码:worker_id与datacenter_id
    # 如:SnowFlake(worker_id=1, datacenter_id=1)
    # 更多参数详见源码
    snow = SnowFlake()
    uid = snow.gen_uid() 
    print(uid)
    
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
雪花算法是种生成分布式ID的算法,它可以生成一个64位的ID,其中包含了时间戳、数据中心ID和机器ID等信息。下面是雪花算法生成分布式ID的软件设计模型: 1. 定义一个Snowflake类,该类包含以下属性: - datacenter_id: 数据中心ID,占5位,取值围为0~31。 - worker_id: 机器ID,占5位,取值范围为0~31。 - sequence: 序列号,占12位,取值范围为0~4095。 - last_timestamp: 上一次生成ID的时间戳。 2. 实现Snowflake类的构造函数,初始化datacenter_id和worker_id属性。 3. 实现一个next_id方法,该方法用于生成下一个ID。具体实现如下: - 获取当前时间戳,单位为毫秒。 - 如果当前时间戳小于上一次生成ID的时间戳,则说明系统时钟回退过,抛出异常。 - 如果当前时间戳等于上一次生成ID的时间戳,则将序列号加1。 - 如果当前时间戳大于上一次生成ID的时间戳,则将序列号重置为0,并将last_timestamp属性更新为当前时间戳。 - 将datacenter_id、worker_id、时间戳和序列号按照一定的位数组合成一个64位的ID。 - 返回生成ID。 4. 在分布式系统中,每个节点都需要创建一个Snowflake实例,并指定不同的datacenter_id和worker_id。每个节点生成ID都是唯一的,且具有时间顺序。 下面是一个Python实现的雪花算法生成分布式ID的代码示例: ```python import time class Snowflake: def __init__(self, datacenter_id, worker_id): self.datacenter_id = datacenter_id self.worker_id = worker_id self.sequence = 0 self.last_timestamp = -1 def next_id(self): timestamp = int(time.time() * 1000) if timestamp < self.last_timestamp: raise Exception("Clock moved backwards. Refusing to generate id") if timestamp == self.last_timestamp: self.sequence = (self.sequence + 1) & 4095 if self.sequence == 0: timestamp = self.wait_next_millis(self.last_timestamp) else: self.sequence = 0 self.last_timestamp = timestamp return ((timestamp - 1288834974657) << 22) | (self.datacenter_id << 17) | (self.worker_id << 12) | self.sequence def wait_next_millis(self, last_timestamp): timestamp = int(time.time() * 1000) while timestamp <= last_timestamp: timestamp = int(time.time() * 1000) return timestamp ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值