生成分布式随机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都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是 ...
随机推荐
- FloatingActionButton 完全解析
鸿洋大神说的很明白这里就直接引用一下: FloatingActionButton 完全解析[Design Support Library(2)]
- python 基础 8.2 编译正则对象
#/usr/bin/python #coding=utf-8 #@Time :2017/11/14 9:55 #@Auther :liuzhenchuan #@File :编译正则对象.py ...
- springcloud微服务实战--笔记
目前对Springcloud对了解仅限于:“用[注册服务.配置服务]来统一管理其他微服务” 这个水平.有待提高 Springcloud微服务实战这本书是翟永超2017年5月写的,时间已经过去了两年,略 ...
- sed命令使用举例
选择操作的行范围 sed -n '1,2p' testsed2.txt 匹配第1到2行 sed -n '/a/,/b/p' testsed2.txt 匹配从包含a的行到包含b的行 sed -n ' ...
- wimdows安装mongodb,开机启动
> d: > cd D:\Program Files\MongoDB\Server\3.0\bin > .\mongod --logpath "D:\Program Fil ...
- 【题解】CF24D Broken Robots(收敛性)
[题解]CF24D Broken Robots http://codeforces.com/problemset/problem/24/D 解1(不会写,口胡的) 获得一个比较显然的转移式子 \(dp ...
- php标准库DirectoryIterator类的操作说明
<?php $dir = new DirectoryIterator(dirname(__FILE__)); foreach ($dir as $fileInfo) { if ($fileInf ...
- 【Xcode学C-4】进制知识、位运算符、变量存储细节以及指针的知识点介绍
一.进制知识 (1)默认是十进制.八进制前面加0.即int num1=015;是13.十六进制前面加0x/0X.即int num1=0xd.结果是13.二进制前面是0b/0B,即int num1=0b ...
- mysql服务突然不能启动
mysql之前一直用的好好的,今天突然不能启动.前几天改过my.ini文件,在[mysqld]下添加了default-character-set=utf8.查看日志发现是添加的那句话的错误,删除.并且 ...
- String源码中hashCode算法
针对java中String源码hashcode算法源码分析 /** The value is used for character storage. */ private final char val ...