前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >雪花算法Snowflake

雪花算法Snowflake

作者头像
JusterZhu
发布2022-12-07 19:03:50
9260
发布2022-12-07 19:03:50
举报
文章被收录于专栏:JusterZhuJusterZhu

以下文章来源于智能大石头 ,作者智能大石头

雪花Id生成算法,是鼎鼎有名的分布式Id生成算法。它的优点在于,在分布式系统中快速生成有时间顺序的唯一编号!Snowflake实测每秒可生成900万个唯一Id。

Nuget包:NewLife.Core

源码地址:

https://github.com/NewLifeX/X/blob/master/NewLife.Core/Data/Snowflake.cs

核心原理

使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增。

格式:1bit保留 + 41bit时间戳 + 10bit机器 + 12bit序列号

第一位不使用,主要是为了避免部分场景变成负数;

41位时间戳,也就是2的41次方,毫秒为单位,足够保存69年。这里一般存储1970年以来的毫秒数,建议各个系统根据需要自定义这个开始日期;

10位机器码,理论上可以表示1024台机器,也可以拆分几位表示机房几位表示机器。这里默认采用本机IPv4地址最后两段以及进程Id一起作为机器码,确保机房内部不同机器,以及相同机器上的不同进程,拥有不同的机器码;

12位序列号,表示范围0~4095,一直递增,即使毫秒数加一,这里也不会归零,避免被恶意用户轻易猜测得到前后订单号;

生成Id

NewId用于生成新的唯一Id

代码语言:javascript
复制
/// <summary>获取下一个Id</summary>
/// <returns></returns>
public virtual Int64 NewId();

/// <summary>获取指定时间的Id,带上节点和序列号。可用于根据业务时间构造插入Id</summary>
/// <param name="time">时间</param>
/// <returns></returns>
public virtual Int64 NewId(DateTime time);

无参版默认使用当前时间生成唯一Id,也可以给指定时间生成唯一Id。

以下是采用雪花Id作为订单号。

解析Id

大型数据表,例如订单表、日志表等,可以使用Int64作为主键,然后使用雪花Id。因为雪花Id内带有时间戳信息,因此我们可以根据主键Id来直接搜索指定时间区间的数据。

代码语言:javascript
复制
/// <summary>时间转为Id,不带节点和序列号。可用于构建时间片段查询</summary>
/// <param name="time">时间</param>
/// <returns></returns>
public virtual Int64 GetId(DateTime time);

GetId用于计算指定时间的基准Id,只有最高的时间部分,机器码和序列化为零。我们在计算指定时间区间(start, end)内的数据时,可以有:

代码语言:javascript
复制
Select * from Order where Id>=Get(start) and Id<GetId(end);
代码语言:javascript
复制

拿到一个雪花Id,也可以从中解析得到时间等信息

代码语言:javascript
复制
/// <summary>尝试分析</summary>
/// <param name="id"></param>
/// <param name="time">时间</param>
/// <param name="workerId">节点</param>
/// <param name="sequence">序列号</param>
/// <returns></returns>
public virtual Boolean TryParse(Int64 id, out DateTime time, out Int32 workerId, out Int32 sequence);

解析订单号 152075078181383514 ,时间基准设为 2020年1月1日

总结

在分布式系统中,雪花Id具有非常重要的意义。星尘大量使用雪花Id,用于存储跟踪数据和采样数据,以前必须先插入跟踪数据得到自增Id然后才能插入采样数据(需要关联)的问题迎难而解,两者都可以同时走批量插入。

对于日志型数据表,强烈推荐使用雪花Id,因为它带有时间戳信息,等同于省去了CreateTime字段的索引。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 核心原理
  • 生成Id
  • 解析Id
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档