序言:
文章内容输出来源:拉勾教育Java高薪训练营。
本篇文章是学习课程中的一部分课后笔记
一、分库分表介绍
1.遇到的问题
- 用户请求量太大
单服务器TPS、内存、IO都是有上限的,需要将请求打散分布到多个服务器 - 单库数据量太大
单个数据库处理能力有限;单库所在服务器的磁盘空间有限;单库上的操作IO有瓶颈 - 单表数据量太大
查询、插入、更新操作都会变慢,在加字段、加索引、机器迁移都会产生高负载,影响服务
2.解决方案
- 垂直拆分
-
垂直分库
垂直分库.png
微服务架构时,业务切割得足够独立,数据也会按照业务切分,保证业务数据隔离,大大提
升了数据库的吞吐能力
-
垂直分表
垂直分表.png
表中字段太多且包含大字段的时候,在查询时对数据库的IO、内存会受到影响,同时更新数
据时,产生的binlog文件会很大,MySQL在主从同步时也会有延迟的风险
-
- 水平拆分
-
水平分库
将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合
不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件
资源等的瓶颈
水平分库.png -
水平分表
针对数据量巨大的单张表(比如订单表),按照规则把一张表的数据切分到多张表里面去。
但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。
水平分表.png
-
3.分库分表规则
-
水平分库规则
不跨库、不跨表,保证同一类的数据都在同一个服务器上面。
数据在切分之前,需要考虑如何高效的进行数据获取,如果每次查询都要跨越多个节点,就需要谨
慎使用。 -
水平分表规则
-
RANGE
时间:按照年、月、日去切分。例如order_2020、order_202005、order_20200501
地域:按照省或市去切分。例如order_beijing、order_shanghai、order_chengdu
大小:从0到1000000一个表。例如1000001-2000000放一个表,每100万放一个表 -
HASH
用户ID取模
不同的业务使用的切分规则是不一样,就上面提到的切分规则,举例如下: -
站内信
用户维度:用户只能看到发送给自己的消息,其他用户是不可见的,这种情况下是按照
用户ID hash分库,在用户查看历史记录翻页查询时,所有的查询请求都在同一个库内 -
用户表
用户表.png
范围法:以用户ID为划分依据,将数据水平切分到两个数据库实例,如:1到1000W在
一张表,1000W到2000W在一张表,这种情况会出现单表的负载较高
按照用户ID HASH尽量保证用户数据均衡分到数据库中
- 流水表
时间维度:可以根据每天新增的流水来判断,选择按照年份分库,还是按照月份分库,
甚至也可以按照日期分库
- 流水表
-
4.分库分表其他情况
- 主键选择
UUID:本地生成,不依赖数据库,缺点就是作为主键性能太差
SNOWFLAKE:百度UidGenerator、美团Leaf、基于SNOWFLAKE算法实现 - 数据一致性
强一致性:XA协议
最终一致性:TCC、saga、Seata - 数据库扩容
成倍增加数据节点,实现平滑扩容
成倍扩容以后,表中的部分数据请求已被路由到其他节点上面,可以清理掉 - 业务层改造
基于代理层方式:Mycat、Sharding-Proxy、MySQL Proxy
基于应用层方式:Sharding-jdbc - 分库后面临的问题
- 事务问题:一次投递需要插入两条记录,且分布在不同的服务器上,数据需要保障一致性。
- 跨库跨表的join问题:
- 全局表(字典表):基础数据/配置数据,所有库都拷贝一份
- 字段冗余:可以使用字段冗余就不用join查询了
- 系统层组装:可以在业务层分别查询出来,然后组装起来,逻辑较复杂
- 额外的数据管理负担和数据运算压力:数据库扩容、维护成本变高
二、ShardingSphere简介
1.ShardingSphere
Apache ShardingSphere是一款开源的分布式数据库中间件组成的生态圈。它由Sharding-JDBC、
Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。
shardingsphere.png
- Sharding-JDBC:被定位为轻量级Java框架,在Java的JDBC层提供的额外服务,以jar包形式使用。
- Sharding-Proxy:被定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版
本,用于完成对异构语言的支持。 - Sharding-Sidecar:被定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代
理所有对数据库的访问。
2.Sharding-JDBC
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架的使用。
- 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
- 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
-
支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。
jdbc.png
Sharding-JDBC主要功能:
- 数据分片
分库、分表
读写分离
分片策略
分布式主键 - 分布式事务
标准化的事务接口
XA强一致性事务
柔性事务 - 数据库治理
配置动态化
编排和治理
数据脱敏
可视化链路追踪
Sharding-JDBC内部结构:
初始化过程:
- 根据配置的信息生成Configuration对象
- 通过Factory会将Configuration对象转化为Rule对象
- 通过Factory会将Rule对象与DataSource对象封装
- Sharding-JDBC使用DataSource进行分库分表和读写分离操作
3.Sharding-Proxy
harding-Proxy是ShardingSphere的第二个产品,定位为透明化的数据库代理端,提供封装了数据库
二进制协议的服务端版本,用于完成对异构语言的支持。
目前先提供MySQL版本,它可以使用任何兼容MySQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench等操作数据,对DBA更加友好。
- 向应用程序完全透明,可直接当做MySQL使用
- 适用于任何兼容MySQL协议的客户端
Sharding-Proxy使用过程:
- 下载Sharding-Proxy的最新发行版;
- 解压缩后修改conf/server.yaml和以config-前缀开头的文件,进行分片规则、读写分离规则配置
编辑%SHARDING_PROXY_HOME%\conf\config-xxx.yaml
编辑%SHARDING_PROXY_HOME%\conf\server.yaml - 引入依赖jar
如果后端连接MySQL数据库,需要下载MySQL驱动, 解压缩后将mysql-connector-java-
5.1.48.jar拷贝到${sharding-proxy}\lib目录。
如果后端连接PostgreSQL数据库,不需要引入额外依赖。 - Linux操作系统请运行bin/start.sh,Windows操作系统请运行bin/start.bat启动Sharding-Proxy。
使用默认配置启动: start.sh
配置端口启动:start.sh ${port} - 使用客户端工具连接。如: mysql -h 127.0.0.1 -P 3307 -u root -p root
若想使用Sharding-Proxy的数据库治理功能,则需要使用注册中心实现实例熔断和从库禁用功能。
Sharding-Proxy默认提供了Zookeeper的注册中心解决方案。只需按照配置规则进行注册中心的配置,即可使用。
注意事项:
- Sharding-Proxy 默认不支持hint,如需支持,请在conf/server.yaml中,将props的属性proxy.hint.enabled设置为true。在Sharding-Proxy中,HintShardingAlgorithm的泛型只能是
String类型。 - Sharding-Proxy默认使用3307端口,可以通过启动脚本追加参数作为启动端口号。如:
bin/start.sh 3308 - Sharding-Proxy使用conf/server.yaml配置注册中心、认证信息以及公用属性。
- Sharding-Proxy支持多逻辑数据源,每个以"config-"做前缀命名yaml配置文件,即为一个逻辑数
据源。
网友评论