c#分布式ID生成器
c#分布式ID生成器
简介
这个是根据twitter的snowflake来写的.这里有中文的介绍.

如上图所示,一个64位ID,除了最左边的符号位不用(固定为0,以保证生成的ID都是正数),还剩余63位可用.
下面的代码与图中的位数分配略有不同,除了中间部分10bit工作机器id不变,时间戳和序列号的位数是可以根据自己的需求变化的,就是说,你可以把中间的工作机器ID往左挪一挪,或往右挪一挪.
代码
/// <summary>
/// 64位ID生成器,最高位为符号位,始终为0,可用位数63.
/// 实例编号占10位,范围为0-1023
/// 时间戳和索引共占53位
/// </summary>
public sealed class IdCreator
{
private static readonly Random r = new Random();
private static readonly IdCreator _default = new IdCreator();
private readonly long instanceID;//实例编号
private readonly int indexBitLength;//索引可用位数
private readonly long tsMax = 0;//时间戳最大值
private readonly long indexMax = 0;
private readonly object m_lock = new object();
private long timestamp = 0;//当前时间戳
private long index = 0;//索引/计数器
/// <summary>
///
/// </summary>
/// <param name="instanceID">实例编号(0-1023)</param>
/// <param name="indexBitLength">索引可用位数(1-32).每秒可生成ID数等于2的indexBitLength次方.大并发情况下,当前秒内ID数达到最大值时,将使用下一秒的时间戳,不影响获取ID.</param>
/// <param name="initTimestamp">初始化时间戳,精确到秒.当之前同一实例生成ID的timestamp值大于当前时间的时间戳时,
/// 有可能会产生重复ID(如持续一段时间的大并发请求).设置initTimestamp比最后的时间戳大一些,可避免这种问题</param>
public IdCreator(int instanceID, int indexBitLength, long? initTimestamp = null)
{
if (instanceID < 0)
{
//这里给每个实例随机生成个实例编号
this.instanceID = r.Next(0, 1024);
}
else
{
this.instanceID = instanceID % 1024;
}
if (indexBitLength < 1)
{
this.indexBitLength = 1;
}
else if (indexBitLength > 32)
{
this.indexBitLength = 32;
}
else
{
this.indexBitLength = indexBitLength;
}
tsMax = Convert.ToInt64(new string('1', 53 - indexBitLength), 2);
indexMax = Convert.ToInt64(new string('1', indexBitLength), 2);
if (initTimestamp != null)
{
this.timestamp = initTimestamp.Value;
}
}
/// <summary>
/// 默认每实例每秒生成65536个ID,从1970年1月1日起,累计可使用4358年
/// </summary>
/// <param name="instanceID">实例编号(0-1023)</param>
public IdCreator(int instanceID) : this(instanceID, 16)
{
}
/// <summary>
/// 默认每秒生成65536个ID,从1970年1月1日起,累计可使用4358年
/// </summary>
public IdCreator() : this(-1)
{
}
/// <summary>
/// 生成64位ID
/// </summary>
/// <returns></returns>
public long Create()
{
long id = 0;
lock (m_lock)
{
//增加时间戳部分
long ts = Harry.Common.Utils.GetTimeStamp() / 1000;
ts = ts % tsMax; //如果超过时间戳允许的最大值,从0开始
id = ts << (10 + indexBitLength);//腾出后面部分,给实例编号和索引编号使用
//增加实例部分
id = id | (instanceID << indexBitLength);
//获取计数
if (timestamp < ts)
{
timestamp = ts;
index = 0;
}
else
{
if (index > indexMax)
{
timestamp++;
index = 0;
}
}
id = id | index;
index++;
}
return id;
}
/// <summary>
/// 获取当前实例的时间戳
/// </summary>
public long CurrentTimestamp
{
get
{
return this.timestamp;
}
}
/// <summary>
/// 默认每实例每秒生成65536个ID,从1970年1月1日起,累计可使用4358年
/// </summary>
public static IdCreator Default
{
get
{
return _default;
}
}
}
代码说明
使用时,需要new一个IdCreator的实例,然后调用Create()方法,生成一个ID号.需要把IdCreator的例实赋给一个静态变量,以保证ID号的唯一性.如果是分布式部署,需要给IdCreator的构造函数传递instanceID参数,每一个部署都要有一个不同的值,范围为0-1023.
构造函数中的indexBitLength参数,代表图中最右边的'序列号'的长度,不再固定为12bit,范围为1-32.剩下的可用位,就留给了时间戳.
注意:IdCreator类的时间戳是按秒计的. 如果想改成毫秒,只需要将代码long ts = Harry.Common.Utils.GetTimeStamp() / 1000;改成long ts = Harry.Common.Utils.GetTimeStamp();即可.
示例代码
IdCreator c=new IdCreator(0,16);
var id=c.Create();
转载自:http://www.cnblogs.com/harry-wang/p/6030514.html
c#分布式ID生成器的更多相关文章
- 基于redis的分布式ID生成器
基于redis的分布式ID生成器
- 分布式ID生成器PHP+Swoole实现(上) - 实现原理
1.发号器介绍 什么是发号器? 全局唯一ID生成器,主要用于分库分表唯一ID,分布式系统数据的唯一标识. 是否需要发号器? 1)是否需要全局唯一. 分布式系统应该不受单点递增ID限制,中心式的会涉及到 ...
- go语言实现分布式id生成器
本文:https://chai2010.cn/advanced-go-programming-book/ch6-cloud/ch6-01-dist-id.html 分布式id生成器 有时我们需要能够生 ...
- 分布式ID生成器的解决方案总结
在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十分重要 ...
- 来吧,自己动手撸一个分布式ID生成器组件
在经过了众多轮的面试之后,小林终于进入到了一家互联网公司的基础架构组,小林目前在公司有使用到架构组研究到分布式id生成器,前一阵子大概看了下其内部的实现,发现还是存在一些架构设计不合理之处.但是又由于 ...
- CosId 通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
- CosId 1.0.0 发布,通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
- CosId 1.0.3 发布,通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
- CosId 1.1.0 发布,通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
随机推荐
- 支付宝支付之App支付
与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的. 支付宝开放平台地址:https://docs.open.alipay.com/204/105297/ 支付宝支 ...
- JAVA中的String类(详解)
Java.lang.String类是final类型的,因此不可以继承这个类.不能修改这个类.String是一个类不属于基本数据类型. 可以从源码中看到,String是一个final类型. String ...
- 业务限流场景简单实现方案:RateLimiter
前因:因为本系统中,有大数据高并发的场景.在向下游系统发送请求的时候,需要限流.否则会造成下游系统的堵塞. 实现方案1: Thread.sleep(ms). 优点:简单粗暴,一行代码搞定 缺点:有点l ...
- ABP EventBus(事件总线)
事件总线就是订阅/发布模式的一种实现 事件总线就是为了降低耦合 1.比如在winform中 到处都是事件 触发事件的对象 sender 事件的数据 e 事件的处理逻辑 方法体 通过E ...
- 【编程语言】Kotlin之object关键字
在一个体重秤项目里面使用Kotlin开发,考虑到项目比较小型轻量,所以和团队申请决定使用Kotlin开发,以此熟悉和尝试一下Kotlin. 首先使用Kotlin之后,发现能和Java很好的兼容一起,开 ...
- 理解去中心化 稳定币 DAI
本文转载于深入浅出区块链, 原文链接 随着摩根大通推出JPM Coin 稳定币,可以预见稳定币将成为区块链落地的一大助推器. 坦白来讲,对于一个程序员的我来讲(不懂一点专业经济和金融),理解DAI的机 ...
- 获取的输入内容,没有被P标签包裹的文本和元素进行处理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- IIS部署发布flask网站
先参考http://python.jobbole.com/87655/,会发现失败. 再参考https://blog.csdn.net/david_lee13/article/details/8198 ...
- Oracle启用和禁用触发器
1.禁用 table_name 表的所有 trigger alter table table_name disable all triggers; 2.启用 table_name 表的所有 trigg ...
- linux所有命令不能用显示-bash: ls: command not found
所有的命令都显示找不到了,原因是修改了/etc/profile造成的 解决方法 1.修正属性文件中的错误 /usr/bin/vi /etc/profile 2.生效属性文件 source /etc/p ...