在分布式系统中使用雪花数,在Python使用pysnowflake生成雪花数示例

部署运行你感兴趣的模型镜像


在分布式系统中使用雪花数,在Python使用pysnowflake生成雪花数示例
UUID和雪花数的比较
Python中使用pysnowflake生成雪花数
在分布式系统中生成雪花数
参考文档
在分布式系统中使用雪花数,在Python使用pysnowflake生成雪花数示例
在数据库表设计时,表的主键一般可以用:

数据库自增长的IDENTITY,自动递增的正整数
程序生成的UID
一般情况下,使用数据库自增长的IDENTITY就可满足要求,但是在分库分表的情况,就只能使用程序生成的UID。

UUID和雪花数的比较
相比常见的64位数字字母随机数的UUID,使用雪花算法(snowflake)生成雪花数的方法更好:

UUID    雪花数
全局唯一    支持    支持
有序,可以支持排序、比较    无序    支持,大致有序,按时间排序
节约存储空间    64位数字字母随机组合的字符串    19位正整数,更节约存储空间
根据UID查询速度快,且稳定    数据库根据索引查询速度不稳定    数据库根据索引查询速度快且稳定
防止被恶意推测    支持    支持
带有业务属性    无    无
限制条件    全局唯一性依赖于生成随机数的种子和随机数的长度    需要单独部署雪花数生成器;依赖于生成器的时间戳。
为什么叫雪花数,因为据说世界上每一朵雪花都是独一无二的。

雪花数算法参见:

https://github.com/twitter-archive/snowflake/tree/snowflake-2010
Python中使用pysnowflake生成雪花数
参考:

https://pysnowflake.readthedocs.io/en/latest/

安装pysnowflake:

pip install pysnowflake
1
启动雪花数生成器:

snowflake_start_server
1
在程序中获取雪花数:

import snowflake.client

for _ in range(20):
    print(snowflake.client.get_guid())


生成的雪花数为按时间戳排序的19位正整数,对应MySQL bigint unsigned数据类型。

在分布式系统中生成雪花数
在分布式系统中生成雪花数时,还需要考虑高性能和高可用。

可以在每个业务服务器节点上都部署雪花数生成器,并用不同标识区分:

# 节点1
snowflake_start_server --worker=1

# 节点2
snowflake_start_server --worker=2

也可以在启动雪花数生成器的脚本中,将IP地址的最后一段用来作为worker的标识

ip=$(ip route get 1 | awk '{print $NF;exit}')
ip_suffix=$(echo $ip | cut -d'.' -f 4)
snowflake_start_server --worker=$ip_suffix

应用只需从本机的雪花数生成器去获取雪花数,避免了远程调用网络延迟。

参考文档
https://github.com/twitter-archive/snowflake/tree/snowflake-2010
https://pysnowflake.readthedocs.io/en/latest/
MySQL分库分表使用Snowflake全局ID生成器
https://github.com/erans/pysnowflake
雪花算法分析与实现

原文链接:https://blog.youkuaiyun.com/nklinsirui/article/details/104629100

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

确保雪花ID生成算法在分布式系统中的唯一性,主要需要解决三个关键问题:**时间戳唯一性**、**工作节点ID唯一性**和**序列号唯一性**。以下是具体方案: --- ### 一、核心实现方案 1. **时间戳部分(41bit)** - 使用毫秒级时间戳(可支持69年) - 添加**NTP时间同步**机制(所有节点必须同步时钟) - 处理时间回拨: ```python if current_timestamp < last_timestamp: raise ClockMoveBackwardException("时间回拨异常") ``` 2. **工作节点ID(10bit)** - **静态配置**(适合固定服务器): ```python # 通过环境变量或配置文件强制指定 WORKER_ID = int(os.getenv("SNOWFLAKE_WORKER_ID")) ``` - **动态分配**(适合云环境): ```python # 使用ZooKeeper/Etcd分配唯一ID worker_id = zk.create_ephemeral_sequential("/snowflake/workers") ``` 3. **序列号(12bit)** - 同一毫秒内通过自增序列区分 - 毫秒切换时重置序列号: ```python if timestamp == last_timestamp: sequence = (sequence + 1) & 0xFFF # 12bit最大值4095 else: sequence = 0 ``` --- ### 二、分布式环境特殊处理 1. **容器化环境**: - 通过K8s StatefulSet的`pod-name`哈希生成WorkerID - 或使用服务注册中心(如Consul)动态分配 2. **云服务器**: - 利用云厂商元据(如AWS的实例ID)生成WorkerID: ```python # AWS示例 instance_id = requests.get("http://169.254.169.254/latest/meta-data/instance-id").text worker_id = hash(instance_id) % 1024 ``` 3. **防冲突校验**: ```python # 生成ID后检查是否大于前一个ID(避免时间回拨未检测到) new_id = (timestamp << 22) | (worker_id << 12) | sequence assert new_id > last_id, "ID生成冲突" ``` --- ### 三、推荐架构 ``` [分布式协调服务] ↑ [WorkerID分配] ← [NTP时间服务器] ↓ [本地ID生成器] → [时钟异常监控] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值