分布式唯一ID

在做多个库之间的同步时 自增长 就不太适用了  

 

Comb算法(combined guid/timestamp) 用于解决 guid 无序的问题

/// <summary> 
/// Generate a new <see cref="Guid"/> using the comb algorithm. 
/// </summary> 
private Guid GenerateComb()
{
    byte[] guidArray = Guid.NewGuid().ToByteArray();
 
    DateTime baseDate = new DateTime(1900, 1, 1);
    DateTime now = DateTime.Now;
 
    // Get the days and milliseconds which will be used to build    
    //the byte string    
    TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
    TimeSpan msecs = now.TimeOfDay;
 
    // Convert to a byte array        
    // Note that SQL Server is accurate to 1/300th of a    
    // millisecond so we divide by 3.333333    
    byte[] daysArray = BitConverter.GetBytes(days.Days);
    byte[] msecsArray = BitConverter.GetBytes((long)
      (msecs.TotalMilliseconds / 3.333333));
 
    // Reverse the bytes to match SQL Servers ordering    
    Array.Reverse(daysArray);
    Array.Reverse(msecsArray);
 
    // Copy the bytes into the guid    
    Array.Copy(daysArray, daysArray.Length - 2, guidArray,
      guidArray.Length - 6, 2);
    Array.Copy(msecsArray, msecsArray.Length - 4, guidArray,
      guidArray.Length - 4, 4);
 
    return new Guid(guidArray);
}

 

 

 

Twitter的snowflake算法   

反正代码 如下 试用也很简单  实例化以后 next()  就行了 

    public class IdWorker
        {
            private long workerId;
            private long datacenterId;
            private long sequence = 0L;

            private static long twepoch = 1288834974657L;

            private static long workerIdBits = 5L;
            private static long datacenterIdBits = 5L;
            private static long maxWorkerId = -1L ^ (-1L << (int)workerIdBits);
            private static long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);
            private static long sequenceBits = 12L;

            private long workerIdShift = sequenceBits;
            private long datacenterIdShift = sequenceBits + workerIdBits;
            private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
            private long sequenceMask = -1L ^ (-1L << (int)sequenceBits);

            private long lastTimestamp = -1L;
            private static object syncRoot = new object();

            public IdWorker(long workerId, long datacenterId)
            {

                // sanity check for workerId
                if (workerId > maxWorkerId || workerId < 0)
                {
                    throw new ArgumentException(string.Format("worker Id can't be greater than %d or less than 0", maxWorkerId));
                }
                if (datacenterId > maxDatacenterId || datacenterId < 0)
                {
                    throw new ArgumentException(string.Format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
                }
                this.workerId = workerId;
                this.datacenterId = datacenterId;
            }

            public long nextId()
            {
                lock (syncRoot)
                {
                    long timestamp = timeGen();

                    if (timestamp < lastTimestamp)
                    {
                        throw new ApplicationException(string.Format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
                    }

                    if (lastTimestamp == timestamp)
                    {
                        sequence = (sequence + 1) & sequenceMask;
                        if (sequence == 0)
                        {
                            timestamp = tilNextMillis(lastTimestamp);
                        }
                    }
                    else
                    {
                        sequence = 0L;
                    }

                    lastTimestamp = timestamp;

                    return ((timestamp - twepoch) << (int)timestampLeftShift) | (datacenterId << (int)datacenterIdShift) | (workerId << (int)workerIdShift) | sequence;
                }
            }

            protected long tilNextMillis(long lastTimestamp)
            {
                long timestamp = timeGen();
                while (timestamp <= lastTimestamp)
                {
                    timestamp = timeGen();
                }
                return timestamp;
            }

            protected long timeGen()
            {
                return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
            }
        }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值