基于.NET Standard的分布式自增ID算法--Snowflake代码实现

本文详细介绍如何使用C#语言实现Snowflake算法,包括工作节点ID、机房ID及当前生成ID的基础字段设置,以及时间戳获取、新时间戳生成等基础方法。核心方法NextId()确保了生成ID的唯一性和递增性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

上篇文章介绍了3种常见的Id生成算法,本篇主要介绍如何使用C#实现Snowflake。

基础字段

/// <summary>
/// 工作节点Id(长度为5位)
/// </summary>
public long WorkId{get;protected set;}

/// <summary>
/// 机房Id(长度为5位)
/// </summary>
public long DataCenterId{get;protected set;}

/// <summary>
/// 当前生成的Id
/// </summary>
public long CurrentId { get;protected set; }

基础方法

//获取当前时间的Unix时间戳
 private long TimeGen()
{
      return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}

//生成新时间戳(一定比上次生成的时间戳大)
 private long TilNextMillis(long lastTimestamp)
 {
      var timestamp = TimeGen();
      while (timestamp <= lastTimestamp)
      {
           timestamp = TimeGen();
      }
       return timestamp;
}

Id生成核心方法

        private const long TwEpoch = 1543765593681L;//2018-12-2 15:47:06 +00:00

        private const int WorkerIdBits = 5;
        private const int DatacenterIdBits = 5;
        private const int SequenceBits = 12;
        private const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits);
        private const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits);

        private const int WorkerIdShift = SequenceBits;
        private const int DatacenterIdShift = SequenceBits + WorkerIdBits;
        private const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits;
        private const long SequenceMask = -1L ^ (-1L << SequenceBits);

        private long _sequence = 0L;
        private long _lastTimestamp = -1L;

        private readonly object _lock = new object();
        
         public long NextId()
        {
            lock (_lock)
            {
                var timestamp = TimeGen();
                if (timestamp < _lastTimestamp)
                {
                    //TODO 是否可以考虑直接等待?
                    throw new Exception(
                        $"Clock moved backwards or wrapped around. Refusing to generate id for {_lastTimestamp - timestamp} ticks");
                }

                if (_lastTimestamp == timestamp)
                {
                    _sequence = (_sequence + 1) & SequenceMask;
                    if (_sequence == 0)
                    {
                        timestamp = TilNextMillis(_lastTimestamp);
                    }
                }
                else
                {
                    _sequence = 0;
                }
                _lastTimestamp = timestamp;
                CurrentId = ((timestamp - TwEpoch) << TimestampLeftShift) |
                         (DatacenterId << DatacenterIdShift) |
                         (WorkerId << WorkerIdShift) | _sequence;

                return CurrentId;
            }
        }

完整实现、使用Demo以及benchmark测试请参见源代码:https://github.com/sampsonye/nice

转载于:https://www.cnblogs.com/leafly/p/10089540.html

spring: #spring sharding jdbc 配置 shardingsphere: datasource: names: dataudit dataudit: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://10.131.187.231:10002/jiaanpei_dataudit?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false username: janp_base password: dBdZ+FdRL7#J76heJ)!jGNbmA_=HDs&P sharding: tables: # janpb_goods_supp_standard_snapshot表分片策略 janpb_goods_supp_standard_snapshot: actual-data-nodes: dataudit.janpb_goods_supp_standard_snapshot_$->{0..31} table-strategy: inline: # 根据companyCode 进行分片 sharding-column: companyCode # 逻辑分片不需要加 datasource.names 或者schema name algorithm-expression: janpb_goods_supp_standard_snapshot_$->{companyCode % 32} ###分表的总数 0到31 janpb_goods_supp_standard_snapshot_0, .... janpb_goods_supp_standard_snapshot_31 janpb_goods_standard_snapshot: actual-data-nodes: dataudit.janpb_goods_standard_snapshot_$->{0..31} table-strategy: inline: # 根据companyCode 进行分片 sharding-column: companyCode # 逻辑分片不需要加 datasource.names 或者schema name algorithm-expression: janpb_goods_standard_snapshot_$->{companyCode % 32} ###分表的总数 0到31 janpb_goods_standard_snapshot_0, .... janpb_goods_standard_snapshot_31 keyGenerateStrategy: # 分布式序列策略 column: id # 自列名称,缺省表示不使用自主键生成器 keyGeneratorName: SNOWFLAKE # 分布式序列算法名称 props: sql: ### 开启分片日志 show: true 基于高版本对么?
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值