一、ShardingSphere简介

ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。 ​

ShardingSphere定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。 它与NoSQL和NewSQL是并存而非互斥的关系。NoSQL和NewSQL作为新技术探索的前沿,放眼未来,拥抱变化,是非常值得推荐的。反之,也可以用另一种思路看待问题,放眼未来,关注不变的东西,进而抓住事物本质。 关系型数据库当今依然占有巨大市场,是各个公司核心业务的基石,未来也难于撼动,我们目前阶段更加关注在原有基础上的增量,而非颠覆。 ​

ShardingSphere 4.0已经在2020年4月16日从Apache孵化器毕业,成为Apache顶级项目。  

(1)ShardingSphere-JDBC

定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。 ​ 其特征如下:

  1. 适用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。

  2. 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。

  3. 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。ShardingSphere-JDBC对SQL中数据的解析是基于强类型的。

 (2)ShardingSphere-Proxy

定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前先提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据,对DBA更加友好。

(3)ShardingSphere-Sidecar

定位为Kubernetes的云原生数据库代理,以Sidecar的形式代理所有对数据库的访问。 通过无中心、零侵入的方案提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。 ​ Database Mesh的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来,它更加关注的是交互,是将杂乱无章的应用与数据库之间的交互有效的梳理。使用Database Mesh,访问数据库的应用和数据库终将形成一个巨大的网格体系,应用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。

(4)垂直分片

按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。

(5)水平分片

 水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。效果:每个数据库中表是一样的。 

二、基于ShardingSphere-JDBC访问数据库

 (1)导入依赖

    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <version>4.1.1</version>
    </dependency>

(2)编辑配置文件

spring:
  shardingsphere:
    datasource:
      names: m0,m1,s0,s1
      m0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.8.128:3306/t1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        url: jdbc:mysql://192.168.8.128:3306/t1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
      m1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.8.128:3306/t2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        url: jdbc:mysql://192.168.8.128:3306/t2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
      s0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.8.129:3306/t1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        url: jdbc:mysql://192.168.8.129:3306/t1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
      s1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.8.129:3306/t2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        url: jdbc:mysql://192.168.8.129:3306/t2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root

(3)编辑配置类

@Configuration
@MapperScan(basePackages = "com.bjsxt.mapper",sqlSessionFactoryRef = "sessionFactory")
public class TestConfiguration {
    /**
     * 配置数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则
     * @return
     */
    @Bean(name = "m0")
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.m0")
    public DataSource dataSource0() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "m1")
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.m1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "s0")
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.s0")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "s1")
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.s1")
    public DataSource dataSource3() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource dataSource() throws SQLException {
        // 配置分片规则
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();

        // 配置真实数据源
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        dataSourceMap.put("m0", dataSource0());
        dataSourceMap.put("m1", dataSource1());
        dataSourceMap.put("s0", dataSource2());
        dataSourceMap.put("s1", dataSource3());

        TableRuleConfiguration testTableRuleConfig = new TableRuleConfiguration("tb_user", "ds${0..1}.tb_user");
        // 配置分库分表策略
        testTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "ds${id % 2}"));
        shardingRuleConfig.getTableRuleConfigs().add(testTableRuleConfig);

        // 配置读写分离配置
        MasterSlaveRuleConfiguration ds0 = new MasterSlaveRuleConfiguration("ds0","m0",Arrays.asList("s0"));
        MasterSlaveRuleConfiguration ds1 = new MasterSlaveRuleConfiguration("ds1","m1",Arrays.asList("s1"));
        shardingRuleConfig.setMasterSlaveRuleConfigs(Arrays.asList(ds0, ds1));

        // 获取数据源对象
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sessionFactory(DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        sessionFactory.setConfiguration(configuration);

        return sessionFactory.getObject();
    }

    @Bean
    public DataSourceTransactionManager shardTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

(4)编辑启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class ShardingApp{
	public static void main(String[] args){
		SpringApplication.run(ShardingApp.class, args);
	}
}

三、基于ShardingSphere-Proxy访问数据库

(1)解压

 tar zxf apache-shardingsphere-4.1.1-sharding-proxy-bin.tar.gz

(2)移动到安装目录

mv apache-shardingsphere-4.1.1-sharding-proxy-bin /usr/local/shardingsphere-proxy

(3)进入conf目录

cd /usr/local/shardingsphere-proxy/conf

(4)编辑配置文件: server.yaml

vim server.yaml

authentication:  # ShardingSphere-Proxy验证配置
  users:  # ShardingSphere-Proxy用户配置
    root:  # ShardingSphere-Proxy用户名
      password: root  # ShardingSphere-Proxy用户密码
    sharding:  # ShardingSphere-Proxy用户名
      password: root   # ShardingSphere-Proxy用户密码
      authorizedSchemas: baizhan  # ShardingSphere-Proxy用户授权数据库

props:
  max.connections.size.per.query: 1  # 每个链接最多处理的查询数量
  acceptor.size: 2 #  CPU核心数 * 2。  监听线程
  executor.size: 1 # CPU核心数。  执行线程
  proxy.frontend.flush.threshold: 128  
  proxy.transaction.type: LOCAL
  proxy.opentracing.enabled: false
  proxy.hint.enabled: false
  query.with.cipher.column: true
  sql.show: true  # 显示执行的SQL
  allow.range.query.with.inline.sharding: false

(5)编辑配置文件:config-sharding.yaml

vim config-sharding.yaml 

schemaName: baizhan   # 逻辑数据库名
dataSources:  # 数据源配置
  ds0:  # 数据源名
    url: jdbc:mysql://192.168.199.159:3306/ego0?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 30

shardingRule:  # 分片规则
  tables: # 表格配置
    tb_item_cat:  # 表格名称
      actualDataNodes: ds${0..1}.tb_item_cat  # 数据节点设置,ds{0..1}代表有数据源ds0和ds1,在数据源对应的库中,有表格tb_item_cat
      databaseStrategy:  # 分片规则
        inline:  
          shardingColumn: parent_id # 分片键字段
          algorithmExpression: ds${(parent_id) % 2} # 计算方式 ${parent_id%2} 使用字段parent_id的值,计算结果为具体数据源名,如: parent_id=3,parent_id%2=1,数据库为ds1,访问表格为ds1.tb_item_cat

(6)启动ShardingSphere-Proxy

Sharding-Proxy的默认端口是:3307。如果需要修改端口可以在命令后加端口号

$ShardingSphere-Proxy_HOME/bin/start.sh

(7)关闭ShardingSphere-Proxy

 $ShardingSphere-Proxy_HOME/bin/stop.sh

(8)查看日志

 tail -f $ShardingSphere-Proxy_HOME/logs/stdout.log

(9)服务使用

ShardingSphere-Proxy相当于为MySQL数据库提供了一个代理中间件,默认端口为3307,任意客户端访问ShardingSphere-Proxy所在服务器3307端口服务即可实现访问操作。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