Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。

snowflake把时间戳工作机器id序列号组合在一起。

除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。以下关于此算法的可行性研究

 Console.WriteLine("41bit的时间戳可以支持该算法使用年限:{0}", (1L << ) / (3600L *  *  * 1000.0));
Console.WriteLine("10bit的工作机器id数量:{0}", (1L << ) - );
Console.WriteLine("12bit序列id数量:{0}", (1L << ) - );

运行结果:

41bit的时间戳可以支持该算法使用年限:69.7305700010147
10bit的工作机器id数量:
12bit序列id数量:

默认情况下41bit的时间戳(从当前开始计算)可以支持该算法使用近70年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。那么理论上,一个应用1秒钟可以产生409万条自增ID,此算法可持续使用近70年。完全能满足我们日常开发项目的需求。

工作机器id严格意义上来说这个bit段的使用可以是进程级,机器级的话你可以使用MAC地址来唯一标示工作机器,工作进程级可以使用IP+Path来区分工作进程。如果工作机器比较少,可以使用配置文件来设置这个id是一个不错的选择,如果机器过多配置文件的维护是一个灾难性的事情。这个工作机器id的bit段也可以进一步拆分,比如用前5个bit标记workerid,后5个bit标记datacenterid,具体代码如下:

    class Snowflake
{ //工作机器id的bit段拆分为前5个bit标记workerid,后5个bit标记datacenterid
const int WorkerIdBits = ;
const int DatacenterIdBits = ;
//序列号bit数
const int SequenceBits = ;
//最大编号限制
const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits);
const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits);
private const long SequenceMask = -1L ^ (-1L << SequenceBits);
//位左运算移动量
public const int WorkerIdShift = SequenceBits;
public const int DatacenterIdShift = SequenceBits + WorkerIdBits;
public const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits; //序列号记录
private long _sequence = 0L;
//时间戳记录
private long _lastTimestamp = -1L; public long WorkerId { get; protected set; }
public long DatacenterId { get; protected set; } public Snowflake(long workerId, long datacenterId, long sequence = 0L)
{
WorkerId = workerId;
DatacenterId = datacenterId;
_sequence = sequence; // sanity check for workerId
if (workerId > MaxWorkerId || workerId < )
{
throw new ArgumentException( String.Format("worker Id can't be greater than {0} or less than 0", MaxWorkerId) );
} if (datacenterId > MaxDatacenterId || datacenterId < )
{
throw new ArgumentException( String.Format("datacenter Id can't be greater than {0} or less than 0", MaxDatacenterId));
} }
/// <summary>
/// 格林时间戳
/// </summary>
/// <returns></returns>
public long TimeGen()
{
DateTime Jan1st1970 = new DateTime(, , , , , , DateTimeKind.Utc);//
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
} readonly object _lock = new Object(); public virtual long NextId()
{
lock (_lock)
{
var timestamp = TimeGen(); if (timestamp < _lastTimestamp)
{
throw new InvalidSystemClock(String.Format(
"发现最新时间戳少{0}毫秒的异常", _lastTimestamp - timestamp));
} if (_lastTimestamp == timestamp)
{
_sequence = (_sequence + ) & SequenceMask;
if (_sequence == )
{
//序列号超过限制,重新取时间戳
timestamp = TilNextMillis(_lastTimestamp);
}
}
else
{
_sequence = ;
} _lastTimestamp = timestamp;
//snowflake算法
var id = (timestamp << TimestampLeftShift) |
(DatacenterId << DatacenterIdShift) |
(WorkerId << WorkerIdShift) | _sequence; return id;
}
}
/// <summary>
/// 重新取时间戳
/// </summary>
protected virtual long TilNextMillis(long lastTimestamp)
{
var timestamp = TimeGen();
while (timestamp <= lastTimestamp)
{
//新的时间戳要大于旧的时间戳,才算作有效时间戳
timestamp = TimeGen();
}
return timestamp;
}
}

