转自:http://blog.csdn.net/kinwyb/article/details/50238505

使用twitter的snowflake算法生成唯一ID。

在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位+机器ID 10位+毫秒内序列12位。

  1. /// <summary>
  2. /// 根据twitter的snowflake算法生成唯一ID
  3. /// snowflake算法 64 位
  4. /// 0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
  5. /// 第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
  6. /// 其中datacenter标识位起始是机器位,机器ID其实是线程标识,可以同一一个10位来表示不同机器
  7. /// </summary>
  8. public class IdWorker
  9. {
  10. //机器ID
  11. private static long workerId;
  12. private static long twepoch = 687888001020L; //唯一时间,这是一个避免重复的随机量,自行设定不要大于当前时间戳
  13. private static long sequence = 0L;
  14. private static int workerIdBits = ; //机器码字节数。4个字节用来保存机器码
  15. public static long maxWorkerId = -1L ^ -1L << workerIdBits; //最大机器ID
  16. private static int sequenceBits = ; //计数器字节数,10个字节用来保存计数码
  17. private static int workerIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
  18. private static int timestampLeftShift = sequenceBits + workerIdBits; //时间戳左移动位数就是机器码和计数器总字节数
  19. public static long sequenceMask = -1L ^ -1L << sequenceBits; //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
  20. private long lastTimestamp = -1L;
  21.  
  22. public IdWorker(long workerId)
  23. {
  24. if (workerId > maxWorkerId || workerId < )
  25. throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0 ", workerId));
  26. IdWorker.workerId=workerId;
  27. }
  28.  
  29. public long nextId()
  30. {
  31. lock (this)
  32. {
  33. long timestamp = timeGen();
  34. if(this.lastTimestamp == timestamp){ //同一微妙中生成ID
  35. IdWorker.sequence = (IdWorker.sequence + ) & IdWorker.sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
  36. if(IdWorker.sequence == ){
  37. //一微妙内产生的ID计数已达上限,等待下一微妙
  38. timestamp = tillNextMillis(this.lastTimestamp);
  39. }
  40. }
  41. else{ //不同微秒生成ID
  42. IdWorker.sequence = ; //计数清0
  43. }
  44. if(timestamp < lastTimestamp)
  45. { //如果当前时间戳比上一次生成ID时时间戳还小,抛出异常,因为不能保证现在生成的ID之前没有生成过
  46. throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds",
  47. this.lastTimestamp - timestamp));
  48. }
  49. this.lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
  50. long nextId = (timestamp - twepoch << timestampLeftShift) | IdWorker.workerId << IdWorker.workerIdShift | IdWorker.sequence;
  51. return nextId;
  52. }
  53. }
  54.  
  55. /// <summary>
  56. /// 获取下一微秒时间戳
  57. /// </summary>
  58. /// <param name="lastTimestamp"></param>
  59. /// <returns></returns>
  60. private long tillNextMillis(long lastTimestamp)
  61. {
  62. long timestamp = timeGen();
  63. while(timestamp <= lastTimestamp)
  64. {
  65. timestamp = timeGen();
  66. }
  67. return timestamp;
  68. }
  69.  
  70. /// <summary>
  71. /// 生成当前时间戳
  72. /// </summary>
  73. /// <returns></returns>
  74. private long timeGen()
  75. {
  76. return (long)(DateTime.UtcNow - new DateTime(, , , , , , DateTimeKind.Utc)).TotalMilliseconds;
  77. }
  78.  
  79. }

