zoukankan      html  css  js  c++  java
  • ShardingSphere入门实战(2)-Sharding-Proxy使用

    Sharding-Proxy定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前先提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端。本文主要介绍Sharding-Proxy的基本使用,文中使用到的软件版本:sharding-proxy 4.1.1、MySQL 5.7.26、Java 1.8.0_191。

    1、Sharding-Proxy和Sharding-JDBC的区别

    2、Sharding-Proxy安装

    2.1、下载并解压

    https://shardingsphere.apache.org/document/current/cn/downloads/

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

    2.2、修改配置文件

    conf/server.yaml

    authentication:
      users:
        root:
          password: root
        sharding:
          password: sharding 
          authorizedSchemas: sharding_db,master_slave_db
    
    props:
      max.connections.size.per.query: 1
      acceptor.size: 16  # The default value is available processors count * 2.
      executor.size: 16  # Infinite by default.
      proxy.frontend.flush.threshold: 128  # The default value is 128.
        # LOCAL: Proxy will run with LOCAL transaction.
        # XA: Proxy will run with XA transaction.
        # BASE: Proxy will run with B.A.S.E transaction.
      proxy.transaction.type: LOCAL
      proxy.opentracing.enabled: false
      proxy.hint.enabled: false
      query.with.cipher.column: true
      sql.show: true
      allow.range.query.with.inline.sharding: false

    conf/config-sharding.yaml

    schemaName: sharding_db
    
    dataSources:
      ds0:
        url: jdbc:mysql://10.49.196.10:3306/itest
        username: admin
        password: Root_123!
        connectionTimeoutMilliseconds: 30000
        idleTimeoutMilliseconds: 60000
        maxLifetimeMilliseconds: 1800000
        maxPoolSize: 50
      ds1:
        url: jdbc:mysql://10.49.196.20:3306/itest
        username: admin
        password: Root_123!
        connectionTimeoutMilliseconds: 30000
        idleTimeoutMilliseconds: 60000
        maxLifetimeMilliseconds: 1800000
        maxPoolSize: 50
    
    shardingRule:
      tables:
        t_user: #逻辑表名,在一个库里分表:ds0.t_user_0,ds0.t_user_1
          actualDataNodes: ds0.t_user_$->{0..1}
          tableStrategy: #表分片策略
            inline: #行表达式分片策略
              shardingColumn: user_id #分片的字段
              algorithmExpression: t_user_$->{user_id % 2} #分片的算法
        t_dept: #分库,两个库里建系统的表:ds0.t_dept,ds1.t_dept
          actualDataNodes: ds$->{0..1}.t_dept
          databaseStrategy: #数据库分片策略
            inline: #行表达式分片策略
              shardingColumn: dept_id #分片的字段
              algorithmExpression: ds$->{dept_id % 2} #分片的算法

    conf/config-master_slave.yaml

    schemaName: master_slave_db
    
    dataSources:
      master:
        url: jdbc:mysql://10.49.196.10:3306/itest
        username: admin
        password: Root_123!
      slave0:
        url: jdbc:mysql://10.49.196.20:3306/itest
        username: admin
        password: Root_123!
    
    masterSlaveRule:
      name: ds_ms
      masterDataSourceName: master
      slaveDataSourceNames: 
        - slave0

    2.3、启动

    bin/start.sh [port]   #不加端口,默认3307

    3、使用JDBC访问Sharding-Proxy

    package com.inspur.demo.shardingsphere;
    
    import com.inspur.demo.shardingsphere.util.JdbcUtil;
    import org.apache.shardingsphere.api.hint.HintManager;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.annotation.Resource;
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    public class ShardingProxyCase {
        private static Logger logger = LoggerFactory.getLogger(ShardingProxyCase.class);
    
    
        /**
         * 数据分片
         * t_user在同一个库里分表(t_user_0,t_user_1)
         * t_dept分库
         */
        @Test
        public void fragmentation() {
            Connection con = null;
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
                con = DriverManager.getConnection("jdbc:mysql://10.49.196.10:3307/sharding_db", "sharding", "sharding");
                con.setAutoCommit(false);
                Statement st = con.createStatement();
    
                //插入ds0.t_user_0表
                st.executeUpdate("insert into t_user(user_id,user_name,age) values(110,'赵云2', 30)");
                //插入ds0.t_user_1表
                st.executeUpdate("insert into t_user(user_id,user_name,age) values(111,'张飞2', 31)");
    
                //插入ds0.t_dept表
                st.executeUpdate("insert into t_dept(dept_id,dept_name) values(110,'dept10-2')");
                //插入ds1.t_dept表
                st.executeUpdate("insert into t_dept(dept_id,dept_name) values(111,'dept11-2')");
    
                ResultSet rs = st.executeQuery("select user_id,user_name from t_user where user_id in(110,111)");
                while (rs.next()) {
                    logger.info("user_id={},user_name={}", rs.getString("user_id"), rs.getString("user_name"));
                }
    
                rs = st.executeQuery("select dept_id,dept_name from t_dept where dept_id in(110,111)");
                while (rs.next()) {
                    logger.info("dept_id={},dept_name={}", rs.getString("dept_id"), rs.getString("dept_name"));
                }
    
                con.commit();
            } catch (Exception e) {
                JdbcUtil.rollback(con);
                e.printStackTrace();
            } finally {
                JdbcUtil.close(con);
            }
        }
    
    
        /**
         * 读写分离,主库写,从库读
         * 同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性
         */
        @Test
        public void readWrite() {
            Connection con = null;
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
                con = DriverManager.getConnection("jdbc:mysql://10.49.196.10:3307/master_slave_db", "sharding", "sharding");
                Statement st = con.createStatement();
    
                //从slave0读数据
                ResultSet rs = st.executeQuery("select * from t_student");
                while (rs.next()) {
                    System.out.println(rs.getString("id") + "|" + rs.getString("name"));
                }
    
                //写入master
                st.executeUpdate("insert into t_student(id,name) values(600,'测试')");
    
                //这边应该从master读数据,但是还是从slave0读取数据,可能是ShardingProxy的bug
                rs = st.executeQuery("select * from t_student");
                while (rs.next()) {
                    System.out.println(rs.getString(1) + "|" + rs.getString(2));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JdbcUtil.close(con);
            }
        }
    
    }

    数据分配和读写分离访问了不同schema;在读写分离的例子中第二次查询应从master读数据,但是还是从slave0读取数据,不知是我配置错了还是ShardingProxy的bug,知道的同学告诉下哈。

  • 相关阅读:
    MINA的session.close
    Maven构建灵活配置文件
    函数的凹凸性
    幂函数习题
    2017全国卷1文科第9题高考真题的解法
    指数函数习题
    三角形的四心的向量表示
    进退中体会数学运算和数学策略
    函数f(x+1)和f(x-1)的奇偶性
    函数的奇偶性周期性习题
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/13415319.html
Copyright © 2011-2022 走看看