Twitter-Snowflake,64位自增ID算法详解的更多相关文章

  1. 【转】Twitter-Snowflake,64位自增ID算法详解

    Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统 ...

  2. windows 64位下,React-Native环境搭建详解 (Android)

    React-Native环境搭建需要: 1.安装Java JDK 2.安装Android Studio 3.安装node.js 4.安装git 5.安装Python 2.x (注意目前不支持Pytho ...

  3. DonkeyID---php扩展-64位自增ID生成器

    ##原理 参考Twitter-Snowflake 算法,扩展了其中的细节.具体组成如下图: 如图所示,64bits 咱们分成了4个部分. 毫秒级的时间戳,有42个bit.能够使用139年,从1970年 ...

  4. Twitter-Snowflake:自增ID算法

    简介 Twitter 早期用 MySQL 存储数据,随着用户的增长,单一的 MySQL 实例没法承受海量的数据,后来团队就研究如何产生完美的自增ID,以满足两个基本的要求: 每秒能生成几十万条 ID ...

  5. Twitter分布式自增ID算法snowflake原理解析

    以JAVA为例 Twitter分布式自增ID算法snowflake,生成的是Long类型的id,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特(0和1). 那么一个 ...

  6. Twitter分布式自增ID算法snowflake原理解析(Long类型)

    Twitter分布式自增ID算法snowflake,生成的是Long类型的id,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特(0和1). 那么一个Long类型的6 ...

  7. 详解Twitter开源分布式自增ID算法snowflake(附演算验证过程)

    详解Twitter开源分布式自增ID算法snowflake,附演算验证过程 2017年01月22日 14:44:40 url: http://blog.csdn.net/li396864285/art ...

  8. 分布式自增ID算法-Snowflake详解

    1.Snowflake简介 互联网快速发展的今天,分布式应用系统已经见怪不怪,在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同的特性,比如像并 ...

  9. 安全体系(三)——SHA1算法详解

    本文主要讲述使用SHA1算法计算信息摘要的过程. 安全体系(零)—— 加解密算法.消息摘要.消息认证技术.数字签名与公钥证书 安全体系(一)—— DES算法详解 安全体系(二)——RSA算法详解 为保 ...

随机推荐

  1. php读取json时无数据(为空)的解决方法

    在使用PHP调用一些json接口文件时 如果使用 file_get_contents 获取页面json数据后 再使用json_decode()解析后 数据无法正常输出 这是的返回值为null 这是由于 ...

  2. CentOS 安装 Wine

    1. 下载安装包 Wine的中文官网可以下载到最新稳定和开发版本的Wine安装包,根据不同需求可以自行下载 2. 解压安装包,编译前检查 根据不同的平台选择不同的编译选项: For 32-Bit Sy ...

  3. extjs_button

    在网页中,填写的内容都在form(表单)中显示,要交互就要用到按钮.所以,今天试了一下按钮,但不清楚的是js中定义的按钮能显示在页面,但怎样响应php代码呢?实际效果就是点击按钮后,通过什么方式调出数 ...

  4. CEPH经常出现slow request的排查解决

    现象: 通过ceph -w日志经常发现有request blocked的问题(如果虚拟机系统跑在ceph上时,就会发现严重的卡顿现象) 排查: 1.通过dstat未发现有明显的瓶颈 (dstat -t ...

  5. Android之ListView&ViewPager模拟新闻界面

    模拟新闻 APP 的界面 1)写 ListView 之前先写布局: 这里有两种 Item 的布局: <?xml version="1.0" encoding="ut ...

  6. apply 伴生对象 单例对象

    apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object F ...

  7. POJ 2251 BFS(简单)

    一道三维的BFS Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24003 Accepted: 9 ...

  8. 初步认知java的方法

    1.正确区分函数和方法: 面向对象的语言叫做方法,面向过程的语言叫做函数,两者的意义是一样的,只是叫法不同.java是面向对象的语言,所以用方法. 2.方法的定义: 就是有名字的代码段 3.方法的目的 ...

  9. Reveal UI 分析工具简单使用

    官网下载地址(30天免费试用):http://revealapp.com/ 作用: 在 iOS 开发中,我们有时很希望有一款类似 Web 开发中的 UI Debug 工具(例如:Firebug),让我 ...

  10. XJOI‘s story (不定期连载)

    王城双基的力量.... 我也不知道写写这种东西会不会被查大表..尴尬  . 我为什么要写这东西: 为了蛤鸡 为了红太阳 xj 人物列传 2017   1,6   Friday 得到大新闻 机房后面的监 ...