`

SnowFlake 分布式ID生成算法Java实现

    博客分类:
  • Java
阅读更多

SnowFlake 分布式ID生成Java实现

SnowFlake不依赖第三方介质,不像基于ZK,Redis等,每次用完一个区间还得通过网络去获取下一个区间,效率较低,基于SnowFlake的分布式ID生成是目前我见过的最快的

 

SnowFlake生成的是一个64位的数字,其中42位时间戳,接下来10位是自定义的数,其作用就是区分集群中的所有机器,最后12位是毫秒内序列,集群内每个机器能够在1毫秒内生成2^12 - 1个ID

 

 

/**
* 基于SnowFlake的序列号生成实现, 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
*/
static class Generator {

		private final static long TWEPOCH = 1288834974657L;

		// 机器标识位数
		private final static long WORKER_ID_BITS = 5L;

		// 数据中心标识位数
		private final static long DATA_CENTER_ID_BITS = 5L;

		// 机器ID最大值 31
		private final static long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS);

		// 数据中心ID最大值 31
		private final static long MAX_DATA_CENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS);

		// 毫秒内自增位
		private final static long SEQUENCE_BITS = 12L;

		// 机器ID偏左移12位
		private final static long WORKER_ID_SHIFT = SEQUENCE_BITS;

		private final static long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;

		// 时间毫秒左移22位
		private final static long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;

		private final static long SEQUENCE_MASK = -1L ^ (-1L << SEQUENCE_BITS);

		private long lastTimestamp = -1L;

		private long sequence = 0L;
		private final long workerId;
		private final long dataCenterId;
		
		//private final AtomicBoolean lock = new AtomicBoolean(false);
		
		Generator(long workerId, long dataCenterId) {
			if (workerId > MAX_WORKER_ID || workerId < 0) {
				throw new IllegalArgumentException(String.format("%s must range from %d to %d", K_WORK_ID, 0,
						MAX_WORKER_ID));
			}

			if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
				throw new IllegalArgumentException(String.format("%s must range from %d to %d", K_DC_ID, 0,
						MAX_DATA_CENTER_ID));
			}

			this.workerId = workerId;
			this.dataCenterId = dataCenterId;
		}

		synchronized long nextValue() throws SequenceException {
			long timestamp = time();
			if (timestamp < lastTimestamp) {
				throw new SequenceException("Clock moved backwards, refuse to generate id for "
						+ (lastTimestamp - timestamp) + " milliseconds");
			}

			if (lastTimestamp == timestamp) {
				// 当前毫秒内,则+1
				sequence = (sequence + 1) & SEQUENCE_MASK;
				if (sequence == 0) {
					// 当前毫秒内计数满了,则等待下一秒
					timestamp = tilNextMillis(lastTimestamp);
				}
			} else {
				sequence = 0;
			}
			lastTimestamp = timestamp;
			
			// ID偏移组合生成最终的ID,并返回ID
			long nextId = ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT)
					| (dataCenterId << DATA_CENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT) | sequence;

			return nextId;
		}

		private long tilNextMillis(final long lastTimestamp) {
			long timestamp = this.time();
			while (timestamp <= lastTimestamp) {
				timestamp = this.time();
			}
			return timestamp;
		}

		private long time() {
			return System.currentTimeMillis();
		}

	}

 

0
2
分享到:
评论
5 楼 莫名的拉风 2016-12-29  
bjyzxxds 写道
bjyzxxds 写道
莫名的拉风 写道
bjyzxxds 写道
重点就在这个10位自定义数,需要考虑应用自动弹性扩展时,如何自动获取,不用zk、redis,那也得找个其他的或者自己写个,总之跑不了

这个数一般无须变化,所以在配置文件里面配没啥问题吧


当然必须变化,否则就有产生相同id的情况出现

对于已启动的应用,在运行过程中,是不需要变化的,但是弹性扩展出来的新实例,必须与已有实例中的配置不一样。

嗯,确实是
4 楼 bjyzxxds 2016-12-29  
bjyzxxds 写道
莫名的拉风 写道
bjyzxxds 写道
重点就在这个10位自定义数,需要考虑应用自动弹性扩展时,如何自动获取,不用zk、redis,那也得找个其他的或者自己写个,总之跑不了

这个数一般无须变化,所以在配置文件里面配没啥问题吧


当然必须变化,否则就有产生相同id的情况出现

对于已启动的应用,在运行过程中,是不需要变化的,但是弹性扩展出来的新实例,必须与已有实例中的配置不一样。
3 楼 bjyzxxds 2016-12-29  
莫名的拉风 写道
bjyzxxds 写道
重点就在这个10位自定义数,需要考虑应用自动弹性扩展时,如何自动获取,不用zk、redis,那也得找个其他的或者自己写个,总之跑不了

这个数一般无须变化,所以在配置文件里面配没啥问题吧


当然必须变化,否则就有产生相同id的情况出现
2 楼 莫名的拉风 2016-12-29  
bjyzxxds 写道
重点就在这个10位自定义数,需要考虑应用自动弹性扩展时,如何自动获取,不用zk、redis,那也得找个其他的或者自己写个,总之跑不了

这个数一般无须变化,所以在配置文件里面配没啥问题吧

1 楼 bjyzxxds 2016-12-29  
重点就在这个10位自定义数,需要考虑应用自动弹性扩展时,如何自动获取,不用zk、redis,那也得找个其他的或者自己写个,总之跑不了

相关推荐

    分布式ID生成策略_snowflake算法

    Snowflake算法是由Twitter开源的一种高效且可扩展的分布式ID生成方案,广泛应用于Java和其他编程语言的系统中。 Snowflake算法的核心思想是将64位的整数划分为不同的部分,分别为: 1. **时间戳**(41位):自定义...

    java 分布式 代码生成器 唯一ID

    结合上述信息,"idGenerate"这个文件很可能是包含了一个Java实现的分布式代码生成器项目,可能包含了Snowflake算法或者其他分布式ID生成策略的源代码。通过学习和理解这些代码,我们可以更好地掌握在Java环境中如何...

    java 获取分布式唯一ID.雪花ID

    总结来说,Java中获取分布式唯一ID可以通过实现雪花ID算法,例如`SnowflakeIdWorker`,它能提供时间序列的64位整数ID。同时,可以使用`UUID`生成字符串唯一ID,但不适用于分布式环境。而`IdUtils`中的方法可能是对...

    Twitter的分布式自增ID雪花算法snowflake

    雪花算法是Twitter开源的一种分布式ID生成算法,它能够生成全局唯一、递增且无碰撞的64位整数ID。这个算法在分布式系统中非常适用,因为传统的序列号生成方式在分布式环境中往往难以解决冲突问题。下面我们将详细...

    分布式id生成器.zip

    UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。 在实现上...

    分布式ID生成策略(1)_snowflake算法

    Snowflake算法就是一种被广泛使用的分布式ID生成方案,它由Twitter开源,具有时间戳、工作机器ID和序列号三部分组成,能够确保在分布式环境下生成的ID具有唯一性、有序性和高性能。 Snowflake算法的核心思想是将64...

    distributed-id:基于netty4+twitter-snowFlake分布式Id生成之服务实现

    雪花算法分布式ID生成器 该项目的目的是提供一个轻量级、高并发、高可用的生成唯一ID的服务,生成的ID是一个64位的 长整型,全局唯一,保持递增,相对有序。基于twitter的雪花算法来生成ID,用于取代UUID那种无序、...

    迄今为止最全面的分布式主键ID生成器,多语言新雪花算法(SnowFlake IdGenerator).zip

    迄今为止最全面的分布式主键ID生成器。 优化的雪花算法(SnowFlake)——雪花漂移算法,在缩短ID长度的同时,具备极高瞬时并发处理能力(50W/0.1s)。 原生支持 C#/Java/Go/Rust/C/SQL 等多语言,且提供 PHP 扩展及 ...

    Java实现Twitter的分布式自增ID算法snowflake

    总结来说,Java实现的Twitter Snowflake算法是一种高效、有序的分布式自增ID生成器,适用于需要全局唯一标识且对时间顺序有要求的系统。通过合理的位分配,它能够在分布式环境中提供线性扩展性和时间上的顺序性。

    通用、灵活、高性能的分布式 ID 生成器

    1. **分布式算法实现**:可能基于Snowflake或其他优化的ID生成算法,保证全局唯一性。 2. **服务化部署**:作为一个独立的服务,可以被其他微服务或应用通过网络调用。 3. **可配置性**:允许用户自定义ID结构,比如...

    springboot分布式自增id_javaredis_源码

    在分布式系统中,为了生成全局唯一的自增ID,可以使用Snowflake算法、Twitter的分布式ID生成服务,或者基于Redis的序列号生成方案。Spring Boot可以轻松集成这些方案,通过配置和注解简化开发流程。 2. **Redis作为...

    迄今为止最全面的分布式主键ID生成器优化的雪花算法(SnowFlake)雪花漂移算法在缩短ID长度的同时具备高瞬时并发处理能力

    迄今为止最全面的分布式主键ID生成器。 优化的雪花算法(SnowFlake)——雪花漂移算法,在缩短ID长度的同时,具备极高瞬时并发处理能力(50W/0.1s)。 原生支持 C#/Java/Go/Rust/C/SQL 等多语言,且提供 PHP 扩展及 ...

    分布式ID生成器的解决方案总结.docx

    分布式ID生成器是大型互联网系统中不可或缺的一部分,其主要任务是为系统中的各种实体生成全局唯一的标识符(ID)。在复杂分布式环境下,选择合适的ID生成策略对于系统的性能、可用性和可扩展性至关重要。以下是几种...

    基于Java和Lua的微服务架构高并发高可用神经网络设计源码

    该项目是一个基于Java和Lua的微服务架构设计,专注于实现高并发和高可用的神经网络服务...此外,项目还包含了多项创新技术,如IP黑白名单管理、增强版UUID、Snowflake分布式ID生成算法以及高效的大并发时间戳获取技术。

    分布式ID生成器(雪花算法SpringBoot版)

    全局唯一ID作为一种唯一标识来区分数据,可用作订单号、用户ID等。ID生成器是生成全局唯一ID的工具,可封装为一种基础服务为其他业务提供服务。因此此项目就是用springboot封装ID生成器,让各种业务系统调用

    全局唯一ID生成

    在分布式ID生成的项目中,"src"目录下可能包含了实现各种ID生成算法的Java代码,而"WebContent"则可能包含展示或测试这些ID生成服务的前端页面。 总的来说,全局唯一ID生成是分布式系统设计中的核心问题之一,涉及...

    java快速ID自增器

    在Java开发中,高效地生成唯一且自增...它可以是基于Java内置的原子类、数据库序列、分布式ID生成算法,或者是结合数据库和Spring框架的高级应用场景。选择哪种方案取决于具体的应用场景、性能需求以及系统是否分布式。

    idworker:idworker是一个基于zookeeper和snowflake算法的分布式ID生成工具,通过zookeeper自动注册机器(最多1024台),无需手动指定workerId和datacenterId

    idworker是一个基于zookeeper和snowflake算法的分布式统一ID生成工具,通过zookeeper自动注册机器(最多1024台),无需手动指定workerId和dataCenterId 怎么用 Maven &lt; groupId&gt;com.imadcn.framework&lt;/ groupId&gt; ...

Global site tag (gtag.js) - Google Analytics