zoukankan      html  css  js  c++  java
  • sharding-jdbc从入门到熟练使用

    sharding-jdbc属于ShardingSphere的一员,定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

    • 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
    • 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
    • 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。

    sharding-jdbc数据分片工作原理

    核心由 SQL解析 => 执行器优化=> SQL路由 => SQL改写 => SQL执行 => 结果归并 的流程组成。
    image.png

    sql解析

    分为词法解析和语法解析。 先通过词法解析器将SQL拆分为一个个不可再分的单词。再使用语
    法解析器对SQL进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、
    分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。

    执行器优化

    合并和优化分片条件,如OR等

    sql路由

    根据解析上下文匹配用户配置的分片策略,并生成路由路径。目前支持分片路由和广播路由。

    sql改写

    将SQL改写为在真实数据库中可以正确执行的语句。SQL改写分为正确性改写和优化改写

    sql执行

    通过多线程执行器异步执行

    结果归并

    将多个执行结果集归并以便于通过统一的JDBC接口输出。结果归并包括流式归并、内存归并和
    使用装饰者模式的追加归并这几种方式

    sharding-jdbc读写分离

    springboot2.x + mybatis + sharding-jdbc

    手动配置方式

    maven依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shardingsphere</groupId>
                <artifactId>sharding-jdbc-core</artifactId>
                <version>${sharding-sphere.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot-starter.version}</version>
            </dependency>
    

    配置数据源

    @Configuration
    public class DataSourceConfig {
    
        @Value("${spring.datasource.minIdle:10}")
        private int minIdle;
        @Value("${spring.datasource.maxActive:50}")
        private int maxActive;
        @Value("${spring.datasource.maxLifetime}")
        private int maxLifetime;
        @Value("${spring.datasource.idleTimeout}")
        private int idleTimeout;
    
        @Value("${spring.datasource0.url}")
        private String url0;
        @Value("${spring.datasource0.username}")
        private String username0;
        @Value("${spring.datasource0.password}")
        private String password0;
        @Value("${spring.datasource0.driverClassName}")
        private String driverClassName0;
    
        @Value("${spring.datasource1.url}")
        private String url1;
        @Value("${spring.datasource1.username}")
        private String username1;
        @Value("${spring.datasource1.password}")
        private String password1;
        @Value("${spring.datasource1.driverClassName}")
        private String driverClassName1;
    
        @Autowired
        private CustomerDataSourceFactory customerDataSourceFactory;
    
        @Bean("dataSource0")
        public DataSource dataSource0() {
            return initDataSource(url0,username0,password0,driverClassName0);
        }
    
        @Bean("dataSource1")
        public DataSource dataSource1() {
            return initDataSource(url1,username1,password1,driverClassName1);
        }
    
        @Bean(name = "shardingDataSource")
        public DataSource shardingDataSource(@Qualifier("dataSource0") DataSource dataSource0,
                                             @Qualifier("dataSource1") DataSource dataSource1) throws SQLException {
            Map<String,DataSource> map= new HashMap<>();
            map.put("ds_master",dataSource0);
            map.put("ds_slave",dataSource1);
            return customerDataSourceFactory.createDataSource(map);
        }
    
    
        private DataSource initDataSource(String url,String username,String password, String driverClassName) {
            HikariDataSource datasource = new HikariDataSource();
            datasource.setJdbcUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);
            datasource.setMaximumPoolSize(maxActive);
            datasource.setMinimumIdle(minIdle);
            datasource.setMaxLifetime(maxLifetime);
            datasource.setIdleTimeout(idleTimeout);
            datasource.setConnectionTestQuery("select 1");
            return datasource;
        }
    }
    
    @Component
    public class CustomerDataSourceFactory {
    
    
    
        public DataSource createDataSource(Map<String,DataSource> map ) throws SQLException {
    
            MasterSlaveRuleConfiguration masterSlaveRuleConfiguration = new MasterSlaveRuleConfiguration("ds_master_slave","ds_master", Lists.newArrayList("ds_slave"));
    
            Properties properties = new Properties();
            properties.setProperty(ShardingPropertiesConstant.SQL_SHOW.getKey(),
                    String.valueOf(true));
            properties.setProperty(ShardingPropertiesConstant.MAX_CONNECTIONS_SIZE_PER_QUERY.getKey(),
                    String.valueOf(200));
    
            return MasterSlaveDataSourceFactory.createDataSource(map, masterSlaveRuleConfiguration,
                    properties);
        }
    }
    

    mybatis配置

    @Configuration
    @MapperScan(basePackages = "com.example.dao" ,sqlSessionFactoryRef="shardingSqlSessionFactory" )
    @EnableTransactionManagement
    public class ShardingMyBatisConfig {
    
    
        @Autowired
        @Qualifier("shardingDataSource")
        private DataSource dataSource;
    
        @Bean("shardingSqlSessionFactory")
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setTypeAliasesPackage("com.example.entity");
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            bean.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
            return bean.getObject();
        }
    
        @Bean("platformTransactionManager")
        public PlatformTransactionManager platformTransactionManager(){
            return new DataSourceTransactionManager(dataSource);
        }
    
    }
    

    springboot-starter集成

    maven依赖

            <dependency>
                <groupId>org.apache.shardingsphere</groupId>
                <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
                <version>4.0.0-RC1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
           <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot-starter.version}</version>
            </dependency>
    

    application.yml配置

    server:
      port: 8085
    spring:
      shardingsphere:
        datasource:
          names: ds0,ds1
          ds0:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3339/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
          ds1:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3340/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
        masterslave:
          load-balance-algorithm-type: round_robin
          name: ms
          master-data-source-name: ds0
          slave-data-source-names: ds1
        props:
          sql.show: true
    mybatis:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.example.entity
    

    启动类上加上mapper扫描路径及开启事务

    @SpringBootApplication
    @EnableTransactionManagement
    @MapperScan("com.example.dao")
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
    
        }
    }
    

    在例子中我们使用了mybatis-starter,所以无需配SqlSessionFactory等,如果手动整合则直接通过注入的方式即可使用DataSource,或者将DataSource配置在JPA、Hibernate或MyBatis中使用。

    @Resource
    private DataSource dataSource;
    

    读写分离配置项说明

    masterSlaveRule:
      name: #读写分离数据源名称,自定义
      masterDataSourceName: #主库数据源名称,数据源处定义的数据源名
      slaveDataSourceNames: #从库数据源名称列表,数据源处定义的数据源名
      - <data_source_name1>
      - <data_source_name2>
      - <data_source_name_x>
      loadBalanceAlgorithmClassName: #从库负载均衡算法类名称。该类需实现MasterSlaveLoadBalanceAlgorithm接口且提供无参数构造器
      loadBalanceAlgorithmType: #从库负载均衡算法类型,可选值:ROUND_ROBIN,RANDOM。`loadBalanceAlgorithmClassName`存在则忽略该配置
    

    sharding-jdbc 可配置项参数说明

    props:
      sql.show: #是否开启SQL显示,默认值: false
      acceptor.size: # accept连接的线程数量,默认为cpu核数2倍
      executor.size: #工作线程数量最大,默认值: 无限制
      max.connections.size.per.query: # 每个查询可以打开的最大连接数量,默认为1
      check.table.metadata.enabled: #是否在启动时检查分表元数据一致性,默认值: false
      proxy.frontend.flush.threshold: # proxy的服务时候,对于单个大查询,每多少个网络包返回一次
      proxy.transaction.type: # 默认LOCAL,proxy的事务模型 允许LOCAL,XA,BASE三个值,LOCAL无分布式事务,XA则是采用atomikos实现的分布式事务 BASE目前尚未实现
      proxy.opentracing.enabled: # 是否启用opentracing
      proxy.backend.use.nio: # 是否采用netty的NIO机制连接后端数据库,默认False ,使用epoll机制
      proxy.backend.max.connections: # 使用NIO而非epoll的话,proxy后台连接每个netty客户端允许的最大连接数量(注意不是数据库连接限制) 默认为8
      proxy.backend.connection.timeout.seconds: #使用nio而非epoll的话,proxy后台连接的超时时间,默认60s
    

    sharind-jdbc分库分表

    分片维度配置

    对于分片策略存有数据源分片策略和表分片策略两种维度。两种策略的API完全相同。

    • 数据源分片策略
      对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。
    • 表分片策略
      对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。

    分片策略

    包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供5种分片策略。

    • 标准分片策略
      对应StandardShardingStrategy。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置
      RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
    • 复合分片策略
      对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
    • 行表达式分片策略
      对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0 到 t_user_7 。
    • Hint分片策略
      对应HintShardingStrategy。通过Hint而非SQL解析的方式分片的策略。
    • 不分片策略
      对应NoneShardingStrategy。不分片的策略。

    行表达式语法说明

    行表达式的使用非常直观,只需要在配置中使用 ${ expression } 或 $->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。行表达式的内容使用的是Groovy的语法,Groovy能够支持的所有操作,行表达式均能够支持。例如:

    • ${begin..end} 表示范围区间
    • ${[unit1, unit2, unit_x]} 表示枚举值
    • 行表达式中如果出现连续多个 ${ expression } 或 $->{ expression } 表达式,整个表达式最终的结果将会根据每个子表达式的结果进行笛卡尔组合。

    分布式主键

    ShardingSphere不仅提供了内置的分布式主键生成器,例如UUID、SNOWFLAKE、LEAF(进行中),还抽离出分布式主键生成器的接口,方便用户自行实现自定义的自增主键生成器。

    配置项说明

    defaultKeyGenerator: #默认的主键生成算法 如果没有设置,默认为SNOWFLAKE算法
      column: # 自增键对应的列名称
      type: #自增键的类型,主要用于调用内置的主键生成算法有三个可用值:SNOWFLAKE(时间戳+worker id+自增id),UUID(java.util.UUID类生成的随机UUID),LEAF,其中Snowflake算法与UUID算法已经实现,LEAF目前尚未实现
      props:
            # 定制算法需要设置的参数,比如SNOWFLAKE算法的worker.id与max.tolerate.time.difference.milliseconds
    

    自定义主键生成策略

    第一步:添加策略类

    public class CustomIdGenerator implements ShardingKeyGenerator {
        @Override
        public Comparable<?> generateKey() {
            return UUID.randomUUID().toString().replace("-","");
        }
    
        @Override
        public String getType() {
            return "CUSTOM";
        }
    
        @Override
        public Properties getProperties() {
            return null;
        }
    
        @Override
        public void setProperties(Properties properties) {
    
        }
    }
    

    第二步:配置spi
    image.png
    第三步:通过手动配置或者在yml文件中配置使用

    绑定表

    指分片规则一致的主表和子表。例如: t_order 表和 t_order_item 表,均按照 order_id 分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
    配置示例

    bindingTables: # 绑定表,也就是实际上哪些配置的sharidng表规则需要实际生效的列表,配置为yaml列表,并且允许单个条目中以逗号切割,所配置表必须已经配置为逻辑表
    - sharding_t1
    - sharding_t2,sharding_t3
    

    广播表

    指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表
    配置实例

    broadcastTables: # 广播表 这里配置的表列表,对于发生的所有数据变更,都会不经sharidng处理,而是直接发送到所有数据节点,注意此处为列表,每个项目为一个表名称
      - broad_1
      - broad_2
    

    手动配置方式

    数据源配置

    @Configuration
    public class DataSourceConfig {
    
        @Value("${spring.datasource.minIdle:10}")
        private int minIdle;
        @Value("${spring.datasource.maxActive:50}")
        private int maxActive;
        @Value("${spring.datasource.maxLifetime}")
        private int maxLifetime;
        @Value("${spring.datasource.idleTimeout}")
        private int idleTimeout;
    
        @Value("${spring.datasource0.url}")
        private String url0;
        @Value("${spring.datasource0.username}")
        private String username0;
        @Value("${spring.datasource0.password}")
        private String password0;
        @Value("${spring.datasource0.driverClassName}")
        private String driverClassName0;
    
        @Value("${spring.datasource1.url}")
        private String url1;
        @Value("${spring.datasource1.username}")
        private String username1;
        @Value("${spring.datasource1.password}")
        private String password1;
        @Value("${spring.datasource1.driverClassName}")
        private String driverClassName1;
    
        @Autowired
        private CustomerDataSourceFactory customerDataSourceFactory;
    
        @Bean("dataSource0")
        public DataSource dataSource0() {
            return initDataSource(url0,username0,password0,driverClassName0);
        }
    
        @Bean("dataSource1")
        public DataSource dataSource1() {
            return initDataSource(url1,username1,password1,driverClassName1);
        }
    
        @Bean(name = "shardingDataSource")
        public DataSource shardingDataSource(@Qualifier("dataSource0") DataSource dataSource0,
                                             @Qualifier("dataSource1") DataSource dataSource1) throws SQLException {
            List<DataSource> dataSourceList = new ArrayList<>();
            dataSourceList.add(dataSource0);
            dataSourceList.add(dataSource1);
            return customerDataSourceFactory.createDataSource(dataSourceList);
        }
    
    
        private DataSource initDataSource(String url,String username,String password, String driverClassName) {
            HikariDataSource datasource = new HikariDataSource();
            datasource.setJdbcUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);
            datasource.setMaximumPoolSize(maxActive);
            datasource.setMinimumIdle(minIdle);
            datasource.setMaxLifetime(maxLifetime);
            datasource.setIdleTimeout(idleTimeout);
            datasource.setConnectionTestQuery("select 1");
            return datasource;
        }
    }
    

    分库分表规则配置

    @Component
    public class CustomerDataSourceFactory {
    
    
    
        public DataSource createDataSource(List<DataSource> dataSourceList) throws SQLException {
    
            ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
    
            /**user表分表配置**/
            TableRuleConfiguration userTableRuleConfig = new TableRuleConfiguration("t_user","db0.t_user_0,db0.t_user_1");
            userTableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("CUSTOM","user_id"));
            userTableRuleConfig.setDatabaseShardingStrategyConfig(new NoneShardingStrategyConfiguration());
            userTableRuleConfig.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id",new UserTableAlgoritm()));
            shardingRuleConfig.getTableRuleConfigs().add(userTableRuleConfig);
    
    
    
            /**order表分库分表配置**/
            TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration(
                    "t_order", "db0.t_order_2020_0,db0.t_order_2020_1,db0.t_order_2019_0,db0.t_order_2019_1,db1.t_order_2019_0,db1.t_order_2019_1,db1.t_order_2020_0,db1.t_order_2020_1");
            orderTableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE","order_id"));
            // 数据库分片配置
            StandardShardingStrategyConfiguration dataSourceStrategyConfiguration = new StandardShardingStrategyConfiguration(
                    "addr", new OrderDataSourcePreciseShardingAlgorithm());
            orderTableRuleConfig.setDatabaseShardingStrategyConfig(dataSourceStrategyConfiguration);
            orderTableRuleConfig.setTableShardingStrategyConfig(new ComplexShardingStrategyConfiguration(
                    "order_year,user_id", new OrderTableComplexKeyAlgorithm()));
            shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);
    
    
    
            Properties properties = new Properties();
            properties.setProperty(ShardingPropertiesConstant.SQL_SHOW.getKey(),
                    String.valueOf(true));
            properties.setProperty(ShardingPropertiesConstant.MAX_CONNECTIONS_SIZE_PER_QUERY.getKey(),
                    String.valueOf(200));
    
            Map<String, DataSource> dataSourceMap = new HashMap<>();
            for (int i = 0; i < dataSourceList.size(); i++) {
                dataSourceMap.put("db" + String.valueOf(i), dataSourceList.get(i));
            }
            return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig,
                    properties);
        }
    }
    

    这里分别对user和order进行可分库分表,其中user单分片键只分表不分库,order表分库采用复合分片策略,分表采用单分片键。
    对应的分库分表策略如下

    @Slf4j
    public class UserTableAlgoritm  implements PreciseShardingAlgorithm<String> {
        @Override
        public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
            log.info("availableTargetNames={},shardingValue={}", ObjectToStrUtils.JSONString(availableTargetNames),ObjectToStrUtils.JSONString(shardingValue));
            String value = shardingValue.getValue();
            List<String> list = Lists.newArrayList(availableTargetNames);
            return list.get(value.hashCode()%list.size());
        }
    }
    
    @Slf4j
    public class OrderTableComplexKeyAlgorithm implements ComplexKeysShardingAlgorithm<String> {
        public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<String> shardingValue) {
            List<String> list = new ArrayList<>();
            log.info("availableTargetNames={},shardingValue={}",availableTargetNames,shardingValue);
            Map<String, Collection<String>> columnNameAndShardingValuesMap = shardingValue.getColumnNameAndShardingValuesMap();
            if(columnNameAndShardingValuesMap.containsKey("order_year")){
                Collection<String> orderYear = columnNameAndShardingValuesMap.get("order_year");
                String address = orderYear.iterator().next();
                list = availableTargetNames.stream().filter(t -> t.contains(address)).collect(Collectors.toList());
            }
            if(columnNameAndShardingValuesMap.containsKey("user_id")){
                Collection<String> userId = columnNameAndShardingValuesMap.get("user_id");
                String stringUserId = userId.iterator().next();
                String index = String.valueOf(stringUserId.hashCode()%list.size());
                list = list.stream().filter(t -> t.endsWith(index)).collect(Collectors.toList());
            }
            log.info("actual table :{}",list);
            return list;
        }
    }
    
    @Slf4j
    public class OrderDataSourcePreciseShardingAlgorithm  implements PreciseShardingAlgorithm<String> {
    
        public String doSharding(Collection<String> availableDataSourceNames, PreciseShardingValue<String> shardingValue) {
            log.info("availableDataSourceNames={},shardingValue={}",availableDataSourceNames,shardingValue);
            String value = shardingValue.getValue();
            Iterator<String> iterator = availableDataSourceNames.iterator();
            List<String> list = Lists.newArrayList(availableDataSourceNames);
            int index = value.hashCode()%list.size();
            return list.get(index);
        }
    }
    

    springboot-starter配置读写分离+分库分表

    spring:
      shardingsphere:
        datasource:
          names: db0_master,db0_slave,db1_master,db1_slave
          db0_master:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3339/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
          db0_slave:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3341/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
          db1_master:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3340/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
          db1_slave:
            type: com.zaxxer.hikari.HikariDataSource
            jdbcUrl: jdbc:mysql://localhost:3342/sharding01?useSSL=false&useUnicode=yes&characterEncoding=utf8
            username: root
            password: 123456
            driverClassName: com.mysql.cj.jdbc.Driver
        sharding:
          tables:
            t_order:
              actual-data-nodes: db0.t_order_2020_0,db0.t_order_2020_1,db0.t_order_2019_0,db0.t_order_2019_1,db1.t_order_2019_0,db1.t_order_2019_1,db1.t_order_2020_0,db1.t_order_2020_1
              database-strategy:
                standard:
                  shardingColumn: addr
                  preciseAlgorithmClassName: com.example.config.OrderDataSourcePreciseShardingAlgorithm
              table-strategy:
                complex:
                  shardingColumns: order_year,user_id
                  algorithmClassName: com.example.config.OrderTableComplexKeyAlgorithm
              keyGenerator:
                column: order_id
          master-slave-rules:
            db0:
              master-data-source-name: db0_master
              slave-data-source-names: db0_slave
              loadBalanceAlgorithmType: ROUND_ROBIN
            db1:
              master-data-source-name: db1_master
              slave-data-source-names: db1_slave
              loadBalanceAlgorithmType: ROUND_ROBIN
          props:
            sql.show: true
          default-key-generator:
            type: SNOWFLAKE
            props:
              work.id: 100
    

    需要注意的是分片时的数据源是读写分离中定义的集群名。

    参考文档

    官方文档:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/overview/
    源码地址:https://github.com/apache/shardingsphere/tree/4.1.0/examples/sharding-jdbc-example/sharding-example

  • 相关阅读:
    apache 多站点设置
    关键词使用什么分隔符好
    ASP.NET MVC ModelState与数据验证【转】
    Sealed,new,virtual,abstract与override的区别
    ASP.NET MVC4中调用WEB API的四个方法
    wcf 基础连接已经关闭: 连接被意外关闭
    解决MySQL不允许从远程访问的方法有哪些?
    PHP魔法函数 自动转义 magic_quotes_gpc和magic_quotes_runtim
    Html.RenderPartial与Html.RenderAction 用法
    MVC中的扩展点 ActionResult
  • 原文地址:https://www.cnblogs.com/hhhshct/p/13862960.html
Copyright © 2011-2022 走看看