生成分布式随机ID
经测试,最快的一种
public class Generator
{
// should be between 40 (34 years) and 42 (139 years)
internal const int NumberOfTimeBits = ; // should be between 0 (single generator) and 10 (1024 generators)
internal const int NumberOfGeneratorIdBits = ; // should be 10 at least (4096 unique ids per millisecond per generator)
internal const int NumberOfSequenceBits = - NumberOfTimeBits - NumberOfGeneratorIdBits; private readonly byte[] _buffer = new byte[];
private readonly byte[] _timeBytes = new byte[];
private readonly byte[] _idBytes = new byte[];
private readonly byte[] _sequenceBytes = new byte[];
private readonly int _maxSequence = (int)Math.Pow(, NumberOfSequenceBits) - ;
private readonly DateTime _start; private short _sequence;
private long _previousTime; /// <summary>
/// Instantiate the generator. Each Generator should have its own ID, so you can
/// use multiple Generator instances in a cluster. All generated IDs are unique
/// provided the start date newer changes. I recommend to choose January 1, 2013.
/// </summary>
public Generator(short generatorId, DateTime start)
{
if (generatorId < || generatorId >= Math.Pow(, NumberOfGeneratorIdBits))
{
var msg = string.Format(
CultureInfo.InvariantCulture,
"generator id must be between 0 (inclusive) and {0} (exclusive).",
Math.Pow(, NumberOfGeneratorIdBits));
throw new ArgumentException(msg, "generatorId");
}
if (start > DateTime.Today)
{
throw new ArgumentException("start date must not be in the future.", "start");
} CalculateIdBytes(generatorId);
_start = start;
} /// <summary>
/// Can generate up to 4096 different IDs per millisecond.
/// </summary>
public string Next()
{
SpinToNextSequence();
WriteValuesToByteArray(_buffer, _previousTime, _sequence); //return DateTime.Now.ToString("yyyyMMddHH")+Convert.ToBase64String(_buffer); 这样有更好的排序
return Convert.ToBase64String(_buffer);
} public ulong NextLong()
{
SpinToNextSequence();
WriteValuesToByteArray(_buffer, _previousTime, _sequence); Array.Reverse(_buffer);
return BitConverter.ToUInt64(_buffer, );
} internal unsafe void WriteValuesToByteArray(byte[] target, long time, short sequence)
{
fixed (byte* arrayPointer = target)
{
*(long*)arrayPointer = ;
} fixed (byte* arrayPointer = _timeBytes)
{
*(long*)arrayPointer = time << ( - NumberOfTimeBits);
} fixed (byte* arrayPointer = _sequenceBytes)
{
*(short*)arrayPointer = sequence;
} WriteValuesToByteArray(target, _timeBytes, _idBytes, _sequenceBytes);
} private unsafe void CalculateIdBytes(short id)
{
fixed (byte* arrayPointer = _idBytes)
{
*(short*)arrayPointer = (short)(id << ( - (( - NumberOfSequenceBits) % )));
}
} [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteValuesToByteArray(byte[] target, byte[] time, byte[] id, byte[] sequence)
{
//// 1234567890123456789012
//// time: 1111111111111111111111111111111111111111110000
//// id: 0011111111110000
//// seq: 0000111111111111
////
//// 000000000000000100010111101010100001000010 0000001011 000000000000
//// pos: 0 1 2 3 4 5 6
//// byte: 0 1 2 3 4 5 6 7 target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]); target[] = (byte)(target[] | id[]);
target[] = (byte)(target[] | id[]); target[] = (byte)(target[] | sequence[]);
target[] = (byte)(target[] | sequence[]);
} private void SpinToNextSequence()
{
var time = GetTime(); while (time == _previousTime && _sequence >= _maxSequence)
{
time = GetTime();
} _sequence = time == _previousTime ? (short)(_sequence + ) : (short);
_previousTime = time;
} [MethodImpl(MethodImplOptions.AggressiveInlining)]
private long GetTime()
{
return (long)(DateTime.UtcNow - _start).TotalMilliseconds;
}
}
gihub地址:https://github.com/mschuler/UniqueIdGenerator
生成分布式随机ID的更多相关文章
- 雪花算法,生成分布式唯一ID
2.3 基于算法实现 [转载] 这里介绍下Twitter的Snowflake算法——snowflake,它把时间戳,工作机器id,序列号组合在一起,以保证在分布式系统中唯一性和自增性. snowfla ...
- 高并发情况下,如何生成分布式全局id
1.使用UUID生成全局id,不占用宽带 2.基于数据库自增或者序列生成全局id,占用宽带,设置自增步长实现集群,但可扩展性差 3.基于redis生成全局id,占用宽度,设置自增步长实现集群,性能比数 ...
- Zookeeper命名服务——生成分布式有序且唯一id
生成分布式有序且唯一id的方法有很多种,使用zookeeper是比较简单的一种方法,只是生成的速度不高,这里只是一个借助zk的版本号生成分布式唯一且有序id的例子. ZkIdGenerator.jav ...
- 高并发情况下分布式全局ID
1.高并发情况下,生成分布式全局id策略2.利用全球唯一UUID生成订单号优缺点3.基于数据库自增或者序列生成订单号4.数据库集群如何考虑数据库自增唯一性5.基于Redis生成生成全局id策略6.Tw ...
- 分布式唯一id:snowflake算法思考
匠心零度 转载请注明原创出处,谢谢! 缘起 为什么会突然谈到分布式唯一id呢?原因是最近在准备使用RocketMQ,看看官网介绍: 一句话,消息可能会重复,所以消费端需要做幂等.为什么消息会重复后续R ...
- 分布式Unique ID的生成方法
分布式Unique ID的生成方法 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结了林林总总的各种生成算法. 1. 发号器 我接触的最早的Unique ID, ...
- [转帖]分布式Unique ID的生成方法一览
分布式Unique ID的生成方法一览 http://www.importnew.com/22211.html 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结 ...
- 分布式全局ID生成方案
传统的单体架构的时候,我们基本是单库然后业务单表的结构.每个业务表的ID一般我们都是从1增,通过AUTO_INCREMENT=1设置自增起始值,但是在分布式服务架构模式下分库分表的设计,使得多个库或多 ...
- 分布式全局ID的几种生成方案
前言 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等. 那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是 ...
随机推荐
- 函数模板&类模板
#include <iostream> #if 0//函数模板 template<typename T> T max(T a, T b, T c)//函数模板 { if (a ...
- 两个DataGridEHToExcel
procedure TForm1.N1Click(Sender: TObject); var GridtoExcel: TDBGridEhToExcel; begin try Gri ...
- 九度OJ 1158:买房子 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1801 解决:1096 题目描述: 某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每 ...
- 九度OJ 1062:分段函数 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3306 解决:1952 题目描述: 编写程序,计算下列分段函数y=f(x)的值. y=-x+2.5; 0<=x<2 y=2-1. ...
- iOS UIWebview添加请求头的两种方式
1.在UIWebviewDelegate的方法中拦截request,设置request的请求头,废话不多说看代码: - (BOOL)webView:(UIWebView *)webView shoul ...
- Cauchy sequence Hilbert space 希尔波特空间的柯西序列
http://mathworld.wolfram.com/HilbertSpace.html A Hilbert space is a vector space with an inner prod ...
- json (js对象标记)
基础 JSON: JavaScript Object Notation (JavaScript对象表示法) 网络媒体类型是 application/json,文件名扩展是 .json JSON 独立于 ...
- Swift 学习笔记 (属性)
属性可以将值与特定的类 结构体 或者枚举联系起来. 存储属性会存储常量或者变量作为实例的一部分.反之计算属性会计算(而不是存储值)值. 计算属性可以由类 结构体 和枚举定义.存储属性只能由类和结构体定 ...
- sed 和awk结合取ip 地址
1.打印文件的第一列(域) : awk '{print $1}' filename 2.打印文件的前两列(域) : awk '{prin ...
- postgres 备份数据库
https://www.postgresql.org/docs/9.1/static/app-pgdump.html bash-4.2$ pg_dump -Fc xianlan_prod > / ...