Leaf——美团点评分布式ID生成系统中Leaf-segment数据库方案的实现
Switch branches/tags
Nothing to show
Clone or download
sunff sunff
sunff and sunff 完善包目录
Latest commit 0939111 Aug 25, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
sql 增加使用说明 May 19, 2017
src 完善包目录 Aug 25, 2018
README.md 重构package Apr 3, 2018
pom.xml 升级版本 Aug 24, 2018

README.md

idleaf

简介

对于 Leaf——美团点评分布式ID生成系统 中介绍的 Leaf-segment数据库方案 生成唯一orderId的方案的一个实现。 在实现中使用双buffer优化,在第一个buffer使用50%的时候去加载另一个buffer的数据,这里分同步与异步两种方式,默认是同步加载。对于异步增加参数asynLoadingSegment 设为true. 在第一个buffer使用完毕之后,切换到另一个buffer,需要去验证该buffer是否加载完成数据,然后进行切换(对于异步加载出了异常则同步加载数据,然后再切换,此时会产生发号的阻塞)。

使用示例

一种业务id使用方式

<bean id="idLeafService" 	class="com.z.idleaf.support.MysqlIdLeafServiceImpl">
	<property name="jdbcTemplate" ref="jdbcTemplate" />
	<property name="asynLoadingSegment" value="true" />
	<property name="bizTag" value="order"></property>
</bean>

Long id=idLeafService.getId()

多个业务id使用方式

<bean id="parentIdLeafService"  abstract="true" 	class="com.z.idleaf.support.MysqlIdLeafServiceImpl">
	<property name="jdbcTemplate" ref="jdbcTemplate" />
	<property name="asynLoadingSegment" value="true" />
	
</bean>

<bean id="productIdLeafService"  parent="parentIdLeafService">
	<property name="bizTag" value="product"></property>
</bean>

<bean id="orderIdLeafService"  parent="parentIdLeafService">
	<property name="bizTag" value="order"></property>
</bean>




Long orderId=orderIdLeafService.getId();
Long productId=productIdLeafService.getId();

spring提供的关于主键生成的策略

spring 框架是无所不能,关于主键的生成它也提供了类似的功能,相应的类为org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer 但是这个类只保证单jvm的唯一性,在集群环中它会有并发更新的问题,所以我在此写了一个ExtendMySQLMaxValueIncrementer。思路还是沿袭上面的。

使用示例

<bean id="extendMysqlMaxValueIncrementer" abstract="true"
	class="com.z.idleaf.support.ExtendMySQLMaxValueIncrementer">
	<property name="dataSource" ref="testDataSource" />
	<property name="asynLoadingSegment" value="true"></property>
	<property name="incrementerName" value="id_segment" />
	<property name="columnName" value="max_id" />
	<property name="stepField" value="p_step" />
	<property name="bizField" value="biz_tag"></property>
	<property name="lastUpdateTimeField" value="last_update_time" />
	<property name="updateTimeField" value="current_update_time" />
	<property name="paddingLength" value="6"></property>

</bean>

<bean id="orderIncrementer" parent="extendMysqlMaxValueIncrementer">
	<property name="bizTag" value="order" />
</bean>

<bean id="productNoIncrementer" parent="extendMysqlMaxValueIncrementer">
	<property name="bizTag" value="productNo" />
</bean>

 @Autowired
@Qualifier("productNoIncrementer")
private DataFieldMaxValueIncrementer incrementer;

@Test
public void test() {
    int i = 0;
    while (i < 10) {
        System.out.println("long id=" + incrementer.nextLongValue());
        System.out.println("int id=" + incrementer.nextIntValue());
        System.out.println("string id=" + incrementer.nextStringValue());
        i++;
    }
}

spring 帮我们提供了三个接口,分别为获取int,long,string 三种数据类型。当然这种方式需要深度使用spring-jdbc框架.

带基因法id生成

基因法生成id,主要思路来自架构师之路 实现接口com.z.idleaf.WithGeneIdLeafService 使用示例

<bean id="idLeafService"    class="com.z.idleaf.support.MysqlIdLeafServiceImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
    <property name="asynLoadingSegment" value="true" />
    <property name="bizTag" value="order"></property>
</bean>
<bean id="withGeneIdLeafService" class="com.z.idleaf.support.WithGeneIdLeafServiceImpl">
	 <property name="idLeafService" ref="idLeafService" />
    <property name="dbSize" value="32" />
</bean>
Long orderId=withGeneIdLeafService.getId(10000L)