MySQL(八)高可用

2024 年 4 月 23 日 星期二(已编辑)
/
72
这篇文章上次修改于 2024 年 7 月 24 日 星期三,可能部分内容已经不适用,如有疑问可询问作者。

阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。

MySQL(八)高可用

MySQL主从复制的过程是怎么样

主从复制主要有3个阶段:

  • 主库修改数据后,会写入binlog日志,从库连接到主库之后,主库会创建一个log dump线程,用于发送binlog的内容
  • 从库会创建一个专门的I/O线程来连接主库的log dump线程,来接收主库的binlog日志,再把binlog信息写入relay log的中继日志里,再返回给主库复制成功的响应
  • 接着从库还会创建一个用于回放binlog的SQL线程,去读relay log中继日志,然后回放binlog更新存储引擎中的数据,最终实现主从的数据一致性

MySQL提供了几种复制模式?默认的复制模式是什么

主要有三种同步复制、半同步复制、异步复制,MySQL默认的复制模型是异步复制

  • 同步复制:MySQL主库提交事务的线程要等待所有从库的复制成功响应,才返回客户端结果。这种方式是性能最差的复制模式,但是能保证数据的安全性,如果对数据安全性比较高的业务,可以考虑采用同步复制的模式。
  • 异步复制:MySQL主库提交事务的线程并不会等待binlog同步到各从库,就返回客户端结果,这种模式性能是最高的,但是一旦主库宕机,数据就会发生丢失。
  • 半同步复制:介于两者之间,事务线程不用等待所有的从库复制成功响应,只要一部分复制成功响应回来就行,比如一主二从的集群,只要数据成功复制到任意一个从库上,主库的事务线程就可以返回给客户端。这种半同步复制的方式,兼顾了异步复制和同步复制的优点,即使出现主库宕机,至少还有一个从库有最新的数据,不存在数据丢失的风险。

MySQL主从复制的数据延迟怎么解决

  • 使用缓存解决:可以在写入数据主库的同时,把数据写到Redis缓存里,这样其他线程再获取数据时会优先查询缓存,也可以保证数据的一致性。不过这种方式会带来缓存和数据库的一致性问题。
  • 直接查询主库:对于数据延迟敏感的业务,可以强制读主库。但是我们要提前明确查询的数据量不大,不然会出现主库写请求锁行,影响读请求的执行,最终对主库造成比较大的压力。

MySQL主从架构中,读写分离怎么实现

一种简单的做法是:提前把所有数据源配置在工程中,每个数据源对应一个主库或者从库,然后改造代码,在代码逻辑中进行判断,将SQL语句发送给某一个指定的数据源来处理。这个方案简单易实现,但SQL路由规则侵入代码逻辑,在复杂的工程中不利于代码的维护。

另一个做法是:独立部署的代理中间件,如MyCat,这一类中间件部署在独立的服务器上,一般使用标准的MySQL通信协议,可以代理多个数据库。该方案的优点是隔离底层数据库与上层应用的访问复杂度,比较适合有独立运维团队的公司选型;缺陷是所有的SQL语句都要跨两次网络传输,有一定的性能损耗,再就是运维中间件是一个专业且复杂的工作,需要一定的技术沉淀。

MySQL主库挂了怎么办

MySQL主从复制没有实现发现主服务器宕机和处理故障迁移的功能,要实现自动主从故障迁移的话,可以使用开源的MySQL高可用套件MHA,MHA可以在主数据库发生宕机时,可以剔除原有主机,选出新的主机,然后对外提供服务,保证业务的连续性。

什么是分库分表?什么时候需要分表?什么时候需要分库

分库分表的意思把原本存储于单个数据库上的数据拆分到多个数据库,把原来存储在单张数据表的数据拆分到多张数据表中,实现数据切分。

分库分表使用的场景不一样:

  • 当单张数据表的数据量太大的时候,经验值是500W以上的数据量,就会影响了事务的执行效率,这时候就要考虑分表了,通过减少每次查询数据总量来解决数据查询缓慢的问题。
  • 当单台MySQL扛不住高并发流量的时候,就要考虑分库了,把并发请求分散到多台MySQL实例中。

分库分表后,会产生什么问题?怎么解决

分布式事务问题:对业务进行分库之后,同一个操作会分散到多个数据库中,涉及跨库执行SQL语句,也就出现了分布式事务问题。

  • 解决方式,如果对一致性要求比较高的业务,比如金融类的业务,可以使用分布式事务中间件,实现TCC事务模型;互联网的业务通常对一致性要求低,会使用基于本地消息表来实现分布式事务,达到最终一致性的效果,这个分布式事务的方案性能会好一些。

全局ID唯一性问题:在单库单表时,业务D可以依赖数据库的自增主键实现,进行分库分表之后,如果还是用数据库的自增主键,可能会导致主键重复。

  • 解决方式,可以通过雪花算法或者美团leaf算法生成唯一主键ID。

跨库跨表关联查询问题:分库分表后,跨库和跨表的查询操作实现起来会比较复杂。

  • 解决方式,可以通过冗余额外字段避免跨库关联,或者交给数据库分库分表中间件来实现,也可以将数据全量存储到ES中去,通过ES进行查询。

跨库跨表的排序问题:分库分表以后,数据分散存储到不同的数据库和表中,如果需要对数据列表进行排序时,就变得异常复杂。

  • 解决方式,可以通过业务代码或者数据库分库分表中间件分别查询每个子表中的数据,然后汇总进行排序,也可以将数据全量存储到ES中去,通过ES进行查询。

跨库跨表COUNT查询的问题:分库分表以后,数据分散存储到不同的数据库和表中,如果需要对表进行COUNT查询就会很复杂。

  • 解决方式,我们可以将计数的数据单独存储在一张表里,或者将聚合查询的数据同步到ES中,交给ES进行查询。
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...