C# 版 雪花ID

文章目录

  • Snowflakes ID
    • 雪花ID的结构
    • 时钟回拨问题
  • iml6yu.Fingerprint
    • 引入nuget包(预览版)
    • 初始化
    • 测试用法

Snowflakes ID

“雪花ID”(Snowflake ID),那么它是一种分布式系统中的唯一性标识符,可以保证在分布式环境下生成全局唯一的ID。它是由Twitter公司创造并开源的。

雪花ID由64位构成,以时间戳为高位,后面的位数分别代表数据中心信息、机器标识和序列号等元素,最终通过位运算组合而成。这样生成的ID具有全局唯一性,且在生成过程中天然自带排序能力。

雪花ID广泛应用于分布式系统中。比如,在微服务架构中,每个服务实例都需要一个唯一的ID,用于追踪相关业务操作的日志和流转情况;在分布式消息队列中,消息需要设置唯一ID,避免重复消费或者消息顺序混乱等问题。

总之,雪花ID是分布式系统中非常实用的工具之一,可以很好地解决全局唯一性的问题,进而帮助分布式系统更好地运转和管理。

雪花ID的结构

雪花ID 包含五个部分:

  1. 符号位:1 位,固定为 0。
  2. 时间戳:41 位,记录毫秒级的时间戳。这里需要注意的是,时间戳不是当前时刻的时间戳,而是指距离某个特定时间点(如某一年月日)的时间差值,因此它可以支持未来数十年甚至几百年的使用。
  3. 机器 ID:10 位,用于区分同一数据中心内不同的机器。与数据中心 ID 类似,机器 ID 也需要手动设置,并确保全局唯一。
  4. 序列号:12 位,表示同一毫秒时间戳内生成的不同 ID 序号。如果在同一毫秒内生成的 ID 数量超过了 4096 个,那么序列号会从 0 开始重新计数。

时钟回拨问题

在雪花ID算法中,系统时钟回拨可能会导致生成的ID不唯一或者无效,因此需要进行处理。

具体地,在每次生成ID时,都需要获取当前的系统时间戳,并与上一次生成ID时使用的时间戳进行比较。如果发现当前的时间戳小于等于上一次的时间戳,则说明系统时钟发生了回拨,此时可以抛出异常或者阻塞等待,直到系统时钟追上之前的时间戳。

下面是一个示例代码片段以便更好地理解,展示了一个基本的时钟回拨处理过程:

function nextSnowflakeId() {
  // ...

  var timestamp = getUnixTimestamp();
  if (timestamp < lastTimestamp) { // 发生时钟回拨
    var offset = lastTimestamp - timestamp;
    if (offset <= 5) { // 小于等于5毫秒,可以等待追赶
      delay(offset);
      timestamp = getUnixTimestamp();
    } else { // 大于5毫秒,抛出异常
      throw new Exception("Clock moved backwards");
    }
  }

  // ...
}

function delay(offset) {
  try {
    Thread.sleep(offset);
  } catch (InterruptedException e) {
    // ignore
  }
}

function getUnixTimestamp() {
  return new Date().getTime();
}

iml6yu.Fingerprint

一个对雪花算法封装的类库

引入nuget包(预览版)

初始化

第一个参数是机器号 1 ~ 255

第二个参数是机器组号 1~3

Fingerprint.UseFingerprint(1, 3);

测试用法

 [TestMethod()]
        public void GetIdTest()
        {
            Fingerprint.UseFingerprint(1, 3);

            var ids = new ConcurrentBag();
            Parallel.For(0, 100, index =>
            {
                var id = Fingerprint.GetId();
                Console.WriteLine(id);
                ids.Add(id);
            });

            Assert.AreEqual(100, ids.Count);
        }

你可能感兴趣的:(分布式,C#)