在分布式系统中使用雪花数,在Python使用pysnowflake生成雪花数示例
在数据库表设计时,表的主键一般可以用:
数据库自增长的IDENTITY,自动递增的正整数
程序生成的UID
一般情况下,使用数据库自增长的IDENTITY就可满足要求,但是在分库分表的情况,就只能使用程序生成的UID。
相比常见的64位数字字母随机数的UUID,使用雪花算法(snowflake)生成雪花数的方法更好:
UUID雪花数
全局唯一支持支持
有序,可以支持排序、比较无序支持,大致有序,按时间排序
节约存储空间64位数字字母随机组合的字符串19位正整数,更节约存储空间
根据UID查询速度快,且稳定数据库根据索引查询速度不稳定数据库根据索引查询速度快且稳定
防止被恶意推测支持支持
带有业务属性无无
限制条件全局唯一性依赖于生成随机数的种子和随机数的长度需要单独部署雪花数生成器;依赖于生成器的时间戳。
为什么叫雪花数,因为据说世界上每一朵雪花都是独一无二的。
雪花数算法参见:
https://github.com/twitter-archive/snowflake/tree/snowflake-2010
参考:
https://pysnowflake.readthedocs.io/en/latest/
安装pysnowflake:
pip install pysnowflake
启动雪花数生成器:
snowflake_start_server
在程序中获取雪花数:
importsnowflake.clientfor_inrange(20):print(snowflake.client.get_guid())
生成的雪花数为按时间戳排序的19位正整数,对应MySQL bigint unsigned数据类型。
在分布式系统中生成雪花数时,还需要考虑高性能和高可用。
可以在每个业务服务器节点上都部署雪花数生成器,并用不同标识区分:
# 节点1snowflake_start_server --worker=1# 节点2snowflake_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/
网友评论