标签:属性 tom 使用情况 分布 序列 sequence 全局 gre 一个
在分布式系统中都涉及到全局序列号的问题,网上分布式id生成的核心思路大概有以下几种
基于UUID
本人以前做过一个java实现的基于Snowflake实现的全局id生成器,当时需求是生成20位的id,主要解决了机器启动时机器id的无法确定的问题,依赖zookeeper。github地址,在了解到更多的分布式id生成方案后,对分布式id生成又有了新的思路。
可将redis换成zookeeper等其它的原子性的long操作。
该实现主要有三个类或接口AtomicLongBufferRepository、AtomicLongBuffer以及GlobalAtomicLongService,下面具体说明各个实现思路以及使用方法。
该类是用于实现根据序列名对外提供全局的id。
private static final String DEFAULT_SEQ_NAME = "DEFAULT_WHOLE_SEQUENCE_NAME";
默认的序列名private final Map<String, AtomicLongBuffer> pool = new ConcurrentHashMap<>(16);
通过线程安全的ConcurrentHashMap来保存不同序列的缓存private SequenceMapper mapper;
传给AtomicLongBuffer使用
public long incrementAndGet(String sequenceName)
对外提供的通过序列名获取序列号public long incrementAndGet()
对外提供的默认序列名的序列号,实际上调用public long incrementAndGet(String sequenceName)
方法private AtomicLongBuffer createSequenceIfNotExistAndGet (String sequenceName)
内部使用,获取对应序列号的缓存实现类public Map<String, AtomicLongBuffer> getPool()
获取存储序列的map,主要用于定时检查各个序列缓存使用情况,在缓存快使用完成后进行下一次缓存
该类主要实现的是双buffer策略,通过双buffer来减少io时间提升性能。
private final Object lock = new Object();
类中使用的锁对象private String sequenceName;
当前序列名protected AtomicLong[] buffer =new AtomicLong[]{new AtomicLong(0),new AtomicLong(0)};
缓存对象,每次从这里取idprotected long[] maxIds = new long[]{0,0};
当前缓存阶段id的最大值protected int[] steps = new int[]{10,10};
缓存的步长private AtomicBoolean isPerparing = new AtomicBoolean(false);
是否正在进行缓存private AtomicBoolean[] isOks = new AtomicBoolean []{new AtomicBoolean(false),new AtomicBoolean(false)}
两个缓存区的状态private GlobalAtomicLongService atomicLongService;
缓存区的值的获取对象private int currentIndex=0;
当前所在的缓存区private LongAdder count = new LongAdder();
计数器,统计缓存周期内的id消耗量,用于计算下一次缓存步长private SequenceMapper mapper;
mybatis的一个mapper,用于查询、更新序列号信息
public long incrementAndGet()
通过缓存区获取全局id。public void validateStatus()
校验当前缓存区id使用情况,剩余10%时开始缓存另外一个缓存区private void startPerpareProgress(int index)
开始缓存指定缓存区private void storeMaxSequence(long max)
持久化序列号信息到数据库private void completePrepare(int index)
缓存过程结束
long addAndGet(long addValue);
抽象了全局id缓存的获取接口,可将redis实现替换成zookeeper实现获mysql实现void set(long newValue);
抽象了更新全局id的接口
整个分布式id的获取以及生成的流程图如下
标签:属性 tom 使用情况 分布 序列 sequence 全局 gre 一个
原文地址:https://www.cnblogs.com/many-object/p/11304693.html