什么是高可用架构
“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。
什么原因造成系统的不可用
- 严重的主从延迟
- 主从复制中断
- 锁引起的大量阻塞
- 软硬件鼓掌造成的服务器宕机等
正常可用时间和全年时间百分比表示高可用的程度
如果要达到9.99999的高可用:(3652460)*(1-0.99999) = 5.256 即,全年最多有5分钟不可用
如何实现高可用
- 应该尽量避免系统不可用的因素,减少系统不可用的时间,如果导致不可用的原因(服务器磁盘空间消尽,性能糟糕的SQL,表结构和索引没有优化,主从数据不一致,人为的操作失误等)
- 建立完善的监控以及报警系统
- 对备份数据进行恢复测试
- 正确配置数据库环境
- 对不需要的数据进行归档和清理
- 增加系统冗余,保证系统不可用时可以尽快恢复
- 避免存在单点故障
- 主从切换以及故障转移
如何解决单点故障
单点故障是指在一个系统中提供相同的功能的组件只用一个,如果这个组件失败了,就会影响功能的正常使用。组成应用系统的各个组件都可能成为单点。
利用SUN共享存储或者DRDB磁盘复制解决MySQL单点故障
- 共享存储:
优点
- 可以避免除存储外的任何组件失效所引起的数据丢失,同时也可以解决非存储组件的单点问题
缺点
- 共享存储本身就是一个单点,共享存储成为单点恢复需要更长的时间
- 共享存储对于随机I/O性能并不理想
所以共享存储并不是一种好的解决单点故障的方式
- DRDB磁盘镜像
优势
- 通过网卡将主服务器的每一个块复制到另外一个服务器的块设备上,并且在主设备提交之前就会被资助下来,当主设备失效时,可以把备用设备提升为主设备,从而实现故障转移的方式
- DRDB对存储做了镜像,而不是共享存储。当使用DRDB时会获得一份相同的复制数据,使用DRDB时数据时有冗余的,所以存储和数据本身都不会存在单点问题
缺点
- 故障转移时所需时间长
- 备用服务器处理被动模式而不能对外提供任何服务(包括读服务),所以成本比较高
- 如果由于磁盘本身的问题造成的磁盘文件损坏,同时DRDB的主备文件都会被损坏
所以DRDB也不是一种理想的解决反感
利用多写集群或NDB集群来解决MySQL单点故障,比如percona->pxc
优点
- 集群中所有的服务器都是同步的,不存在数据延迟问题
- 集群中的任一一台服务器损坏都不会造成单点问题
缺点
- 性能取决于集群中性能最差的一台
- 就算集群中服务器性能都是一样的,mysql写入性能也比单台服务器性能要差
- 只支持Innodb存储引擎
利用MySQL主从复制来解决MySQL单点故障
参考: https://blog.youkuaiyun.com/Code_Pupil/article/details/89377400
** 但是这需要解决如下几个问题**
- 主服务器切换后如何通知应用新的主服务器的IP地址
- 如何检查MySQL主服务器是否可用
- 如何处理从服务器和新主服务器之间的那种复制关系
MMM架构介绍
MMM(Multi-Master Replication Manager)是MySQL多主复制管理器的简称,主要作用是监控和管理MySQL的主主复制拓扑,并在当前的主从服务器失效时,进行主和主备服务器之间的主从切换和故障转移等工作。
MMM提供了什么功能
- MMM监控MySQL主从复制健康情况
- 在主库出现宕机时进行故障转移并自动配置其他从对新主进行复制
- 提供了主,写虚拟IP,在主从服务器出现问题时可以自动迁移虚拟IP
MMM架构
MMM部署所需要的资源
MMM架构实例演示
MMM是基于MYSQL主主复制拓扑的
MMM部署步骤
- 配置主主复制以及主从同步集群
- 安装主从节点所需要的支持包
- 安装以及配置MMM工具集
- 运行MMM监控服务
- 测试
MMM拓扑图
配置IP地址
- 查看网卡信息
$ 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
- 进入配置文件目录
$ cd /etc/sysconfig/network-scripts
- 拷贝配置文件
#ifcfg-<网卡名>:<IP地址编号>
$ cp ifcfg-eth1 ifcfg-eth1:1
- 编辑配置文件
$ vi ifcfg-eth1:1
#主要修改的是设备号和IP地址
IPADDR=192.168.33.201#IP地址
DEVICE=eth1:1#设备号
- 启用网卡
$ ifup eth1:1
- 测试
$ ip addr show
$ ping 192.168.33.201
数据库配置
数据库配置参考: https://blog.youkuaiyun.com/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.youkuaiyun.com/linuxlsq/article/details/52606255
MHA架构优缺点
优点
- 同样是由perl语言开发的开源工具
- 可以支持GTID的复制模式
- MHA在进行故障转移时更不容易产生数据丢失
- 同一个监控节点可以监控多个集群
缺点
- 需要编写脚本或利用第三方工具来实现VIP的配置
- MHA启动后只会对主数据库进行监控
- 需要基于SSH免认证配置,存在一定的安全隐患
- 没有提供从服务器的读写负载均衡的功能
参考文章
https://github.com/caojx-git/learn/blob/master/notes/mysql/打造扛得住的MySQL.md