学习思路:
- 引入分库分表原因
- 分库分表方式:水平、垂直
- sharding分库分表:基础概念、分表策略、带来的问题
- sharding的使用:水平分库分表+读写分离配置
- 读写分离的前提:mysql主从复制
- sharding本地事务
- 数据量过大时的迁移扩容 ...
放到最前面:
1. 引入分库分表原因
主要看两点:IO和CPU瓶颈;
服务器的IO操作可以涉及硬盘、网络、内存等设备和资源
分库:单数据库实例支持的连接数有限。(网络IO)
分表:单表数量量过大,导致查询和存储效率变低。(磁盘IO+CPU)
一些流水表、用户表后续量级可能较大时,才进行分库分表。
2. 两种分库分表方式:水平、垂直
生产上,垂直拆分已经应用到各个业务域了;
对于单个业务域,对用户相关的记录,一般十库百表、四库1024表等进行水平拆分。
垂直拆分:将不同业务的数据拆分到不同的表、库; (分为用户、订单、价格业务等,各个业务服务化)
水平拆分:以字段(大多uid)按照一定策略,将数据分到不同的表、库;(单个业务内,进行的分库分表)
3. sharding分库分表
Ref:Sharding-JDBC 分库分表,真香!(详细介绍shardingJDBC的基础概念+引入的问题
)
3.1 shardingJDBC介绍
什么是 ShardingSphere (= jdbc + proxy)
3.2 基础概念
3.3 分库分表带来的问题
- 分布式事务问题; (7种分布式事务方案)(TCC:Try Confirm Cancel,侵入业务代码的两阶段提交)
- 跨节点关联join问题(尽量避免;字段冗余;全局表)
- 跨节点分页、排序、函数问题;(尽量避免:底层实现需要将各个节点数据汇总后重新排序获得)
- 全局主键避重问题(uuid Snowflake等)
3.4 ShardingJDBC的整体架构图
4. shardingJDBC使用配置(水平分库分表、读写分离)
sharding-jdbc 生产配置实现!!!(水平分库分片+读写分离配置
)
4.1 水平分库分表配置
# 配置不同的数据源
spring.shardingsphere.datasource.names=ds1,ds2
#配置ds1数据源的基本信息
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://192.168.85.111:3306/sharding_sphere_1?serverTimezone=UTC
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
#配置ds2数据源的基本信息
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://192.168.85.112:3306/sharding_sphere_2?serverTimezone=UTC
spring.shardingsphere.datasource.ds2.username=root
spring.shardingsphere.datasource.ds2.password=123456
#指定数据库的分布情况
spring.shardingsphere.sharding.tables.orders.actual-data-nodes=ds$->{1..2}.orders_$->{1..2}
#指定orders表的主键生成策略
spring.shardingsphere.sharding.tables.orders.key-generator.column=id
spring.shardingsphere.sharding.tables.orders.key-generator.type=SNOWFLAKE
#指定表分片策略,根据id的奇偶性来添加到不同的表中
spring.shardingsphere.sharding.tables.orders.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.orders.table-strategy.inline.algorithm-expression=orders_$->{id%2+1}
#指定库分片策略,根据customer_id的奇偶性来添加到不同的库中
spring.shardingsphere.sharding.tables.orders.database-strategy.inline.sharding-column=customer_id
spring.shardingsphere.sharding.tables.orders.database-strategy.inline.algorithm-expression=ds$->{customer_id%2+1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
4.2 读写分离配置
ShardingJDBC读写分离时,使用限制!!!
#配置数据源
spring.shardingsphere.datasource.names=ds1,ds2
#配置第一个数据源
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://192.168.85.111:3306/shardingsphere?serverTimezone=UTC
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
#配置第二个数据源
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://192.168.85.112:3306/shardingsphere?serverTimezone=UTC
spring.shardingsphere.datasource.ds2.username=root
spring.shardingsphere.datasource.ds2.password=123456
#主库从库逻辑定义
spring.shardingsphere.masterslave.name=ms
spring.shardingsphere.masterslave.master-data-source-name=ds1
spring.shardingsphere.masterslave.slave-data-source-names=ds2
#显示执行的sql
spring.shardingsphere.props.sql.show=true
5. Mysql主从复制读写分离
Ref:
看一遍就了解:聊聊MySQL主从 (主从概念+原理+主从延迟
)
MySQL主从复制读写分离,看这篇就够了!(mysql主从复制配置 + shardingjdbc读写分离配置)
麻了,一个操作把MySQL主从复制整崩了(大事务+blob字段大致binlog非常大,且binlog非mixed模式)
5.1 数据库主从架构
5.2 主从复制原理
5.3 主从延迟问题
6.sharding的本地事务讨论
先放结论:ORZ~~~
记录大佬博客:[@Transactional 竟也能解决分布式事务?]
(cloud.tencent.com/developer/a…)
话外:Spring - Transaction为啥不支持多数据源,不支持异步