ShardingSphere源码分析—分布式主键实现

本文深入探讨了ShardingSphere的分布式主键实现,从GeneratedKey接口出发,详细解析了UUIDShardingKeyGenerator、SnowflakeShardingKeyGenerator以及LeafSegmentKeyGenerator和LeafSnowflakeKeyGenerator的实现原理。文章覆盖了Snowflake算法的时间戳、工作进程位和序列号位,以及如何处理时钟回拨问题。最后,提到了ShardingSphere在新版本中对Leaf框架的整合,使得分布式ID生成更加便捷。
摘要由CSDN通过智能技术生成

分布式主键

在传统数据库软件开发过程中,主键自动生成技术是基本需求。各个数据库对该需求也提供了相应的支持,比如 MySQL 的自增键,Oracle 的自增序列等。而在分片场景下,问题就变得有点复杂,我们不能依靠单个实例上的自增键来实现不同数据节点之间的全局唯一主键,这时分布式主键的需求就应运而生。ShardingSphere 作为一款优秀的分库分表开源软件,同样提供了分布式主键的实现机制,今天,我们就对这一机制的基本原理和实现方式展开讨论。

ShardingSphere 中的自动生成键方案

在介绍 ShardingSphere 提供的具体分布式主键实现方式之前,我们有必要先对框架中抽象的自动生成键 GeneratedKey 方案进行讨论,从而帮助你明确分布式主键的具体使用场景和使用方法。

ShardingSphere 中的 GeneratedKey

GeneratedKey 并不是 ShardingSphere 所创造的概念。如果你熟悉 Mybatis 这种 ORM 框架,对它就不会陌生。通常,我们会在 Mybatis 的 Mapper 文件中设置 useGeneratedKeys 和 keyProperty 属性:

    <insert id="addEntity" useGeneratedKeys="true" keyProperty="recordId" > 
        INSERT INTO health_record (user_id, level_id, remark)  
        VALUES (#{userId,jdbcType=INTEGER}, #{levelId,jdbcType=INTEGER},  
             #{remark,jdbcType=VARCHAR}) 
    </insert> 

在执行这个 insert 语句时,返回的对象中自动包含了生成的主键值。当然,这种方式能够生效的前提是对应的数据库本身支持自增长的主键。

当我们使用 ShardingSphere 提供的自动生成键方案时,开发过程以及效果和上面描述的完全一致。在 ShardingSphere 中,同样实现了一个 GeneratedKey 类。请注意,该类位于 sharding-core-route 工程下。我们先看该类提供的 getGenerateKey 方法:

    public static Optional<GeneratedKey> getGenerateKey(final ShardingRule shardingRule, final TableMetas tableMetas, final List<Object> parameters, final InsertStatement insertStatement) {
    
        //找到自增长列 
     Optional<String> generateKeyColumnName = shardingRule.findGenerateKeyColumnName(insertStatement.getTable().getTableName()); 
        if (!generateKeyColumnName.isPresent()) {
    
            return Optional.absent(); 
        } 
         
        //判断自增长类是否已生成主键值 
        return Optional.of(containsGenerateKey(tableMetas, insertStatement, generateKeyColumnName.get()) 
                ? findGeneratedKey(tableMetas, parameters, insertStatement, generateKeyColumnName.get()) : createGeneratedKey(shardingRule, insertStatement, generateKeyColumnName.get())); 
	} 

这段代码的逻辑在于先从 ShardingRule 中找到主键对应的 Column,然后判断是否已经包含主键:如果是则找到该主键,如果不是则生成新的主键。今天,我们的重点是分布式主键的生成,所以我们直接来到 createGeneratedKey 方法:

    private static GeneratedKey createGeneratedKey(final ShardingRule shardingRule, final InsertStatement insertStatement, final String generateKeyColumnName) {
    
        GeneratedKey result = new 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值