Twitter的分布式自增ID算法snowflake(雪花算法) - C#版
概述
分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。
该项目地址为:https://github.com/twitter/snowflake是用Scala实现的。
python版详见开源项目https://github.com/erans/pysnowflake。
结构
snowflake的结构如下(每部分用-分开):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
一共加起来刚好64位,为一个Long型。(转换成字符串长度为18)
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。据说:snowflake每秒能够产生26万个ID。
源码(C#版本源码)
- public class IdWorker
- {
- //机器ID
- private static long workerId;
- private static long twepoch = 687888001020L; //唯一时间,这是一个避免重复的随机量,自行设定不要大于当前时间戳
- private static long sequence = 0L;
- private static int workerIdBits = ; //机器码字节数。4个字节用来保存机器码(定义为Long类型会出现,最大偏移64位,所以左移64位没有意义)
- public static long maxWorkerId = -1L ^ -1L << workerIdBits; //最大机器ID
- private static int sequenceBits = ; //计数器字节数,10个字节用来保存计数码
- private static int workerIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
- private static int timestampLeftShift = sequenceBits + workerIdBits; //时间戳左移动位数就是机器码和计数器总字节数
- public static long sequenceMask = -1L ^ -1L << sequenceBits; //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
- private long lastTimestamp = -1L;
- /// <summary>
- /// 机器码
- /// </summary>
- /// <param name="workerId"></param>
- public IdWorker(long workerId)
- {
- if (workerId > maxWorkerId || workerId < )
- throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0 ", workerId));
- IdWorker.workerId = workerId;
- }
- public long nextId()
- {
- lock (this)
- {
- long timestamp = timeGen();
- if (this.lastTimestamp == timestamp)
- { //同一微妙中生成ID
- IdWorker.sequence = (IdWorker.sequence + ) & IdWorker.sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
- if (IdWorker.sequence == )
- {
- //一微妙内产生的ID计数已达上限,等待下一微妙
- timestamp = tillNextMillis(this.lastTimestamp);
- }
- }
- else
- { //不同微秒生成ID
- IdWorker.sequence = ; //计数清0
- }
- if (timestamp < lastTimestamp)
- { //如果当前时间戳比上一次生成ID时时间戳还小,抛出异常,因为不能保证现在生成的ID之前没有生成过
- throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds",
- this.lastTimestamp - timestamp));
- }
- this.lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
- long nextId = (timestamp - twepoch << timestampLeftShift) | IdWorker.workerId << IdWorker.workerIdShift | IdWorker.sequence;
- return nextId;
- }
- }
- /// <summary>
- /// 获取下一微秒时间戳
- /// </summary>
- /// <param name="lastTimestamp"></param>
- /// <returns></returns>
- private long tillNextMillis(long lastTimestamp)
- {
- long timestamp = timeGen();
- while (timestamp <= lastTimestamp)
- {
- timestamp = timeGen();
- }
- return timestamp;
- }
- /// <summary>
- /// 生成当前时间戳
- /// </summary>
- /// <returns></returns>
- private long timeGen()
- {
- return (long)(DateTime.UtcNow - new DateTime(, , , , , , DateTimeKind.Utc)).TotalMilliseconds;
- }
- }
调用方法:
- IdWorker idworker = new IdWorker();
- for (int i = ; i < ; i++)
- {
- Response.Write(idworker.nextId() + "<br/>");
- }
转自:https://blog.csdn.net/u011872945/article/details/54562213
Twitter的分布式自增ID算法snowflake(雪花算法) - C#版的更多相关文章
- 详解Twitter开源分布式自增ID算法snowflake(附演算验证过程)
详解Twitter开源分布式自增ID算法snowflake,附演算验证过程 2017年01月22日 14:44:40 url: http://blog.csdn.net/li396864285/art ...
- 分布式ID生成器 snowflake(雪花)算法
在springboot的启动类中引入 @Bean public IdWorker idWorkker(){ return new IdWorker(1, 1); } 在代码中调用 @Autowired ...
- Twitter的分布式自增ID算法snowflake
snowflake 分布式场景下获取自增id git:https://github.com/twitter/snowflake 解读: http://www.cnblogs.com/relucent/ ...
- 分布式主键解决方案之--Snowflake雪花算法
0--前言 对于分布式系统环境,主键ID的设计很关键,什么自增intID那些是绝对不用的,比较早的时候,大部分系统都用UUID/GUID来作为主键,优点是方便又能解决问题,缺点是插入时因为UUID/G ...
- Twitter的分布式自增ID算法snowflake (Java版)
概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种 ...
- UUID实现之一twitter的分布式自增IDsnowflake算法
Twitter的分布式自增ID算法snowflake (Java版) 概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点 ...
- Twitter分布式自增ID算法snowflake原理解析
以JAVA为例 Twitter分布式自增ID算法snowflake,生成的是Long类型的id,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特(0和1). 那么一个 ...
- Twitter分布式自增ID算法snowflake原理解析(Long类型)
Twitter分布式自增ID算法snowflake,生成的是Long类型的id,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特(0和1). 那么一个Long类型的6 ...
- 分布式自增ID算法-Snowflake详解
1.Snowflake简介 互联网快速发展的今天,分布式应用系统已经见怪不怪,在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同的特性,比如像并 ...
随机推荐
- matlab 高级函数 —— colfilt/blockproc (图像)矩阵的分块处理
colfilt 执行功能与 blockproc/nlfilter 类似,但效率更高. B = colfilt(A,[m n],block_type,fun),block_type:distinct/s ...
- Numpy Usage Introduction
Reference : http://my.oschina.net/u/175377/blog/74406 试验性的Numpy教程 原文来自Tentative NumPy Tutorial 目录 先决 ...
- visual studio 编译器在辨异 C/C++ 程序时的注意事项
1. 数组大小的限制 visual studio 对数组的维数(元素的个数)没有限制,但要求数组的 size (sizeof() 后的结果,所占内存的大小)不得超过 0x7fff ffff = 2^3 ...
- this prototype constructor
http://www.cnblogs.com/phpmix/articles/1734031.html
- QWidget居中显示(qt窗口坐标原点是在”左上角”的,有图)
转载请说明出处, 并附上原文链接http://blog.csdn.net/qq907482638/article/details/72189014. 问题描述 在Qt学习过程中,在让QDialog居中 ...
- Android TV开发总结(七)构建一个TV app中的剧集列表控件
原文:Android TV开发总结(七)构建一个TV app中的剧集列表控件 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必转载 ...
- Cocos2d-x 3.1 一步一步地做改编
本文并不想谈论的屏幕改编或真理的概念.假设不知道cocos2d-x的,请先看这篇文章:http://www.cocoachina.com/gamedev/cocos/2014/0516/8451.ht ...
- 受限玻尔兹曼机(RBM)以及对比散度(CD)
1. RBM 的提出 BM 的缺点: 计算时间漫长,尤其是无约束自由迭代的负向阶段: 对抽样噪音敏感: 流行软件的不支持: 受限玻尔兹曼机(Restricted Boltzmann Machine,简 ...
- IME输入法编程心得
原文:IME输入法编程心得 posted @ 2012-11-30 00:42 from [FreedomShe] 自然语言处理的输入法作业成品没有做出来,但不想再在蛋疼的Win32上面耗费时间了,整 ...
- springboot 修改连接地址和端口
spring boot 默认 http://localhost:8080 修改为本地IP地址和修改端口在application.properties中添加以下: server.port=9090 se ...