mysql之复制,扩展,高可用相关知识

154 阅读4分钟

复制

mysql的复制是实现扩展性和高可用性的前提。

复制的过程:

  1. master将提交的事物写入binlog中;
  2. slave的IO thread将master的binlog读取到自己的relay log中(中继日志);
  3. slave的SQL thread将自己relay log中的日志重放到自己的库中。

复制的操作命令:

  1. change master to  给slave设置master
  2. start slave   开始复制

binlog的三种格式:

  • statement   直接将执行的sql语句记录下来
  • row   将数据的变化记录下来
  • mixed   采用上边两种的混合格式,对于不能采用statement的才执行row的格式。

缺点:

statement:部分语句在slave上重放时可能会导致主从不一致。比如带limit的delete语句。

row:产生的数据量比较大,比如delete * from table; 如果删除了10000条记录,则会全部记录下来。

一般我们会采用mixed和row两种方式。statement有不一致的风险。

复制延迟(主从延迟)

复制延迟指的是从A事务在master提交开始,到A事务在slave提交结束这个过程经历的时间。包含两个阶段:slave的IO复制,slave的SQL重放。

查看主从延迟的方法:在slave上执行show slave status命令,查看seconds_behind_master. 原理是master记录binlog时会将该事务执行的时间记录下来,slave重放时,比较当前时间与之前执行事务时间的差值。

出现主从延迟的常见原因:

  • 从库性能差(机器本身差或者机器上有多个从库竞争)
  • 从库压力大  读请求都在从库上,导致从库压力大
  • 大事务  由于事务比较大,master在事务提交后开始写binlog,后边从库的IO thread 和 SQL thread都需要追赶。
  • 大表DDL 类似于大事务

主从延迟产生的问题:

如果采用了读写分离的方式,由于存在延迟,某事务已经在master提交,但是还没有在slave提交,会导致读到的数据(slave)是过期数据(相对于master),我们称为过期读。

过期读的解决方案:

  • 在业务上将查询分为两类,一类绝对不允许过期读,一类允许过期读,不允许的查询走master,允许的查询走slave。
  • 延迟读  每次读都稍微延迟一定时间,然后再读slave,同时要保证主从延迟时间要小于应用查询时的主动延迟时间。
  • 判断slave当前是否过期,如果过期走master或者延迟读,如果不过期走slave。可以通过seconds_behind_master等方式来判断。

扩展

常见的扩展类型可以分为三类:

  • 垂直扩展
  • 水平扩展

水平扩展又包含以下几类:

  • 复制    读写分离,读可以扩展
  • 拆分    按功能将不同的表放到不同的库上
  • 数据分片     将同一张表的数据按记录进行分片

一般在数据量不断变大的情况下,我们会采用数据分片的方案。数据分片要有一个sharding-key。根据sharding-key将记录放到正确的表上。

常见的分配方式:

  • 固定分配: 采用hash取模的方式,将数据按照固定不变的逻辑分配
  • 动态分配:另外维护一张表,记录具体的数据分配规则
  • 类似于redis的槽的方式

优缺点:

固定分配比较简单,但是容易出现数据分布不均匀;

动态分配方案比较复杂,但是比较灵活,可以自定义数据分布方式;

槽的方式,首先将数据hash到很多槽上,然后对槽进行指定分配,可以解决数据分布不均匀的问题。同时,不会像完全的动态分配方案一样,需要维护过多的数据指定关系。

高可用

mysql的高可用一般是当master节点挂掉后,执行故障转移,将其slave升级为master,将后续的流量打到新的master上。

一般有两种策略:

可靠性优先策略

当master挂掉后,等待slave追赶,知道slave没有延迟,将slave切换为master。这样可以保证数据的可靠性。不会出现新的master上同时处理relay log和线上请求,使得数据不一致的情况发生。

缺点:由于要等待slave重放完全部的relay log才能升级为master,因此会导致可用性上有一些缺失。

解决方案:可以通过保证slave的延迟时间始终保持在一个较低的水平来降低等待时间,在保证可靠性的基础上保证可用性。

可用性优先策略

master一旦挂掉,立即将slave切换为master,而不等待重放完全部的relay log。

缺点:由于slave立即切换为master,如果relay log没有重放完,有一些事务没有提交。此时去处理新来的请求,会导致出现与原先不一致的情况。同时,原先已经提交的事务也丢失了。