官方文档:https://shardingsphere.apache.org/document/5.1.0/cn/overview/#shardingsphere-sidecartodo
—— ShardingSphere 简介
- 是一套开源的 分布式数据库中间件 的解决方案
- 三个产品:Sharding-JDBC、Sharding-Proxy、Sharding-Sidecar
- 定位为关系型数据库中间件,合理在分布式环境下使用关系型数据库操作
—— 分库分表
背景
- 数据库数据量不可控,随着时间和业务发展,造成表里面的数据越来越多,如果再去对数据库表进行 CRUD 操作时,造成性能上的问题
- 从硬件上:增加 CPU、内存、硬盘(治标不治本)
- 分库分表:为了解决由于数据量过大而造成数据库性能降低的问题
方式
垂直分库分表
- 垂直分表:按照业务相关字段,将一个表拆分成一个或多个表
- 垂直分库:按照业务相关进行拆分,同一业务中所有的表放在一个数据库中
水平分库分表
- 水平分表:可按照表中特征字段(id,时间)进行横向拆分成一个或多个表,表中字段都相同,极大减少单表的数据量
- 水平分库:将相同表中的特征统一放在统一数据库中
应用 & 问题
应用
- 在数据库设计的时候就考虑垂直分库和垂直分表
- 随着数据库数据量增加,不要马上考虑做水平切分,首先考虑缓存处理,读写分离,使用索引等等,如果这些方式不能根本解决问题,再考虑做水平分库和水平分表
分库分表问题
- 跨节点连接查询(需要查询多个节点的数据才得到查询结果,分页、排序)
- 多数据源管理问题
—— Sharding-JDBC
简介
- 轻量级的 Java 框架
- 增强版的 JDBC 驱动
- 不做分库分表,做数据分片和读写分离
- 主要目的是 简化对分库分表之后数据相关操作
Springboot配置实操
pom.xml
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core</artifactId>
<version>${latest.release.version}</version>
</dependency>
水平分表
库名:course_db,表名:course_1,course_2
# 真实数据源名称(别名),多个数据源用逗号区分
spring.shardingsphere.datasource.names=m1
# 配置数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbc-url=jdbc:mysql://localhost:3306/course_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
# 指定course表分布情况,配置表在哪个数据数据库里面,表名都是什么($->{} 是行表达式)
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_$->{1..2}
# 指定course表里面主键生成策略
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.column= cid
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.key-generator-name=SNOWFLAKE
# 指定分片策略:约定cid值偶数添加到course_1表,cid奇数添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
# 开启sql输出日志
spring.shardingsphere.props.sql.show=true
实操注意的问题:创建实体类时,默认一个实体类对应一张表,若要对应两张表,需要在properties文件中添加配置(spring.main.allow-bean-definition-overriding=true
)
水平分库
数据库:m1,m2
表:course_1,course_2
# 真实数据源名称(别名),多个数据源用逗号区分
spring.shardingsphere.datasource.names=m1,m2
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置第一个数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbc-url=jdbc:mysql://localhost:3306/edu_db1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
# 配置第二个数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.jdbc-url=jdbc:mysql://localhost:3306/edu_db2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root
# 指定数据库分布情况,数据库里面表的分布情况($->{} 是行表达式)
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{1..2}.course_$->{1..2}
# 指定数据库分片策略:约定user_id是偶数添加m1,奇数添加m2
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2+1}
# 指定course表里面主键生成策略
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.column= cid
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.key-generator-name=SNOWFLAKE
# 指定表分片策略:约定cid值偶数添加到course_1表,cid奇数添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
# 开启sql输出日志
spring.shardingsphere.props.sql.show=true
垂直拆分
专库专表:user_db.t_user
# 真实数据源名称(别名),多个数据源用逗号区分
spring.shardingsphere.datasource.names=m0
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true
# 配置数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbc-url=jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
# 配置user_db数据库里面t_user专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
# 指定t_user表里面主键生成策略
spring.shardingsphere.rules.sharding.tables.t_user.key-generate-strategy.column=user_id
spring.shardingsphere.rules.sharding.tables.t_user.key-generate-strategy.key-generator-name=SNOWFLAKE
# 指定表分片策略
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
# 开启sql输出日志
spring.shardingsphere.props.sql.show=true
公共表
概念
- 存储固定数据的表,表数据很少发生变化,查询时经常进行关联
- 在每个数据库中创建出相同结构的公共表
# 配置库(m1,m2,m3)的公共表
spring.shardingsphere.sharding.broadcast-tables=t_udict
# 指定t_user表里面主键生成策略
spring.shardingsphere.rules.sharding.tables.t_udict.key-generate-strategy.column=dictid
spring.shardingsphere.rules.sharding.tables.t_udict.key-generate-strategy.key-generator-name=SNOWFLAKE
主从复制&读写分离
概念:当主服务器有写入(insert、update、delete)语句时候,从服务器自动获取;(insert、update、delete)语句操作一台服务器,(select) 操作另一台服务器
原理图:
Sharding-JDBC读写分离
- 根据 SQL 语义分析,将读写操作分别路由至主库和从库
- 提供透明化读写分离,让使用方尽量像使用一个数据库一样使用主从数据库集群
- 不做数据同步,数据同步参考 mysql 主从数据同步服务搭建
- 配置(前提是 MySQL 主从服务搭建完毕)
# 真实数据源名称(别名),多个数据源用逗号区分
spring.shardingsphere.datasource.names=m1,s1
# 配置主数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbc-url=jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
# 配置从数据源具体内容(连接池、驱动、地址、用户名、密码)
spring.shardingsphere.datasource.s1.type=com.alibaba.druid.pool.DruidDataSource
# mysql连接驱动为8版本以上需要加包名“.cj”
spring.shardingsphere.datasource.s1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.s1.jdbc-url=jdbc:mysql://localhost:3307/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.s1.username=root
spring.shardingsphere.datasource.s1.password=root
# 主从库逻辑数据源定义 ds0 为user_db
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m1
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s1
# 配置user_db数据库里面t_user专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.t_user
—— Sharding-Proxy
概述
- 数据库代理端
- 应用程序完全透明,可以直接当做 Mysql 等数据库使用
- 下载安装配置即可使用
- 可配置数据分片、读写分离……
安装配置启动
- 下载地址:https://shardingsphere.apache.org/document/5.1.0/cn/downloads/
- 解压
- 配置(config-master-slave.yaml 读写分离配置文件)
- 进入 conf 目录,修改文件 server.yaml,打开两段内容注释(authentication 和 props)
- 进入 conf 目录,修改 config-sharding.yaml(分库分表配置文件),连接 MySQL
- 复制 MySQL 驱动 jar 包到 lib 目录
- 打开 MySQL 相关配置注释
- 修改所要配置的相关内容(可配置分库分表,配置方法说明基本与 sharing-jdbc 相同)
- 启动(默认端口3307,连接工具可能受版本影响不稳定,可用 cmd
mysql -P3307 -uroot -p
方式连接 ) - sql 语句即可操作