美文网首页
Sharding JDBC-读写分离

Sharding JDBC-读写分离

作者: 叩丁狼教育 | 来源:发表于2019-08-28 11:27 被阅读0次

    本文作者:梁开权,叩丁狼高级讲师。原创文章,转载请注明出处。

    读写分离

    接着上一篇的分表分库我们继续来说读写分离

    案例模型

    让数据库的读和写功能分开,其中master负责所有的写操作以及在特殊情况下负责少量的读操作,slave在任何情况下都负责所有的读操作,不负责任何写操作,同样完成这个操作我们需要至少需要2个连接池,具体选择哪个连接池来操作取决于内部的一个叫路由的组件,该组件具有SQL的识别功能

    注意:该功能需要依靠数据库的主从同步才能实现,具体怎么配置请参考之前的笔记

    建表

    -- 分别在主和从服务器中建立数据库sharding,并且建表employee
    CREATE TABLE `employee` (
      `id` bigint(20) PRIMARY KEY AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    -- ###################################
    CREATE TABLE `employee` (
      `id` bigint(20) PRIMARY KEY AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    application.properties

    # 定义连接池
    sharding.jdbc.datasource.names=master,slave
    
    # 主库连接池
    sharding.jdbc.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.master.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.master.url=jdbc:mysql://masterIp:port/sharing
    sharding.jdbc.datasource.master.username=xxx
    sharding.jdbc.datasource.master.password=xxx
    
    # 从库连接池
    sharding.jdbc.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.slave.url=jdbc:mysql://slaveIp:port/sharing
    sharding.jdbc.datasource.slave.username=xxx
    sharding.jdbc.datasource.slave.password=xxx
    
    # 主从路由连接池名称,叫dataSource为了方便MyBatis注入
    sharding.jdbc.config.masterslave.name=dataSource
    # 管理主库连接池
    sharding.jdbc.config.masterslave.master-data-source-name=master
    # 管理从库连接池
    sharding.jdbc.config.masterslave.slave-data-source-names=slave
    # 从库负载均衡算法类型:round_robin(轮询),random(随机)
    sharding.jdbc.config.masterslave.load-balance-algorithm-type=round_robin
    
    # 打印日志
    sharding.jdbc.config.props.sql.show=true
    

    mapper

    /**
     * 这里写的employee表是数据库中的真实表
     */
    @Mapper
    public interface EmployeeMapper {
        @Select("select * from employee")
        List<Employee> selectAll();
    
        @Insert("insert into employee (name) values (#{name})")
        void inser(Employee entity);
    }
    

    测试

    跟上面的完全一致,直接运行然后看效果即可

    优缺点

    • 增加冗余
    • 增加了机器的处理能力
    • 对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟

    分库分表 + 读写分离

    案例模型

    做数据分片 + 读写分离,最少需要2主2从,然后再结合前面讲过的数据分片

    application.properties

    # 数据分片 + 读写分离
    sharding.jdbc.datasource.names=master0,master0Slave,master1,master1Slave
    
    sharding.jdbc.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.master0.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.master0.url=jdbc:mysql://master0Ip:port/sharing
    sharding.jdbc.datasource.master0.username=xxx
    sharding.jdbc.datasource.master0.password=xxx
    
    sharding.jdbc.datasource.master0Slave.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.master0Slave.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.master0Slave.url=jdbc:mysql://master0Ip:port/sharing
    sharding.jdbc.datasource.master0Slave.username=xxx
    sharding.jdbc.datasource.master0Slave.password=xxx
    
    sharding.jdbc.datasource.master1.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.master1.url=jdbc:mysql://master1Ip:port/sharing
    sharding.jdbc.datasource.master1.username=xxx
    sharding.jdbc.datasource.master1.password=xxx
    
    sharding.jdbc.datasource.master1Slave.type=com.alibaba.druid.pool.DruidDataSource
    sharding.jdbc.datasource.master1Slave.driver-class-name=com.mysql.jdbc.Driver
    sharding.jdbc.datasource.master1Slave.url=jdbc:mysql://master1SlaveIp:port/sharing
    sharding.jdbc.datasource.master1Slave.username=xxx
    sharding.jdbc.datasource.master1Slave.password=xxx
    
    # 分库规则
    sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
    sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=master$->{id % 2}
    
    # 绑定逻辑表
    sharding.jdbc.config.sharding.binding-tables=employee
    # 分表规则
    sharding.jdbc.config.sharding.tables.employee.actual-data-nodes=db$->{0..1}.employee_$->{0..1}
    sharding.jdbc.config.sharding.tables.employee.table-strategy.inline.sharding-column=id
    sharding.jdbc.config.sharding.tables.employee.table-strategy.inline.algorithm-expression=employee_$->{id % 2}
    sharding.jdbc.config.sharding.tables.employee.key-generator-column-name=id
    
    # 管理主从连接池
    sharding.jdbc.config.sharding.master-slave-rules.db0.master-data-source-name=master0
    sharding.jdbc.config.sharding.master-slave-rules.db0.slave-data-source-names=master0slave
    sharding.jdbc.config.sharding.master-slave-rules.db1.master-data-source-name=master1
    sharding.jdbc.config.sharding.master-slave-rules.db1.slave-data-source-names=master1slave
    

    mapper

    /**
     * 这里写的employee表是逻辑表
     */
    @Mapper
    public interface EmployeeMapper {
        @Select("select * from employee")
        List<Employee> selectAll();
    
        @Insert("insert into employee (name) values (#{name})")
        void inser(Employee entity);
    }
    

    测试

    跟上面的完全一致,直接运行然后看效果即可

    ===============================================

    相关文章

      网友评论

          本文标题:Sharding JDBC-读写分离

          本文链接:https://www.haomeiwen.com/subject/vndpectx.html