概述
今天开始整理一下分库分表的笔记,以供后续复习。为什么要分库分表就不在赘述。在以前的公司项目的多数据源分库分表都是自研,利用spring的IOC和AOP实现多数据源的自由切换,完成分库分表、读写分离。之所以自研也不是因为重复造轮子,只是想能贴合自己公司项目的业务以及从技术角度满足自己的实际需求,达到熟练可配置的效果。今天和以后的文章要说的并不是我们自研的产品,自研即使说了也不一定适用所有公司,而且也不可能通过看这几篇文章就能够完全实现一个自研的产品,要说的是通过比较成熟和开源的分库分表产品ShardingSphere。
ShardingSphrer是当当网开源的产品,后来免费送给aphach组织进行孵化,是目前比较流行的客户端进行分库分表的产品,【mycat也是一款分库分表的产品,但是是基于服务端的】。现更名为Apache ShardingSphere,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 它们均提供标准化的数据水平扩展、分布式事务和分布式治理等功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。
更多介绍请参看官网http://shardingsphere.apache.org/index_zh.html
通过以上简单的介绍可以知道sharding sphere有很多款产品,我们要介绍的是其中的一款sharding-jdbc在项目中的如何使用,当然具体使用和配置方式官网也有详细的介绍,可进行对比参考https://shardingsphere.apache.org/document/4.1.1/en/overview/
场景
首先分析一下分库分表的数据场景:
- 读写分离
- 分库不分表
- 分库不分表,读写分离
- 分表不分库
- 分表不分库,读写分离
- 分库分表
- 分库分表,读写分离
- 广播表
- 广播表,读写分离
- 专库专表
- 专库专表读写分离
因为读写分离其实是在我们实际使用的过程中比较基础的操作,所以我们在每个数据场景都增加一个读写分离的场景配置。
读写分离
- 前情说明:在练习的过程中我们可以只用安装一个数据库实例,我们应用中配置的主从数据库信息都可以是同一个数据库,关于怎么区分读写的时候是使用的那个数据库配置,在idea控制台打印的输出信息中可以进行区分,后面会进行具体的截图说明。
- 环境说明:Spring boot:2.1.11.RELEASE,sharing-jdeb:4.1.1
- 创建项目
pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.22</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency></dependencies>
application.properties
- 一主两从
# mybatis plus配置 mybatis-plus.mapper-locations=classpath:/mapper/**/*.xml mybatis-plus.type-aliases-package=com.spring.demo.xxx.entity mybatis-plus.global-config.db-config.id-type=auto mybatis-plus.configuration.map-underscore-to-camel-case=true mybatis-plus.configuration.cache-enabled=false #返回map时,true:当查询数据为空时字段返回为null;false:不加这个查询数据为空时,字段将被隐藏 mybatis-plus.configuration.call-setters-on-nulls=false mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl # sharding jdbc 读写分离 spring.shardingsphere.datasource.names=master,slave0,slave1 # 主数据连接信息 spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.master.url=jdbc:mysql://yourdburl:3306/yourdbname?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull spring.shardingsphere.datasource.master.username=yourdbusername spring.shardingsphere.datasource.master.password=yuordbpassword # 第一个从数据连接信息 spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.slave0.url=jdbc:mysql://yourdburl:3306/yourdbname?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull spring.shardingsphere.datasource.slave0.username=yourdbusername spring.shardingsphere.datasource.slave0.password=yourdbpassword # 第二个从数据库连接信息 spring.shardingsphere.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.slave1.url=jdbc:mysql://yourdburl:3306/yourdbname?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull spring.shardingsphere.datasource.slave1.username=yourdbusername spring.shardingsphere.datasource.slave1.password=yourdbpassword # 指定主从数据库配置 # 默认数据库,可配置可不配置 spring.shardingsphere.sharding.default-data-source-name=master # 主从复制中的master数据库节点 spring.shardingsphere.masterslave.master-data-source-name=master # 主从复制中的slave数据库节点,多个用逗号分隔 spring.shardingsphere.masterslave.slave-data-source-names=slave0,slave1 # 读请求的时候,多个从节点的负载均衡方式,这里是轮询的方式 spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin # 指定主从的名称,可配置可不配置 spring.shardingsphere.masterslave.name=ms # 打印sharding的数据库信息,可以看出每次执行的sql语句是选用的哪个数据库 spring.shardingsphere.props.sql.show=true
启动类
- 启动类的@SpringBootApplication需要过滤掉默认的数据配置,这样才能使用sharding-jdbc的代理数据源
exclude= {DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class}) (
- 省略掉controller、service、dao、mapper的编写,编写方法和单数据库的编写方式一样
启动项目
- 配置的三个数据库进行了初始化
- 两次查询都通过sharding打印的sql语句可以看出是访问不同的slave数据库
- 保存的时候选择的是master数据库
以上是读写分离的从0到1的配置过程。本实例省略了搭建数据库的部分,若有不清楚的可以通过baidu进行搜索相关文章即可。其中选用的连接池是druid,关于druid的生产配置后续在通过其他文章进行介绍,这片主要专注于sharding-jdbc。
参考资料
后续用新的篇章写其他的场景配置,待续......