原来ShardingSphere也用雪花算法

时间:2022-10-15 22:01:33

原来ShardingSphere也用雪花算法

分布式主键的生成有很多实现方式,比如百度开源的UidGenerator、美团的Leaf、以及众所周知的雪花算法,而在分库分表的场景下,id要保证唯一性,分布式主键就显得尤为重要。

ShardingSphere又是使用的哪种生成策略呢,这篇文章带你一探究竟。

生成主键入口

在sharding-core-route模块下有个GeneratedKey类,它的getGenerateKey()方法中会先获取自增长的列,如果自增长列没有生成主键的话就调用createGeneratedKey()方法来生成,我们看一下它具体是怎么生成主键的

生成主键

GeneratedKey的createGeneratedKey()方法是用来生成主键的,但这个方法也没有写具体生成主键的逻辑,而是调用了ShardingRule的generateKey()来进行生成,生成的主键放入链表集合中保存。

ShardingRule的generateKey()方法:

    public Comparable<?> generateKey(final String logicTableName) {
        Optional<TableRule> tableRule = findTableRule(logicTableName);
        if (!tableRule.isPresent()) {
            throw new ShardingConfigurationException("Cannot find strategy for generate keys.");
        }
        ShardingKeyGenerator shardingKeyGenerator = null == tableRule.get().getShardingKeyGenerator() ? defaultShardingKeyGenerator : tableRule.get().getShardingKeyGenerator();
        return shardingKeyGenerator.generateKey();
    }

这一块的代码很重要,首先会根据逻辑表的名字查找对应的TableRule,如果不存在的话就抛出找不到生成主键的策略,如果存在会根据TableRule获取ShardingKeyGenerator的实例,从而调用generateKey()方法来生成主键。所以要看ShardingSphere使用了什么分布式主键策略还是要看TableRule的ShardingKeyGenerator属性填充了什么实例

生成主键的策略选择

从TableRule的构造方法中我们可以看到它的ShardingKeyGenerator属性填充调用了ShardingKeyGeneratorServiceLoader的newService()方法,这个类是不是很熟悉?没错,就是我们上篇文章分析了利用了Java的SPI机制来加载ShardingKeyGenerator的实现类的实例,ShardingKeyGenerator的实现类定义在resources文件夹下的META-INF/services的org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator文件中:

org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator
org.apache.shardingsphere.core.strategy.keygen.UUIDShardingKeyGenerator

这两个正是ShardingKeyGenerator的实现类SnowflakeShardingKeyGenerator和UUIDShardingKeyGenerator,分别是雪花算法的主键生成策略类和UUID的主键生成策略类

雪花算法

雪花算法是个老生常谈的内容了,长度为64位,第一位是符号位,第二部分41位,为时间戳,这里需要注意一下,如果机器发生时钟回拨问题,也就是机器的时间回到了之前的时间,这就可能会到导致产生的ID重复,这时候程序做了抛出异常或者等待时间到了最新时候后再生成ID的处理,第三部分10位是工作的进程位,由5位机房id和5位机器id组成,第四部分是12位是一毫秒内生成的序列ID

UUID

这个的实现很简单,就是生成UUID,这里就不细说了,懂得都懂

总结

这篇文章我们介绍了ShardingSphere的分布式主键的生成方式是怎样的,从GeneratedKey这个类的createGeneratedKey()方法为入口,一步步分析出了主键的生成是由ShardingKeyGenerator接口的实现类来完成的,而它的实现类的加载利用了Java的SPI机制。生成主键的策略有雪花算法和UUID,在之后的ShardingSphere的源码也支持了美团的Leaf算法,这里就不细说了。

❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话:

  1. 欢迎关注我❤️,点赞????????,评论????,转发????
  2. 关注盼盼小课堂,定期为你推送好文,还有群聊不定期抽奖活动,可以畅所欲言,与大神们一起交流,一起学习。
  3. 有不当之处欢迎批评指正。