twitter的snowflake算法(C#版本)的更多相关文章

  1. 根据twitter的snowflake算法生成唯一ID

    C#版本 /// <summary> /// 根据twitter的snowflake算法生成唯一ID /// snowflake算法 64 位 /// 0---0000000000 000 ...

  2. 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(无懈可击)

    参考美团文档:https://tech.meituan.com/2017/04/21/mt-leaf.html Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万 ...

  3. C# 根据twitter的snowflake算法生成唯一ID

    C# 版算法: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  4. Twitter雪花算法 SnowFlake算法 的java实现

    概述 SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序. 原理 Sn ...

  5. Twitter雪花算法SnowFlake算法的java实现

    https://juejin.im/post/5c75132f51882562276c5065 package javaDemo; /** * twitter的snowflake算法 -- java实 ...

  6. snowflake算法(java版)

     转自:http://www.cnblogs.com/haoxinyue/p/5208136.html 1. 数据库自增长序列或字段 最常见的方式.利用数据库,全数据库唯一. 优点: 1)简单,代码方 ...

  7. PHP使用SnowFlake算法生成唯一ID

    前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的.文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过 ...

  8. 【转】网游服务器中的GUID(唯一标识码)实现-基于snowflake算法

    本文中的算法采用twitter的snowflake算法,具体请搜索介绍,原来是用Scala写的,因我项目需要,改写成C++语言,主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器I ...

  9. 一篇文章彻底搞懂snowflake算法及百度美团的最佳实践

    写在前面的话 一提到分布式ID自动生成方案,大家肯定都非常熟悉,并且立即能说出自家拿手的几种方案,确实,ID作为系统数据的重要标识,重要性不言而喻,而各种方案也是历经多代优化,请允许我用这个视角对分布 ...

随机推荐

  1. 解决win8 plsql无法登录

    今天安装完oracle客户端,然后打开 plsql 之后,就一个提示框,提示没有登录,后来解决方法如下: 在plsql的图标上点右键,以管理员身份运行,即可! 如果不想一直点右键执行,就图标上点右键- ...

  2. zoj 3765

    一道区间更新.查询的题: 但是线段树不能做插入: 后来才知道用splay: splay用来做区间查询的话,先将l-1旋转到根节点,然后把r+1旋转到根节点的右节点: 这样的话,根节点的右节点的左子树就 ...

  3. ZOJ 3609 Modular Inverse

    点我看题目 题意 : 这个题是求逆元的,怎么说呢,题目看着很别扭....就是给你a和m,让你求一个最小的x满足a-1≡x (mod m).或者ax≡1 (mod m).通俗点说呢,就是找一个最小的x, ...

  4. UVA 825 Walkiing on the safe side

    根据地图,要求固定两点间最短路径的条数 . 这题的输入数据就是个坑,题目有没有说明数据之间有多个空格,结尾换行符之前也不止一个空格,WA了好几遍,以后这种情况看来都要默认按照多空格的情况处理了. 可以 ...

  5. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-004-使用AspectJ’s pointcut expression language定义Pointcut

    一. 1.在Spring中,pointcut是通过AspectJ’s pointcut expression language来定义的,但spring只支持它的一部分,如果超出范围就会报Illegal ...

  6. 第五章 HID设备

    5.1 HID介绍 为简化USB设备的开发过程,USB提出了设备类的概念.所有设备类都必须支持标准USB描述符和标准USB设备请求.如果有必要,设备类还可以自行定义其专用的描述符和设备请求,这分别被称 ...

  7. OpenSSH for Windows,CopSSH

    https://www.oschina.net/p/openssh+for+windows https://www.oschina.net/p/copssh

  8. 使用git批量删除分支

    要删除本地,首先要考虑以下三点 列出所有本地分支 搜索目标分支如:所有含有‘dev’的分支 将搜索出的结果传给删除函数 所以我们可以得到: git br |grep 'dev' |xargs git ...

  9. ccleaner的专业版和商业版的注册码

    名称:Registered User 密钥:CBB4-FJN4-EPC6-G5P6-QT4C 断网注册

  10. cocos2d-x 2.2 wp8 开发手记

    最近有朋友问我有没有搞过  wp8 的cocos2dx开发 回复:额,没有.(感觉超没面子对方是妹子 = = ) 本着帮妹子试试的态度  就开始了 今天工作 第一我印象中wp8 开发必须要用 vs20 ...