一、基本概念
UUID,即通用唯一标识符(Universally Unique Identifier),是由一组十六进制数字组成的标识符,可以用来在分布式系统中唯一地标识某个信息。UUID是一种用于多个计算机之间的唯一标识符,用于指示文件或数据库内的唯一对象。
/** * 生成UUID */ public static String generateUUID() { return UUID.randomUUID().toString().replace("-", ""); }
雪花算法,即Snowflake算法,是一种生成ID的算法,它可以保证在分布式系统中生成ID是唯一的。Snowflake算法的核心是一个64位的二进制数字,由以下三部分组成:
1、时间戳(42位):毫秒级时间戳,从开始使用此算法的时间点开始算起,在递增中产生,最大可用69年;
2、机器标识(10位):可以指定每个节点的ID从0-1023进行编号;
3、序列号(12位):同一毫秒级时间戳下,不同机器的序列号会依次递增,最多可以生成4096个ID。
/** * 雪花算法 * * @param dataCenterId 数据中心ID * @param workerId 工作机器ID * @return 分布式ID */ public long snowFlake(long dataCenterId, long workerId) { long timestamp = System.currentTimeMillis(); // 时间戳部分 long timeBits = timestamp - SNOW_FLAKE_EPOCH; // 数据中心ID部分 long dataCenterIdBits = dataCenterId << SNOW_FLAKE_DATACENTER_ID_SHIFT; // 工作机器ID部分 long workerIdBits = workerId << SNOW_FLAKE_WORKER_ID_SHIFT; // 组装分布式ID return timeBits | dataCenterIdBits | workerIdBits | sequence; }
二、唯一性
UUID的唯一性基于产生随机性的伪随机数生成器,因此生成的UUID是几乎不可能重复的,但也不能完全避免重复。
相比之下,雪花算法的唯一性更可靠,因为它对时间戳、数据中心ID、工作机器ID和序列号进行了组合,可以确保在不同时间戳下不同数据中心、不同工作机器之间产生的ID绝对唯一。但也要注意,如果当前工作机器ID生成的序列号达到了上限,就会有重复ID的风险。
三、性能
UUID的生成速度相对较快,建议在需要使用anonymize identifier时使用。但是,由于UUID的长度比较长(128位),在使用时需要花费更多的磁盘空间和网络带宽。
雪花算法的生成速度也比较快,但要求系统时钟准确无误,否则就会有ID重复的问题。此外,在分布式系统中使用时,需要考虑数据中心ID和工作机器ID的分配问题,避免重复。
四、适用场景
UUID可以在多个分布式系统中保持唯一性,因此广泛应用于匿名或无需长期存储的系统,如会话标识符、Cookie ID和游戏中的临时ID等。
雪花算法适用于分布式系统中的唯一ID生成,可用于唯一订单号、会员ID和设备ID等。但是,在多个数据中心之间运行时,需要根据数据中心ID和工作机器ID通过算法配置进行规划,否则就会产生ID冲突。