生成分布式随机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都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是 ...
随机推荐
- 调整图像的尺寸 - cvResize() 函数实现
前言 有时会碰到一张图片太大了,想将它缩小.本文将讲解一个很好用的函数解决这个问题. 图像尺寸调整函数 cvResize() // 图像尺寸调整函数 void Resize ( const CvArr ...
- 继承ViewGroup类
Android中,布局都是直接或间接的继承自ViewGroup类,其中,ViewGroup的直接子类目前有: AbsoluteLayout, AdapterView<T extends Adap ...
- IOS - unity3d错误Could not produce class with ID
运行环境 Unity 5.3.5f1 (IL2CPP)编译IOS版本 XCode Version 7.2.1 (7C1002) Mac OS X 10.11.3 (15D21) (Mac mini) ...
- urllib库python2和python3具体区别
Python 2 name Python 3 name urllib.urlretrieve() urllib.request.urlretrieve() urllib.urlcleanup() ...
- 【分享】自己写的一个可空的DateTimePicker控件-附源码
最近这段时间在重构以前的一个项目,其中有一项就是要把DateTimePicker控件值可空.大家都知道的DateTimePicker值为DateTime类型,DateTime类型值不能等于Null.但 ...
- 怎样拆分View Controller进而实现轻量级的View Controller[UIKit]
參考文章来自objcio站点 为什么要编写轻量级的View Controller?? 1.作为iOS项目中最大的文件,ViewControllers中的代码复用率差点儿是最低的 2.重量级的V ...
- Java for LeetCode 093 Restore IP Addresses
Given a string containing only digits, restore it by returning all possible valid IP address combina ...
- IOS 长姿势---双击Home键
这不值得大惊小怪,因为按两次Home键后,苹果只是简单第提供了一个历史任务列表,而不是人们以为的当前任务列表——这在苹果网站上已经说得很清楚了.至于为什么苹果没有能力为用户提供一个“任务管理器”,我们 ...
- AFNetworking3.0使用简介
注意到咱们集成的版本为3.0.4. 下面的类已从AFNetworking 3.0中废弃: AFURLConnectionOperation AFHTTPRequestOperation AFHTTPR ...
- <再看TCP/IP第一卷>关于链路层的知识细节及相关协议
在TCP/IP协议族中,链路层的主要有三个目的: (1)为IP模块发送和接受数据报 (2)为ARP模块发送ARP请求和接受ARP应答 (3)为RARP发送RARP请求和接受RARP应答 TCP/IP支 ...