Twitter全局唯一ID生成算法
2016-08-09 17:40
573 查看
测试:private static void TestIdWorker() { HashSet<long> set = new HashSet<long>(); IdWorker idWorker1 = new IdWorker(0, 0); IdWorker idWorker2 = new IdWorker(1, 0); //762884413578018816 //762884520121729024 Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 1; i++) { long id = idWorker1.nextId(); set.Add(id); //if (!set.Add(id)) //{ //Console.WriteLine("duplicate:" + id); //} } sw.Stop(); foreach (var item in set) { Console.WriteLine("结果:" + item); } Console.WriteLine("时间:" + sw.ElapsedTicks); return; } 算法: /// <summary> /// From: https://github.com/twitter/snowflake /// An object that generates IDs. /// This is broken into a separate class in case /// we ever want to support multiple worker threads /// per process /// </summary> 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; } }
相关文章推荐
- 全局唯一ID生成常见的几种方式和twitter/snowflake(雪花算法)解析
- Twitter的分布式自增ID算法Snowflake的PHP实现,Snowflake PHP版本,高并发唯一id,全局唯一id,不重复id
- [Java--算法]--生成全局唯一的Id(IdGen)
- 基于业务对Twitter生成全局唯一ID的SnowFlake算法的改造
- web集群全局唯一request id生成算法, 替代uuid等“通用”方案
- 利用网上的Caesar算法写了一个全局唯一id生成类
- 全局唯一ID的生成方式
- 生成全局唯一Id
- 如何在高并发分布式系统中生成全局唯一Id
- 如何在高并发分布式系统中生成全局唯一Id
- 一个简单的游戏服务器生成全局唯一ID
- 高并发 sql 生成不重复编号 (订单号) & 如何在高并发分布式系统中生成全局唯一Id
- 全局唯一ID的生成策略对比
- (转)如何在高并发分布式系统中生成全局唯一Id
- 如何在高并发分布式系统中生成全局唯一Id
- 生成全局唯一id
- 关于全局唯一ID生成方法
- 全局唯一ID生成方案对比
- 如何在高并发分布式系统中生成全局唯一Id