引用

https://www.cnblogs.com/fengzheng/p/13401783.html
https://zhuanlan.zhihu.com/p/98392844
https://juejin.cn/post/6844903647197806605
https://zhuanlan.zhihu.com/p/98948473

主从数据库

数据库层主要由如下几种模式,分别是单点模式、主备模式、主从模式。
image.png

主从模式

主从配置一般都是和读写分离相结合,主服务器负责写数据,从服务器负责读数据,并保证主服务器的数据及时同步到从服务器。

主从模式又分为一主一从、一主多从和多主多从,越往后部署越复杂,同时,系统稳定性更高。主从模式可以更好的分担数据库压力,将插入更新操作和查询操作分开,提高系统整体性能。

优势

  1. 做数据的热备
  2. 有利于架构的扩展。
  3. 读写分离,使数据库能支撑更大的并发

主从原理

MySQL之间数据复制的基础是二进制日志文件(binary log file)一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志(Relay log)中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。

主节点

  1. 当主节点上进行 insert、update、delete 操作时,会按照时间先后顺序写入到 binlog 中
  2. 当从节点连接到主节点时,主节点会创建一个叫做 binlog dump 的线程
  3. 一个主节点有多少个从节点,就会创建多少个 binlog dump 线程
  4. 当主节点的 binlog 发生变化的时候,也就是进行了更改操作,binlog dump 线程就会通知从节点 (Push模式),并将相应的 binlog 内容发送给从节点

从节点

当开启主从同步的时候,从节点会创建两个线程用来完成数据同步的工作。

  • I/O线程

此线程连接到主节点,主节点上的 binlog dump 线程会将 binlog 的内容发送给此线程。此线程接收到 binlog 内容后,再将内容写入到本地的 relay log。

  • SQL线程

该线程读取 I/O 线程写入的 relay log,并且根据 relay log 的内容对从数据库做对应的操作。

读写分离

主从分离之后,就要做系统的读写分离了,写操作走主节点,读操作走从节点。这就需要数据库中间件来帮忙了,现在比较流行的中间件有Atlas、Cobar、Mycat、Sharding-Sphere

Sharding-Sphere 包括 ShardingSphere-JDBC 和 ShardingSphere-Proxy。

ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

  • 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC。
  • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP 等。
  • 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,Oracle,SQLServer,PostgreSQL 以及任何遵循 SQL92 标准的数据库。

spring boot maven引入

<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  <version>4.1.1</version>
</dependency>

分库分表

主从数据库可以解决读的问题,但在面临写请求的增加就无能为力了。(加一个Master是不能解决问题的, 因为数据要保存一致性,写操作需要2个master之间同步,相当于是重复了,而且更加复杂)

分库分表的顺序应该是先垂直分,后水平分

垂直拆分

垂直指数据库中的例

垂直分表

将一个表按照字段分成多表,每个表存储其中一部分字段,一般是针对那种几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。(MySQL、MSSQL底层都是通过“数据页”来存储的,“跨页”问题可能会造成额外的性能开销)

  • 避免IO争抢并减少锁表的几率
  • 将表按字段切开,将热门字段、冷门字段分开放置在不同库中,充分发挥热门数据的操作效率

垂直分库

​ 垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库建议放在不同的服务器上,它的核心理念是专库专用。

  • 高并发场景下,垂直分库一定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈

水平拆分

水平指数据库中的行

水平分库

水平分库是把同一个表的数据按一定规则(如:奇偶)拆到不同的数据库中,每个库可以放在不同的服务器上。

  • 解决了单库大数据,高并发的性能瓶颈

水平分表

水平分表是在同一个数据库内,把同一个表的数据(与垂直不同)按一定规则拆到多个表中

  • 避免IO争抢并减少锁表的几率
  • 优化单一表数据量过大而产生的性能问题
  • 感觉有点不实用QWQ

分库分表问题

​分库分表能有效的缓解了单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数的瓶颈

事务一致性问题

由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题

跨节点关联查询

垂直分库后[商品信息]和[店铺信息]不在一个数据库,甚至不在一台服务器,无法进行关联查询。

需要将原关联查询分为两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据,最后将获得到的数据进行拼装。

跨节点分页,排序

跨节点多库进行查询时,limit分页、order by排序等问题,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。

主键重复问题

​在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。

MySQl分布式事务

InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对于事务原有的ACID要求又有了提高。另外,在使用分布式事务时,InnoDB存储引擎的事务隔离级别必须设置为SERIALIZABLE。