MySQL高可用架构设计

什么是高可用架构


“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。

什么原因造成系统的不可用

  1. 严重的主从延迟
  2. 主从复制中断
  3. 锁引起的大量阻塞
  4. 软硬件鼓掌造成的服务器宕机等

正常可用时间和全年时间百分比表示高可用的程度
如果要达到9.99999的高可用:(3652460)*(1-0.99999) = 5.256 即,全年最多有5分钟不可用

如何实现高可用

  1. 应该尽量避免系统不可用的因素,减少系统不可用的时间,如果导致不可用的原因(服务器磁盘空间消尽,性能糟糕的SQL,表结构和索引没有优化,主从数据不一致,人为的操作失误等)
  2. 建立完善的监控以及报警系统
  3. 对备份数据进行恢复测试
  4. 正确配置数据库环境
  5. 对不需要的数据进行归档和清理
  6. 增加系统冗余,保证系统不可用时可以尽快恢复
  7. 避免存在单点故障
  8. 主从切换以及故障转移

如何解决单点故障


单点故障是指在一个系统中提供相同的功能的组件只用一个,如果这个组件失败了,就会影响功能的正常使用。组成应用系统的各个组件都可能成为单点。

利用SUN共享存储或者DRDB磁盘复制解决MySQL单点故障

  1. 共享存储:
    在这里插入图片描述

优点

  • 可以避免除存储外的任何组件失效所引起的数据丢失,同时也可以解决非存储组件的单点问题

缺点

  • 共享存储本身就是一个单点,共享存储成为单点恢复需要更长的时间
  • 共享存储对于随机I/O性能并不理想

所以共享存储并不是一种好的解决单点故障的方式

  1. DRDB磁盘镜像

在这里插入图片描述

优势

  • 通过网卡将主服务器的每一个块复制到另外一个服务器的块设备上,并且在主设备提交之前就会被资助下来,当主设备失效时,可以把备用设备提升为主设备,从而实现故障转移的方式
  • DRDB对存储做了镜像,而不是共享存储。当使用DRDB时会获得一份相同的复制数据,使用DRDB时数据时有冗余的,所以存储和数据本身都不会存在单点问题

缺点

  • 故障转移时所需时间长
  • 备用服务器处理被动模式而不能对外提供任何服务(包括读服务),所以成本比较高
  • 如果由于磁盘本身的问题造成的磁盘文件损坏,同时DRDB的主备文件都会被损坏

所以DRDB也不是一种理想的解决反感

利用多写集群或NDB集群来解决MySQL单点故障,比如percona->pxc

在这里插入图片描述

优点

  • 集群中所有的服务器都是同步的,不存在数据延迟问题
  • 集群中的任一一台服务器损坏都不会造成单点问题

缺点

  • 性能取决于集群中性能最差的一台
  • 就算集群中服务器性能都是一样的,mysql写入性能也比单台服务器性能要差
  • 只支持Innodb存储引擎
利用MySQL主从复制来解决MySQL单点故障

参考: https://blog.csdn.net/Code_Pupil/article/details/89377400

** 但是这需要解决如下几个问题**

  1. 主服务器切换后如何通知应用新的主服务器的IP地址
  2. 如何检查MySQL主服务器是否可用
  3. 如何处理从服务器和新主服务器之间的那种复制关系

MMM架构介绍


MMM(Multi-Master Replication Manager)是MySQL多主复制管理器的简称,主要作用是监控和管理MySQL的主主复制拓扑,并在当前的主从服务器失效时,进行主和主备服务器之间的主从切换和故障转移等工作。

MMM提供了什么功能

  1. MMM监控MySQL主从复制健康情况
  2. 在主库出现宕机时进行故障转移并自动配置其他从对新主进行复制
  3. 提供了主,写虚拟IP,在主从服务器出现问题时可以自动迁移虚拟IP

MMM架构
在这里插入图片描述

MMM部署所需要的资源
在这里插入图片描述

MMM架构实例演示


MMM是基于MYSQL主主复制拓扑的

MMM部署步骤

  1. 配置主主复制以及主从同步集群
  2. 安装主从节点所需要的支持包
  3. 安装以及配置MMM工具集
  4. 运行MMM监控服务
  5. 测试

MMM拓扑图
在这里插入图片描述

配置IP地址


  1. 查看网卡信息
$ ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.33.102  netmask 255.255.255.0  broadcast 192.168.33.255
        inet6 fe80::a00:27ff:feba:368b  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:ba:36:8b  txqueuelen 1000  (Ethernet)
        RX packets 232  bytes 23673 (23.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20  bytes 2162 (2.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  1. 进入配置文件目录
$ cd /etc/sysconfig/network-scripts
  1. 拷贝配置文件
#ifcfg-<网卡名>:<IP地址编号>
$ cp ifcfg-eth1 ifcfg-eth1:1
  1. 编辑配置文件
$ vi ifcfg-eth1:1

#主要修改的是设备号和IP地址
IPADDR=192.168.33.201#IP地址
DEVICE=eth1:1#设备号
  1. 启用网卡
$ ifup eth1:1
  1. 测试
$ ip addr show

$ ping 192.168.33.201

数据库配置


数据库配置参考: https://blog.csdn.net/Code_Pupil/article/details/89377400

主DB1服务器配置

#二进制日志的格式
binlog_format=row
binlog_row_image=minimal

#启用二进制日志(可自定义存放位置,需要先创建并赋予权限)
log_bin = /var/lib/mysql/sql_log/mysql_bin

#启用中继日志(可自定义存放位置)
relay_log = /var/lib/mysql/sql_log/mysql_relay_bin

#指定从服务器的服务ID,整个服务集群中式唯一的(自定义,集群中不重复即可)
server_id = 101

#可选(如果需要将从服务器作为其他服务器的主服务器时必须设置,否则不设置)
log_slave_updates = on

#控制ID的自增2
auto_increment_increment = 2

#控制ID初始值1
auto_increment_offset = 1

主DB2服务器

#二进制日志的格式
binlog_format=row
binlog_row_image=minimal

#启用二进制日志(可自定义存放位置,需要先创建并赋予权限)
log_bin = /var/lib/mysql/sql_log/mysql_bin

#启用中继日志(可自定义存放位置)
relay_log = /var/lib/mysql/sql_log/mysql_relay_bin

#指定从服务器的服务ID,整个服务集群中式唯一的(自定义,集群中不重复即可)
server_id = 102

#可选(如果需要将从服务器作为其他服务器的主服务器时必须设置,否则不设置)
log_slave_updates = on

#控制ID的自增2
auto_increment_increment = 2

#控制ID初始值2
auto_increment_offset = 2

从DB服务器

#二进制日志的格式
binlog_format=row
binlog_row_image=minimal

#启用二进制日志(可自定义存放位置,需要先创建并赋予权限)
log_bin = /var/lib/mysql/sql_log/mysql_bin

#启用中继日志(可自定义存放位置)
relay_log = /var/lib/mysql/sql_log/mysql_relay_bin

#指定从服务器的服务ID,整个服务集群中式唯一的(自定义,集群中不重复即可)
server_id = 103

#可选,建议从服务器只读
read_only = on

配置主主复制以及主从同步集群


数据库数据需要一致,提前备份初始化数据

  • 主DB1
#rep:复制用户
#mmm_monitor:监控用户。所有mysql节点进行健康检查
#mmm_agent:代理用户。切换只读模式和同步Master信息

mysql>GRANT REPLICATION SLAVE ON *.* to 'repl'@'ip' identified by '密码';

mysql>GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'ip' IDENTIFIED BY '密码';

mysql>GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'ip' IDENTIFIED BY '密码';

mysql> SHOW MASTER STATUS \G;
*************************** 1. row ***************************
             File: mysql_bin.000006
         Position: 2018
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
  • 主DB2
#rep:复制用户
#mmm_monitor:监控用户。所有mysql节点进行健康检查
#mmm_agent:代理用户。切换只读模式和同步Master信息

mysql>GRANT REPLICATION SLAVE ON *.* to 'repl'@'ip' identified by '密码';

mysql>GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'ip' IDENTIFIED BY '密码';

mysql>GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'ip' IDENTIFIED BY '密码';

mysql>CHANGE MASTER TO
	->MASTER_HOST='master_host_ip',#主DB1服务器IP
	->MASTER_USER='repl',#主DB1复制用户
	->MASTER_PASSWORD='PassWord',#主DB1复制用户密码
	->MASTER_LOG_FILE='mysql_bin.000007',#在主DB1查看日志文件
	->MASTER_LOG_POS=5856;#在主DB1查看节点

mysql>start slave;#启动复制链路
mysql>show slave status \G;#查看复制链路是否启动
*************************** 1. row ***************************
             Slave_IO_Running: Yes					#YES表示成功
            Slave_SQL_Running: Yes					#YES表示成功
                Last_IO_Errno: 0					#IO错误代码
                Last_IO_Error:						#IO错误提示
               Last_SQL_Errno: 0					#SQL错误代码
               Last_SQL_Error:						#SQL错误提示

mysql> SHOW MASTER STATUS \G;
*************************** 1. row ***************************
             File: mysql_bin.000001
         Position: 2175
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

  • 主DB1
mysql>CHANGE MASTER TO
	->MASTER_HOST='master_host_ip',#主DB2服务器IP
	->MASTER_USER='repl',#主DB2复制用户
	->MASTER_PASSWORD='PassWord',#主DB2复制用户密码
	->MASTER_LOG_FILE='mysql_bin.000007',#在主DB2查看日志文件
	->MASTER_LOG_POS=5856;#在主DB2查看节点

mysql>start slave;#启动复制链路
mysql>show slave status \G;#查看复制链路是否启动
*************************** 1. row ***************************
             Slave_IO_Running: Yes					#YES表示成功
            Slave_SQL_Running: Yes					#YES表示成功
                Last_IO_Errno: 0					#IO错误代码
                Last_IO_Error:						#IO错误提示
               Last_SQL_Errno: 0					#SQL错误代码
               Last_SQL_Error:						#SQL错误提示

mysql> SHOW MASTER STATUS \G;
*************************** 1. row ***************************
             File: mysql_bin.000006
         Position: 3401
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
  • 从DB
#mmm_monitor:监控用户。所有mysql节点进行健康检查
#mmm_agent:代理用户。切换只读模式和同步Master信息

mysql>GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'ip' IDENTIFIED BY '密码';

mysql>GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'ip' IDENTIFIED BY '密码';

mysql>CHANGE MASTER TO
	->MASTER_HOST='master_host_ip',#主DB1服务器IP
	->MASTER_USER='repl',#主DB1复制用户
	->MASTER_PASSWORD='PassWord',#主DB1复制用户密码
	->MASTER_LOG_FILE='mysql_bin.000007',#在主DB1查看日志文件
	->MASTER_LOG_POS=5856;#在主DB1查看节点

mysql>start slave;#启动复制链路
mysql>show slave status \G;#查看复制链路是否启动
*************************** 1. row ***************************
             Slave_IO_Running: Yes					#YES表示成功
            Slave_SQL_Running: Yes					#YES表示成功
                Last_IO_Errno: 0					#IO错误代码
                Last_IO_Error:						#IO错误提示
               Last_SQL_Errno: 0					#SQL错误代码
               Last_SQL_Error:						#SQL错误提示

配置MMM架构


主DB1\2、从DB配置YUM源

$ cd /usr/local/src/

$ yum -y install wget

$ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

$ wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

$ rpm -ivh epel-release-latest-7.noarch.rpm

$ rpm -ivh remi-release-7.rpm

$ vi /etc/yum.repos.d/remi.repo
[remi]
enabled=1 #改成1

$ vi /etc/yum.repos.d/epel.repo
[epel]
baseurl #注释取消
#metalink#注释镜像

$ yum search mmm
=============================== N/S matched: mmm ===============================
mysql-mmm-agent.noarch : MMM Database Server Agent Daemon and Libraries
mysql-mmm-monitor.noarch : MMM Monitor Server Daemon and Libraries
mysql-mmm-tools.noarch : MMM Control Scripts and Libraries
mysql-mmm.noarch : Multi-Master Replication Manager for MySQL

$ yum install mysql-mmm-agent.noarch -y

在监控服务器安装监控服务

$ yum -y install mysql-mmm*

MMM数据库节点配置

主DB1\2、从DB配置都要一样

$ vi /etc/mysql-mmm/mmm_common.conf

active_master_role      writer

<host default>
    cluster_interface       eth1						#网卡,ip addr查看IP所在网卡
    pid_path                /run/mysql-mmm-agent.pid
    bin_path                /usr/libexec/mysql-mmm/
    replication_user        repl						#复制用户
    replication_password    Password					#复制用户密码
    agent_user              mmm_agent					#代理用户
    agent_password          Password					#代理用户密码
</host>

<host db1>
    ip      192.168.33.101								#主DB1服务器IP
    mode    master
    peer    db2
</host>

<host db2>
    ip      192.168.33.102								#主DB2服务器IP
    mode    master
    peer    db1
</host>

<host db3>
    ip      192.168.33.103								#从DB服务器IP
    mode    slave
</host>

<role writer>
    hosts   db1, db2									#写角色db
    ips     192.168.33.201								#写角色的虚拟IP
    mode    exclusive									#独占模式,同一时刻只能有一个主
</role>

<role reader>
    hosts   db1, db2, db3								#读角色db
    ips     192.168.33.201, 192.168.33.202,192.168.33.203	#写角色的虚拟IP
    mode    balanced
</role>

修改mmm-agent配置

$ vi /etc/mysql-mmm/mmm-agent.conf

include mmm_common.conf

# The 'this' variable refers to this server.  Proper operation requires
# that 'this' server (db1 by default), as well as all other servers, have the
# proper IP addresses set in mmm_common.conf.
this db1		#只需修改这里,根据mmm_common.conf配置修改(db1|db2|db3)

配置监控服务器监控节点

$ vi /etc/mysql-mmm/mmm-mon.conf

include mmm_common.conf

<monitor>
    ip                  127.0.0.1
    pid_path            /run/mysql-mmm-monitor.pid
    bin_path            /usr/libexec/mysql-mmm
    status_path         /var/lib/mysql-mmm/mmm_mond.status
    ping_ips            192.168.33.101,192.168.33.102,192.168.33.103 #配置主DB1\2、从DB服务器IP
    auto_set_online     60

    # The kill_host_bin does not exist by default, though the monitor will
    # throw a warning about it missing.  See the section 5.10 "Kill Host
    # Functionality" in the PDF documentation.
    #
    # kill_host_bin     /usr/libexec/mysql-mmm/monitor/kill_host
    #
</monitor>

<host default>
    monitor_user        mmm_monitor		#监控用户
    monitor_password    Password		#监控用户密码
</host>

debug 0

启动三个服务器MMM集群

$ service mysql-mmm-agent start

$ service mysql-mmm-agent status

Redirecting to /bin/systemctl status mysql-mmm-agent.service
● mysql-mmm-agent.service - MySQL MMM agent
   Loaded: loaded (/usr/lib/systemd/system/mysql-mmm-agent.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2019-05-10 08:27:16 UTC; 27s ago
  Process: 7347 ExecStart=/usr/sbin/mmm_agentd (code=exited, status=0/SUCCESS)
 Main PID: 7349 (mmm_agentd)
   CGroup: /system.slice/mysql-mmm-agent.service
           ├─7349 mmm_agentd
           └─7350 mmm_agentd

May 10 08:27:16 localhost.localdomain systemd[1]: Starting MySQL MMM agent...
May 10 08:27:16 localhost.localdomain systemd[1]: PID file /run/mysql-mmm-age...
May 10 08:27:16 localhost.localdomain systemd[1]: Started MySQL MMM agent.
Hint: Some lines were ellipsized, use -l to show in full.

监控服务器启动监控服务

$ service mysql-mmm-monitor start

$ mmm_control show 查看状态

MMM架构的优点和缺点


优点

  • 使用perl脚本语言开发完全开源
  • 提供了VIP(虚拟IP),使得服务器角色的变更对前端应用透明
  • MMM提供了从服务器的延迟监控
  • MMM提供了主数据库故障转移后从服务器对新主的重新同步功能,很容易对发生故障的主数据库重新上线

缺点

  • 发布时间比较早不支持MySQL新的复制功能,(a.基于GTID的复制可以保证日志不会重复在slave服务器上备执行 b.对于MySQL5.6后所提供的多线程复制技术也不支持)
  • 没有读的负载均衡的功能
  • 在进行主从切换时,容易造成数据丢失
  • MMM监控服务存在单点故障

MHA架构介绍


MHA是一位日本MySQL大牛用Perl写一套MySQL故障切换方案,来保证数据库系统的高可用,在宕机的事件内(通常10-30秒),完成故障转意,部署MHA,可避免主从一致性问题,节约购买新服务器的费用,不影响服务器性能,易安装,不改变现有部署 参考:https://blog.csdn.net/linuxlsq/article/details/52606255

在这里插入图片描述

MHA架构优缺点


优点

  • 同样是由perl语言开发的开源工具
  • 可以支持GTID的复制模式
  • MHA在进行故障转移时更不容易产生数据丢失
  • 同一个监控节点可以监控多个集群

缺点

  • 需要编写脚本或利用第三方工具来实现VIP的配置
  • MHA启动后只会对主数据库进行监控
  • 需要基于SSH免认证配置,存在一定的安全隐患
  • 没有提供从服务器的读写负载均衡的功能

参考文章

https://github.com/caojx-git/learn/blob/master/notes/mysql/打造扛得住的MySQL.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值