MySQL高级(下):
分库分表:
可根据用户ID或者手机号hash计算来决定存储在哪个库,插入时,利用手机号进行hash算法,根据hash环来定位存储库
可根据时间维度,根据时间来确定存储在哪个库,比如一些流水数据.
可根据业务来进行分库存储.比如根据不同的记录对应的其他记录,可插入同一数据库
主键的选择:
UUID:性能较差
雪花SNOWFLAKE:比较优秀
数据一致性:
强一致性:XA
最终一致性:TCC,SAGA,SEATA
扩容:
平滑扩容,X2式扩容
业务层改造:
重点:
分布式数据库一定需要代理,如果没有代理,那么应用就要频繁的更换数据源.这样对可用性其实较为低效.
分库的问题:
事务问题
同时插入数据,如何保证一致性.
跨库跨表查询的join问题,不同库的表联查.
全局表,所有库都有
字段冗余,不会关联到join查询.
应用级处理.
数据管理的复杂度和运算压力.
分布式数据库中间件 ShardingSphere:
之前为Sharding JDBC和Sharding Proxy,3.0后改为ShardingSphere,包含前两者和Sharding-Sidecar(开发中)
定位于关系型数据库中间件.
Sharding JDBC:轻量级框架 对JDBC提供额外服务
Sharding-Porxy:数据库透明化的代理端.跨语言支持.
Sharding-Sidecar云端型的中间件.正在规划设计中.
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021010922583377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
Sharding-JDBC:
增强版的JDBC.兼容任何ORM框架,
可使用连接池:durid、c3p0
多库支持:mysql、oracle等
主要功能:
分库、分表;读写分离;分片策略;分布式主键
分布式事务:
标准化事务接口
XA强一致性事务
柔性事务
数据库治理:
配置治理
数据库编排控制
数据脱敏(加密)
可视化链路追踪
用法:
maven依赖
sharding-jdbc-core
规则配置:
创建DataSource:
ShardingDataSourceFactory
Sharding-JDBC模块结构:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109225446878.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
ShardingDataSourceFactory支持分库分表、读写分离
MasterSlaveDataSourceFactory支持读写分离
TableRuleConfiguration表分片配置
MasterSlaveRuleConfiguration读写分离配置
初始化流程:
1.根据配置生成配置对象
2.利用配置生成rule对象
3.rule与datasource进行组装
4.sharding-jdbc使用datasource进行操作
数据分片:
表概念:
真实表:
物理表,数据库存在的表, tb_order1、tb_order2
逻辑表:
分片的物理表的统称.tb_order
数据节点:
分片后的数据库和表的节点标记,比如db1.tb_order1
绑定表:
主从表的结构称呼.类似于视图的概念.分片规则需要一致才可成为绑定表,可提升查询效率,不会造成扫描量大
广播表:
所有的库都存在,不需分片.数据量固定.需要做关联查询.如字典表、状态表等.
分片算法:
精确分片算法PreciseShardingAlgorithm:
=与in的分片
范围分片算法RangeShardingAlgorithm:
> < 的分片
复合分片算法CompleShardingAlgorithm:
多键分片的算法
Hint分片算法HintShardingAlgorithm:
无法确定键的分片
分片策略:
标准分片策略StandardShardingStrategy:
精确+范围(可选)的算法添加,如果用了范围却没指定范围算法,会导致全库扫描
复合分片策略 CompleXShardingStrategy:
多键并且精确+范围算法添加
行表达式分片策略 InLineShardingStrategy:
通过Groovy的行表达式的分片算法进行分片. 比如tb_order(id % 2) = tb_order0或者tb_order1
Hint分片策略HintShardingStrategy:
Hint分片算法指定
不分片策略
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109225609744.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
分片流程:
SQL解析
词法解析和语法解析,先拆成单词,再用语法解析进行理解,解析出上下文;
使用不同的解析器解析:
mysql解析器将语句转换为mysql和mrial的语句
oracle解析器、sqlServer解析器、postgre解析器、默认解析器
查询优化
优化sql语句的关键词,比如or等
SQL路由
将分片的库和表进行路由查找关联
SQL改写
将sql进行一定程度的改写
SQL执行
多线程执行多库多表语句,拿到结果
结果归并
将多线程的结果进行归并统一封装
分片sql规范:
单节点(单库)mysql数据库全兼容.
多节点(多库多表)的话,有些语法不支持:having、case when、union(all)
支持分页子查询,其他子查询有限支持,只能支持第一层子查询.多层就会报出异常
归并限制导致子查询聚合函数无法支持(SUM那种)普通聚合没事
不能支持物理多库的表名(带上数据源那种),就老实儿写逻辑表名
将分片列使用了函数,那么会导致全路由查询
不支持insert ?占位符和insert select
分页查询:
mysql 大量数据的分页时,索引无法跳过当前到指定位置.而为了保证数据正确性,多库多表的话 会改成比从0到当前下标的所有数据,多表就多一次这种查询.这样更雪上加霜.
我们需要对我们的SQL进行一些优化,比如ID设置有序,将分页改为范围查询,然后再limit,这样就会提高效率
inline表达式:
简化配置.一体化管理配置.
语法结构:
${}或$->{},范围start..end,枚举[a1,a2,a3],如果多个表达式嵌套,那么会得出表达式之间可选数的复合相乘条数据.
库名、表名没有固定规律时的表达式解决:拆开吧...别想了
主键生成:
内置UUID和snowflake,可以自定义生成规则,默认为雪花
自定义流程:
实现ShardingKeyGenerator接口
SPI规范来加载自定义的接口,mateinf->services->org.apache.shadingsphere.spi.keygen.ShardingKeyGenerator来填写自定义类
配置主键列和主键名称.
sharding-jdbc实战:
分库分表的应用:
配置spring配置文件来决定哪些库、表,并配置哪表中字段作为分片键.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109230003667.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
读写分离的需知:
读写分离只支持单主库;
不需要SQL改写,根据sql直接路由到读写库;
同一线程切同一连接内,能保持数据一致性,即该线程写后,读也用主库读.
Hint强制主库路由,强制用主库查询.防止主库复制延迟.
读写分离的应用:
配置中添加主从路由设置,设置哪些是主哪些是从.分片算法直接在后面添加即可,只是在配置数据源时需要区分主从.
主从架构和分库分表的一些区别和场景:
主从架构:读写分离,保证高可用,读写扩展.一主多从、多主多从(多主会有一些一致性的问题,不太建议使用)根据sql的语义(查还是改)来路由到哪个库
分库分表:数据分片,读写扩展,存储扩容,库和表数据不同,根据分片配置进行路由
某些情况不管:
数据同步他不管;
同步延迟他不管;
不能双主或多主;
跨库之间的数据不一致;
也可复合使用,分库分表+读写分离.一主一从读写分离,多个主从进行分片数据,但复杂度更高.
常见方案:阶梯升级型
开始主从,数据量增大后开始分表,建立从库,继续增大,开始读写分离+分库分表,总之方案是根据数据量进行逐步提升,而不是一口气到最大,造成资源浪费.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109230035950.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
Hint强制路由:
通过自定义代码来设置路由规则.
分片:分片键没有在SQL中,在业务代码中设置
读写分离:强制路由访问到哪些库.
Hint在业务需要时使用,可快速定位需要访问的库,这个应该常用.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109230116387.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
数据脱敏:
在插入时对sql进行解析,将设置的一些规则进行改写加密.达到加密的目的;
查询时,根据SQL对设置的脱敏规则进行解密,展示数据.
我们需要配置的就是脱敏规则.
分布式事务:
分布式事务XA强一致性:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109230150814.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
分布式事务TCC模式:
分布式事务分为主动方和被动方,当主动方发起了写入事物时,再响消息队列发送消息,被动方接收消息进行写入.写入后被动发送消息,主动进行接收确认被动写入完成.
发送失败的情况:
主动消息发送失败:
被动写入失败:
被动读消息失败:
分布式事务saga模式:
一堆短事务组成一个长事务.
每个更新的事务都有对应的补偿事务来保证一致性.
每个saga事务都有一堆幂等的有序事务(ti)组成.
每个ti事务都有对应的补偿事务用于撤销ti事务修改的结果.
向前恢复:
出现问题,接着更新,那么整体看相当于更新了两次,只不过第二次相当于补偿第一次更新.
向后恢复:
出现问题,用补偿事务进行撤销操作.一般很少见.回滚或撤销的操作在分布式事务都有风险.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210109230248362.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM4MDIxMjc=,size_16,color_FFFFFF,t_70)
分布式事务Seata框架:
目标:像本地事务一样管理分布式事务.
支持AT、TCC、Saga三种模式(思想)
AT模型:
谁发起事务谁就是TM,提交都交给了TC(事务控制),TC去给RM发布命令,进行提交还是回滚的操作.
TC将主发起的事务给了一个XID,其余小事务都是跟这个XID关联.
sharding-jdbc XA整合原理:
数据库需要实现RM,TM是第三方实现的.如Atomikos、Narayana、Bitronix等
ShardingSphere支持的分布式事务的功能:
支持XA事务;
两阶段提交保持强一致性;
服务宕机重启,提交或回滚的事务自动恢复执行;
SPI机制去整合第三方的TM,默认SPI加载Atomikos
支持XA和非XA的连接池;
springboot和namespace的接入;
底层机制:上图
流程:
begin:开启全局事务
执行物理SQL:
commit/rollback:
sharding-jdbc Saga整合原理:
柔性事务
通过sevicecomb-saga组件实现,SPI机制注入.
基于反向SQL实现反向补偿,根据更新的SQL语句自动生成反向的SQL, insert就生成delete这种.
完全支持跨库;失败的SQL最大努力送达和重试;反向SQL;默认关系型数据库快照和事务日志持久化,SPI可加载其他类型持久化.
底层机制:上图
sharding-jdbc Seata整合原理:
柔性事务
也支持补偿SQL;支持隔离级别;
底层机制:上图
Sharding-JDBC分布式事务应用:
jta.propertiesl来添加XA相关的配置
saga.properties来添加saga相关的配置
具体应用:
XA:
添加依赖;sharding-transaction-xa-core
添加配置:
添加注解:
@spring事务注解
@SharingTransactionType(TransactionType.XA)
Saga:
添加依赖:sharding-transaction-saga-core
Sharding-Proxy:
下载发行版;