C# 分布式自增ID算法snowflake(雪花算法)
warning:
这篇文章距离上次修改已过201天,其中的内容可能已经有所变动。
雪花算法(Snowflake algorithm)是一种生成唯一ID的算法,适用于分布式系统。在C#中实现雪花算法,可以参考以下代码:
using System;
using System.Threading;
using System.Threading.Tasks;
public class SnowflakeIdGenerator
{
private const ulong Twepoch = 1288834974657; // 起始时间点 (2010-11-04T01:42:54.657Z)
private const int WorkerBits = 10; // 机器ID所占的位数
private const int DatacenterBits = 5; // 数据中心ID所占的位数
private const int SequenceBits = 12; // 序列号所占的位数
private const int WorkerIdShift = SequenceBits;
private const int DatacenterIdShift = SequenceBits + WorkerBits;
private const ulong TimestampLeftShift = (WorkerBits + DatacenterBits + SequenceBits);
private const ulong SequenceMask = -1 ^ (-1 << SequenceBits);
private const ulong WorkerIdMask = -1 ^ (-1 << WorkerBits);
private const ulong DatacenterIdMask = -1 ^ (-1 << DatacenterBits);
private readonly object _lockObj = new object();
private ulong _lastTimestamp = 0;
private ulong _sequence = 0;
public ulong WorkerId { get; private set; }
public ulong DatacenterId { get; private set; }
public SnowflakeIdGenerator(ulong workerId, ulong datacenterId)
{
if (workerId > WorkerIdMask)
throw new ArgumentException("workerId can't be greater than " + WorkerIdMask);
if (datacenterId > DatacenterIdMask)
throw new ArgumentException("datacenterId can't be greater than " + DatacenterIdMask);
WorkerId = workerId;
DatacenterId = datacenterId;
}
public ulong NextId()
{
lock (_lockObj)
{
ulong timestamp = TimeGen();
if (timestamp < _lastTimestamp)
{
throw new InvalidOperationException($"Clock moved backwards, refusing to generate id for {_lastTimestamp - timestamp} milliseconds");
}
if (_lastTimestamp == timestamp)
{
_sequence = (_sequence + 1) & SequenceMask;
if (_sequence == 0)
{
timestamp = TilNextMillis(_lastTimestamp);
}
}
else
{
_sequence = 0;
}
_lastTimestamp = timestamp;
ulong id = ((ti
评论已关闭