【mysql-4】mysql集群架构-理论

一:主从模式

1、主从复制:

【mysql-4】mysql集群架构-理论_第1张图片

步骤:

  • master记录写操作到Binlog日志(masterBinlogDump Thread接收到写操作后,会读取binlog信息推送给slave的I/O Thread
  • slave读取主的Binlog并写入信息到自己的Relay log中继日志(I/O Thread接收到推送过来的binlog信息,写入到本地Relay log)
  • slave读取中继日志更新数据SQL Thread检测到Relay log变更请求,解析内容并在执行更新

以上过程是异步,所以称为异步复制,时序图如下:

【mysql-4】mysql集群架构-理论_第2张图片

异步复制存在问题:

  • 数据丢失风险:master写入binlog后,采用异步线程推送,然后继续commit,完全不关心slave是否成功接收。
  • 从库只有一个sql thread,如果master并发较高,从库的单线程复制很可能延时。

解决办法:

  • 半同步复制-解决数据丢失: master 推送binlog信息给slave后,等待slave成功写入relay log并返回ack信息,再执行commit
  • 并行复制-解决复制延迟: 在从库使用多个sql thread同时执行
    • 5.6中是基于库的并行,如果slave中只有一个库,或者所有的并发操作都在一个库,便没有意义
    • 5.7中基于组的并行复制,真正实现了并行复制
      • 原理: 在binlog中将不冲突的多个事务划分到一组,slave会将同一组中的多个事务,使用多线程执行
      • 写入binlog时如何知道哪些事务不冲突:innodb提交事务分为prepare和commit阶段:
        • prepare阶段会生成redo并刷盘,这时候,已经解析出哪些事务会有冲突。
        • commit阶段将sql语句写入binlog,没有冲突的事务分到同一组,然后binlog刷盘,执行commit,将redo log中标记为commit。  自然,分到同一组的事务在slave上便可以使用多线程同步执行。
      • binlog中组信息用什么记录呢:使用GTID记录,包含:
        • last_committed 编号 :同一组中的事务 ,此编号相同
        • sequence_number编号 : 事务编号
        • 【mysql-4】mysql集群架构-理论_第3张图片

 

二:MMM和MHA架构

传统主从模式下,如果master宕机,集群不可用。 我们需要有备用master,目前有两种实现方式:

MMM架构:

【mysql-4】mysql集群架构-理论_第4张图片

如图示,在常规主从模式下,增加了一台read vip作为master备份,而write vip提供对外服务。 原理:

  1. 两个master互为主从,也是采用异步复制的方式同步数据
  2. 架构需要一个监控程序(monitor)和代理程序(agent-每台节点都要安装,用来执行monitor命令),当monitor监控write master异常,会发送命令切换master。

此架构存在问题:

  1. 需要一台master做备份,浪费资源
  2. 无法保证数据一致性:read master和slave都是异步复制,主master宕机时,并不能保证备用master比slave的数据新。 那么切换过程中,可能造成事务丢失或者多次事务提交

MHA架构:

【mysql-4】mysql集群架构-理论_第5张图片

MHA组成部分:

  • MHA Manager(管理节点): 检测master情况,控制故障转移等。
  • MHA Node(数据节点): 运行在每一台mysql上,被manager监控管理,执行具体的故障处理流程。

故障处理流程:

  • 保存宕机master的binlog
  • 根据binlog位置点找到最新的slave
  • 使用最新slave的relay log修复其他slave
  • 用保存下来的binlog在最新的slave上修复,提升其为master
  • 将其他slave指向新的master,开启新的主从复制

优势:

自动故障转移快,不存在数据不一致问题; 性能优秀,支持半同步复制和异步复制,可以同时监控多个集群。

 

三:分库分表

拆分模式:

  • 垂直拆分:
    • 垂直分库:比如把 order 和 user 拆分到不同的库,解决库内表太多的问题。
    • 垂直分表:比如order字段太多,拆分到不同的表,解决表内字段太多的问题。
  • 水平拆分: 比如order表数据量太大,拆分到不同的库不同的表,解决表内记录太多的问题。

主键策略:

分库分表后,要保证数据主键不能冲突,可以使用以下策略:

  • UUID(无序,不推荐)
  • SNOWFLAKE(雪花算法,推荐)
  • redis(推荐)

分片策略:

范围分片: 根据某个特定字段取范围,比如id为1-100的分到A,101-200的分到B。 

  • 优点:数据均匀分布在mysql各节点,扩容时数据不需要迁移。
  • 缺点:如果数据有冷热情况,则会冷热分布不均,造成节点负荷不均。

hash取模: 根据特定字段的hash值对节点数取模。 

  • 优点:数据均匀分布在mysql各节点。
  • 缺点:也存在冷热分布不均的问题;  另外,如果扩容或者缩容,会造成hash值变动,需要重新分配和迁移数据。

一致性hash: 其实就是hash环取模,弥补普通hash在扩容或者缩容时候的问题。 不过,也存在冷热分布不均的问题。

 

综上: 选用哪种策略分库分表,要根据实际的业务场景来决定。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(mysql,mysql)