分库分表实战及中间件(四)

分库分表实战及中间件(四)

在一些应用场景中,分片条件并不存在于SQL,而存在于外部业务逻辑。因此需要提供一种通过在外部业务代码中指定路由配置的一种方式,在ShardingSphere中叫做Hint。如果使用Hint指定了强制分片路由,那么SQL将会无视原有的分片逻辑,直接路由至指定的数据节点操作。

Hint使用场景

  • 数据分片操作,如果分片键没有在SQL或数据表中,而是在业务逻辑代码中
  • 读写分离操作,如果强制在主库进行某些数据操作

在读写分离结构中,为了避免主从同步数据延迟及时获取刚添加或更新的数据,可以采用强制路由走主库查询实时数据,使用hintManager.setMasterRouteOnly设置主库路由即可。

如何使用

就想我们之前自定义分表策略一样,sharding也为我们提供了接口,实现HintShardingAlgorithm接口,编写分库或分表路由策略。

这儿我们配置test0,test1两个数据库,两个库中分别分了两个表position_master_slave0,position_master_slave1

我们对其取模2进行强制路由策略

/**
 * hint 分片策略
 */
public class HintStrategyConfig implements HintShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(
            Collection<String> collection, //库或者表集合
            HintShardingValue<Long> hintShardingValue//路由key
    ) {


        List<String> result = new ArrayList<>();

        for (String table : collection) {

            Collection<Long> values = hintShardingValue.getValues();
            for (Long value : values) {

                //这儿指定路由规则 我们这儿对库取模 后缀是多少进行选择库
                if (table.endsWith(String.valueOf(value % 2))){
                    result.add(table);
                }

            }

        }

        return result;

    }
}
复制代码

配置


#打印shardingsphere sql
spring.shardingsphere.props.sql.show=true

# 分库信息配置
spring.shardingsphere.datasource.names=test0,test1

#配置数据库信息


#配置连接池
spring.shardingsphere.datasource.test0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.test0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.test0.jdbc-url=jdbc:mysql://localhost:3306/test0
spring.shardingsphere.datasource.test0.username=root
spring.shardingsphere.datasource.test0.password=root


#配置连接池
spring.shardingsphere.datasource.test1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.test1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.shardingsphere.datasource.test1.username=root
spring.shardingsphere.datasource.test1.password=root


#hint 强制指定库 路由

#强制路由库和表

## 指定库路由
spring.shardingsphere.sharding.tables.position_master_slave.database-strategy.hint.algorithm-class-name=com.udeam.hint.HintStrategyConfig
## 指定表路由
spring.shardingsphere.sharding.tables.position_master_slave.table-strategy.hint.algorithm-class-name=com.udeam.hint.HintStrategyConfig
spring.shardingsphere.sharding.tables.position_master_slave.actual-data-nodes=test$->{0..1}.position_master_slave$->{0..1}


#   表 雪花算法id
spring.shardingsphere.sharding.tables.position_master_slave.key-generator.column=id
#对应主键类getType返回内容
spring.shardingsphere.sharding.tables.position_master_slave.key-generator.type=SNOWFLAKE
复制代码

这儿准备好了响应的库和表

在这里插入图片描述

强制路由库

  HintManager hintManager = HintManager.getInstance();

        //选择库的路由 主库进行 0在我们自定义的路由算法中 对 两个库(test0,test1) % 2 操作 就是选择第一个库 即主库test0
        hintManager.setDatabaseShardingValue(0L); //  强制路由库

        System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());
复制代码

可以看到test0中的所有表都进行查询
在这里插入图片描述

对某个库中表进行路由

    @org.junit.Test
    public void hintTest() {

        /**
         * 2 对某个库中表进行路由
         */
        HintManager hintManagerTable = HintManager.getInstance();

        //指定库
        hintManagerTable.addDatabaseShardingValue("position_master_slave",0L);
        //选择库中某个表进行路由,这儿设置对主库中 position_master_slave 表查询
        hintManagerTable.addTableShardingValue("position_master_slave",0L);

        System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());

    }
复制代码

在这里插入图片描述

如果不指定则会全部库和表都撸一遍

        HintManager hintManagerTable = HintManager.getInstance();
        System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());
复制代码

在这里插入图片描述

源码分析

待写…

猜你喜欢

转载自juejin.im/post/7231803423577473082