Sharding-JDBC 分库分表
1.概述
1.1分库分表是什么 ?作用,方式
什么是分库分表:
把数据分散在不同的数据库中,使得单一数据库的数据 量变小来缓解单一数据库的性能问题 ,从而达到提升
数据库性能的目的,如下图:将电商数据库拆分为若干独立的数据库,并且对于大表也拆分为若干小表,通过这种
数据库拆分的方法来解决数据库的性能问题。
作用:
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据
库组成,将数据大表拆分成若干数据表组成,使得单-数据库、 单-数据表的数据量变小,从而达到提升数据库
性能的目的。
方式:
垂直分库 水平分库
垂直分表 水平分库
分表
垂直分表
垂直分表定义:将一个表按照字段分成多表,每个表存储其中- -部分字段。
按照访问评率进行分字段
它带来的提升是:
1.为了避免I0争抢并减少锁表的几率,查看详情的用户与商品信息浏览互不影响
2.充分发挥热门]数据的操作效率,商品信息的操作的高效率不会被商品描述的低效率所拖累。
水平分表
水平分表是在同-个数据库内,把同一个表的数据按一定规则拆到多个表中。
<!--对数据行的拆分,不影响表结构-->
它带来的提升是:
●优化单-表数据量过大而产生的性能问题
●避免10争抢并减少锁表的几率
分库
垂直分库
垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核
心理念是专库专用。
它带来的提升是:
解决业务层面的耦合,业务清晰
●能对不同业务的数据进行分级管理、维护、监控、扩展等
●高并发场景下,垂直分库-定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈
垂直分库通过将表按业务分类,然后分布在不同数据库,并且可以将这些数据库部署在不同服务器上,从而
达到多个服务器共同分摊压力的效果,但是依然没有解决单表数据量过大的问题。
水平分库
水平分库是把同一个表的数据按一定规则拆到不同的数据库中 ,每个库可以放在不同的服务器上。
<!--对比:垂直分库是把不同表拆到不同数据库中,它是对数据行的拆分,不影响表结构- ->
它带来的提升是:
●解决了单库大数据,高并发的性能瓶颈。
●提高了系统的稳定性及可用性。<!-- 稳定性体现在Io冲突减少,锁定减少 ,可用性指某个库出问题,部分可
用-->
sharding执行流程
sql解析 --- sql路由 ---sql改写 ---sql执行 --- 结果归并
SQL解析: 过程分为词法解析和语法解析。 词法解析器用于将SQL拆解为不可再分的原子符号,称为Token。并根据 不同数据库方言所提供的字典,将其归类为关键字,表达式,字面量和操作符。 再使用语法解析器将SQL转换为抽 象语法树。 例如,以下SQL: 解析之后的为抽象语法树见下图: SELECT id, name FROM t_user WHERE status = 'ACTIVE' AND age > 18
路由: SQL路由就是把针对逻辑表的数据操作映射到对数据结点操作的过程。
改写: 工程师面向逻辑表书写的SQL,并不能够直接在真实的数据库中执行,SQL改写用于将逻辑SQL改写为在真实数据 库中可以正确执行的SQL。
sql执行:
内存限制 并行 效率最大化
连接限制: 串行 保证事务
结果归并:
流式归并: 一般是用这种
内存归并:
装饰者归并:
分表,分库策略
更具该字段定义分库规则的列叫分库键,
分库键 + 分库键 = 分库策略
更具该字段定义分表规则的列叫分表键,
分表键 + 分表键 = 分表策略
分表查询
如果查询中不包含分表键,就会广播路由,会去每个分表进行查询,能加入分表建尽量就加入分表键;
分库查询
如果查询中不包含分库键,就会广播路由,会去每个数据源进行查询,能加入分库建尽量就加入分库键;
mysql主从分离
主库
my.ini
character-set-server=utf8
# 开启日志
log-bin=mysql-bin
# 设置需要同步的数据库
binlog-do-db=sharding_user
binlog-do-db=sharding1
binlog-do-db=sharding2
# 屏蔽系统库
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
mysql 命令
#授权主备复制专用账号
GRANT REPLICATION SLAVE ON *.* TO 'db_sync'@'%' IDENTIFIED BY 'db_sync';
#刷新权限
FLUSH PRIVILEGES;
#确认位点 记录下文件名以及位点
SHOW MASTER STATUS;
从库
my.ini
server-id=2
# 开启日志
log-bin=mysql-bin
# 设置需要同步的数据库
replicate_wild_do_table=sharding_user.%
replicate_wild_do_table=sharding1.%
replicate_wild_do_table=sharding2.%
# 屏蔽系统库
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=performance_schema.%
#先停止同步
STOP SLAVE;
#修改从库指向到主库,使用上一步记录的文件名以及位点
CHANGE MASTER TO MASTER_HOST = 'localhost',
MASTER_USER = 'db_sync',
MASTER_PASSWORD = 'db_sync',
MASTER_LOG_FILE = 'mysql-bin.000002',
MASTER_LOG_POS = 607;
#启动同步
START SLAVE;
#查看从库状态Slave_IO_Runing和Slave_SQL_Runing都为Yes说明同步成功,如果不为Yes,请检查error_log,然后 排查相关异常。
SHOW SLAVE STATUS
#注意 如果之前此备库已有主库指向 需要先执行以下命令清空
STOP SLAVE IO_THREAD FOR CHANNEL '';
RESET SLAVE ALL;
注意事项
server-uuid冲突
由于是复制原来的数据库,所以他们 auto.cnf文件下的 server-uuid是一模一样的 , 所以需要删除他们的 auto.cnf文件 ,重新启动让他们自动再生成一次 属于自己的 server-uuid;