MySQL优化--主从同步,分库分表

目录

MySQL主从同步原理

 MySQL主从复制的核心就是二进制日志

面试回答

分库分表

分库分表的时机

分库分表的策略

垂直分库

垂直分表

水平分库

水平分表

分库分表的策略

分库之后的问题

面试回答


MySQL主从同步原理

如果项目上线了,通常情况下,会去搭建主从的架构,一个JAVA应用,首先要去廉价而数据库的中间件,中间件其中至少连接了两个库。当主库写数据的时候,就要把数据同步到从库,那是如何进行同步的呢?原理又是什么呢?

MySQL优化--主从同步,分库分表_第1张图片

 MySQL主从复制的核心就是二进制日志

        二进制日志(BINLOG)记录了所有的 DDL(数据定义语言CREATE,DROP,OUT)语句和 DML(数据操纵语言INSERT,UPDATE,DELETE)语句,但不包括数据查询(SELECT、SHOW)语句。
MySQL优化--主从同步,分库分表_第2张图片

        同步流程是这样的,当主库数据发生了变化,比如是一个写操作,也可以是DDL或者是DML,会把这些数据写到一个blog日志文件中,这时候,从库有一个IOthread线程,专门从主库的blog日志文件中读取数据,读取完成后,就会写入到从库的中继日志中,叫做Relay log。

        再由从库的SQLthread线程来读取中继日志的文件,把里面的命令在重新执行一次,执行完之后,主库和从库不就保持同步了吗

        复制主要分成三步:

Master 主库在事务提交时,会把数据变更记录在二进制日志文件 Binlog 中。

从库读取主库的二进制日志文件 Binlog ,写入到从库的中继日志 Relay Log

slave重做中继日志中的事件,将改变反映它自己的数据。

面试回答

MySQL优化--主从同步,分库分表_第3张图片

面试官:MySQL主从同步原理

候选人:MySQL主从复制的核心就是二进制日志(DDL(数据定义语言)语句 和 DML(数据操纵语言)语句),它的步骤是这样的:

第一:主库在事务提交时,会把数据变更记录在二进制日志文件 Binlog 中。

第二:从库读取主库的二进制日志文件 Binlog ,写入到从库的中继日志 Relay Log 。

第三:从库重做中继日志中的事件,将改变反映它自己的数据

分库分表

在主从同步阶段,主库和从库的数据是一样的,主要解决的是访问的压力,让读写分开进行,它是解决不理海量数据存储的问题的,这个时候,就需要分库分表

当然分库分表也不是一开始就需要的,而是有前提的

分库分表的时机

1前提,项目业务数据逐渐增多,或业务发展比较迅速(单表的数据量达1000W20G以后 )

2,优化已解决不了性能问题(主从读写分离、查询索引

3IO瓶颈(磁盘IO、网络IO)、CPU瓶颈(聚合查询、连接数太多)

分库分表主要解决的是存储的压力,本来只有一个库,现在分了多个库进行存储,是不是就可以存储更多的数据,同时因为我有多个库,那我每一个节点是不是都可以处理用户的请求呢,是不是就可以增加用户的连接数

分库分表的策略

MySQL优化--主从同步,分库分表_第4张图片

垂直分库

以表为依据,根据业务将不同表拆分到不同库中。

MySQL优化--主从同步,分库分表_第5张图片

 

如图,这是一张电商的数据库,前面两张都是和用户有关系,中间两张都是和订单有关系,后面两张是和商品有关系

所以现在我们可以根据不同的业务将不同的表存储到数据库中,这就是典型的垂直分库。而微服务不就是不同的服务对应不同的数据库,如图,不同的服务与不同的数据库相对应

特点:

1按业务对数据分级管理、维护、监控、扩展

2在高并发下,提高磁盘IO和数据量连接数

垂直分表

以字段为依据,根据字段属性将不同字段拆分到不同表中。

拆分规则:

1,把不常用的字段单独放在一张表

2,把textblob等大字段拆分出来放在附表中

MySQL优化--主从同步,分库分表_第6张图片

 

如图,前面的字段都是对于商品的基本描述,而最后的description描述则是大文本内容,所以我们将表拆为基本信息和详细信息,这两个表分别存储不同的数据,其中两张表之间是1对1的关系

特点:

1,冷热数据分离

2,减少IO过渡争抢,两表互不影响

水平分库

将一个库的数据拆分到多个库中。

当数据量越来越大,如果还放在一起可能会影响性能,这个时候我们就需要把他拆到各个库中进行存储。

MySQL优化--主从同步,分库分表_第7张图片

 

如图,每个库中存储的数据是不一样的,所有的库加起来,才是这个订单业务的所有的数据,但是此时出现了一个问题,现在有三个库,那我们应该如何找到数据并且进行查询呢?

在我们查询的时候,其实是有一些路由的规则

1,根据id节点取模

2,按id也就是范围路由,节点1(1-100),节点2(100-200)

特点:

1,解决了单库大数量,高并发的性能瓶颈问题

2,提高了系统的稳定性和可用性

 

水平分表

将一个表的数据拆分到多个表中(可以在同一个库内)

MySQL优化--主从同步,分库分表_第8张图片

特点:

优化单一表数据量过大而产生的性能问题;

避免IO争抢并减少锁表的几率;

分库分表的策略

在一开始的时候,我们的应用程序只是连接了其中的一个库,

现在我们一个应用程序连接了三个库,还要按照取模的方式去找到各个数据库,假如后面因为业务要求,又做了集群,实现起来就会越来越复杂,就会产生一系列的问题

分库之后的问题

1分布式事务一致性问题

        现在有多个库,多个表,现在要同时操作在不同数据库中的不同的表,每一个库都会管理自己的事务,假如有一个库它的提交失败了,这个时候是不是就会产生事务不一致的问题

2,跨节点关联查询

        假如做了分库分表,现在你的a库和b库分别存储的是不同的表,两张表还要进行关联,这个又怎么做呢

3,跨节点分页、排序函数

        和2一样,这种排序,分页又要怎么做呢,即使说是取模,那有应该怎么去分页查询这些数据呢

4,主键避重

        假如现在做了水平分库,每个库中存储的都是相同的表,每个表中的id可能都是自增的,会不会出现id重复的情况呢

MySQL优化--主从同步,分库分表_第9张图片

为了避免上述问题的产生,一般在项目中使用分库分表的话,都会去增加一个中间件,进行关联,并且可以帮助我们降低开发的难度,并且可以帮助我们解决上述的问题

分库分表中间件。比如:

sharding-sphere

mycat

面试回答

MySQL优化--主从同步,分库分表_第10张图片

面试官:你们项目用过MySQL的分库分表吗?

候选人: 嗯,因为我们都是微服务开发,每个微服务对应了一个数据库,是根据业务 进行拆分的,这个其实就是垂直拆分。

面试官:那你之前使用过水平分库吗?

候选人: 嗯,这个是使用过的,我们当时的业务是(xxx),一开始,我们也是单库,后 来这个业务逐渐发展,业务量上来的很迅速,其中(xx)表已经存放了超过 1000万的数据,我们做了很多优化也不好使,性能依然很慢,所以当时就使 用了水平分库。

我们一开始先做了3台服务器对应了3个数据库,由于库多了,需要分片,我 们当时采用的mycat来作为数据库的中间件。数据都是按照id(自增)取模 的方式来存取的。

当然一开始的时候,那些旧数据,我们做了一些清洗的工作,我们也是按照 id取模规则分别存储到了各个数据库中,好处就是可以让各个数据库分摊存 储和读取的压力,解决了我们当时性能的问题

你可能感兴趣的:(mysql,java,数据库)