Java服务端分布式ID生成:Snowflake与Leaf的比较
在分布式系统中,生成唯一ID是一个常见需求。随着业务的扩展,传统的数据库自增ID已无法满足需求。Snowflake和Leaf是两种流行的分布式ID生成方案,它们都能提供高并发、高可用的ID生成服务。本文将探讨这两种方案的特点、使用方式和适用场景。
分布式ID生成的基本概念
分布式ID生成要求在分布式系统中生成唯一的标识符,这些ID需要具备唯一性、趋势递增和高性能等特点。
Snowflake 简介
Snowflake是Twitter开源的分布式ID生成算法,它生成的是一个64位的长整型数,包含4部分:1位符号位、41位时间戳、10位工作机器ID和12位序列号。
优点:
- 唯一性:在不同节点生成不同的ID。
- 趋势递增:时间戳的单调递增保证了ID的递增性。
Java 示例代码:
package cn.juwatech.id;
public class SnowflakeIdWorker {
private final long workerId;
private final long datacenterId;
private final long sequenceMask = -1L ^ (-1L << 12);
private long lastTimestamp = -1L;
private long sequence = 0L;
public SnowflakeIdWorker(long workerId, long datacenterId) {
if (workerId > 31 || workerId < 0) {
throw new IllegalArgumentException("worker Id can't be greater than 31 or less than 0");
}
if (datacenterId > 31 || datacenterId < 0) {
throw new IllegalArgumentException("datacenter Id can't be greater than 31 or less than 0");
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(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 = 0;
}
lastTimestamp = timestamp;
return ((timestamp - 1288834974657L) << 22) | (datacenterId << 12) | sequence;
}
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
protected long timeGen() {
return System.currentTimeMillis();
}
}
Leaf 简介
Leaf是美团开源的分布式ID生成系统,它通过DB或Zookeeper生成序列号,保证ID的递增和唯一性。
优点:
- 高可用:通过DB或Zookeeper实现高可用。
- 易于扩展:支持自定义实现,易于扩展。
Java 示例代码:
package cn.juwatech.id;
import me.zhyd.leaf.core.LeafDay;
import me.zhyd.leaf.core.LeafUtil;
public class LeafIdWorker {
private static final LeafDay LEAF = LeafUtil.getLeafDay();
public static long nextId() {
return LEAF.nextId();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
long id = nextId();
System.out.println(Long.toBinaryString(id));
System.out.println(id);
}
}
}
Snowflake 与 Leaf 的比较
-
实现方式:
- Snowflake通过算法生成ID,不需要依赖外部系统。
- Leaf通过DB或Zookeeper生成ID,依赖外部系统。
-
易用性:
- Snowflake实现简单,易于集成。
- Leaf提供了更多的配置选项,但配置相对复杂。
-
性能:
- Snowflake性能较高,生成ID速度快。
- Leaf性能取决于DB或Zookeeper的性能。
应用场景
- Snowflake:适合对性能要求高,不需要依赖外部系统的分布式ID生成场景。
- Leaf:适合需要高可用和易于扩展的分布式ID生成场景。
结论
Snowflake和Leaf都是优秀的分布式ID生成方案,它们各有优势和适用场景。选择哪个方案取决于项目的具体需求、对性能和可用性的要求。在Java服务端,通过合理使用这些方案,可以有效地生成分布式系统中的唯一ID。