MySQL-mmm是Multi-Master Replication Manager For MySQL的缩写,该软件是为MySQL数据库实现主主复制功能而实现的一系列脚本。
MySQL-mmm的功用:
可以实现MySQL数据库的高可用效果,当主数据库出现故障后,会自动切换其他主服务器,保证业务不会中断,也能对主从数据库服务器实现读负载均衡,在具体的实现细节中,它可以实现一组基于复制的虚拟IP,还能有对数据备份、节点之间重新同步的功能。
MySQL-mmm的使用场景:
用户的读写请求已经完成了读写分离,无论是前端的应用程序层面解决还是使用了MySQL语句路由,到达数据库时,读写分离的工作已经完成,MySQL-MMM主要完成的是数据库节点间工作状态的监控及资源的流转操作。
MySQL-mmm运行的进程:
mysql-mmm是一组脚本套件,其安装套件中有mysql-mmm-monitor、mysql-mmm-tools、mysql-mmm-agent、mysql-mmm四部分。
monitor程序包安装后启动的服务用于监控在common配置文件中定义的数据库工作状况,通常我们使用的数据库主服务器中有一个节点是允许写入数据,其他的节点只能读取数据,如果主服务器故障,监控程序会通知另外的服务器端启动主服务器端原有的资源,并代替之前的主服务器的工作,更多的是接替了主服务器的写入的任务。
mysql-agent程序包是安装在各个数据库节点上的代理程序,其主要功用在于当其他节点尤其是主节点出现故障后,其可以收到mysql-monitor进程的信息,并根据自身的配置自动修改其工作特性,比如提升自己为主服务器,接收写请求,或者是修改主服务器指向等。
实例:使用MySQL-mmm实现双主模型的数据库的高可用
使用三台虚拟机:node1为主服务器,接收用户的写操作,IP:172.16.103.2
node2为备用主服务器,接收用户的读请求,IP:172.16.103.3
monitor主机为监控用服务器,其IP:172.16.103.1
两个主服务器使用的VIP地址为:172.16.103.200(接收写请求的IP)、172.16.103.201、172.16.103.202(后两个IP接收读请求)
实验用简易拓扑:
一、准备工作:
配置好/etc/hosts文件,注意配置好hosts文件很关键,因为连接数据库服务器默认使用的是第一个与IP地址匹配的主机名,这个名称要和授权的IP地址反解出来的主机名保持一致,否则就会出现无法连接或者无法写入的错误,示例:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.103.1 monitor monitor.cluster.com 172.16.103.2 node1 node1.cluster.com 172.16.103.3 node2 node2.cluster.com 172.16.0.1 server.magelinux.com server
注意:简短的主机名放在了完整主机名的前面比如172.16.103.1 monitor monitor.cluster.com而不是习惯性的172.16.103.1 monitor.cluster.com monitor,因为在后续的配置mmm的过程中都是使用的简短的主机名,而我们在连接数据库建立授权账号的时候又往往使用的是IP地址,这些解析的对应关系一定要弄清楚,数据库只解析第一个匹配到的主机名,注意在这里是只解析前面的简短的主机名,我的意思是在解析172.16.103.1时数据库会只解析node1而不会去解析node1.cluster.com,如果完整的主机名放在了前面,那么后续在解析时是会出问题的,也即无法连接数据库去执行写操作。如果觉得这样的配置很繁琐,就在数据库的配置文件中mysqld字段添加skip-name-resolve一行就可以避免这些问题了。
二、在两台虚拟机上安装数据库,安装过程未给出,请参考前面博客内容,直接给出数据库的配置文件:
1、node1:(也只列出了需要添加或者需要留意的条目)
datadir = /mydata/data auto-increment-increment = 2 auto-increment-offset = 2 relay-log=mysql-relay relay-log-index=mysql-relay.index log-bin=mysql-bin binlog_format=mixed server-id = 1
由于两个数据库服务器是主主模型,都要从对方复制数据,所以都要开启中继日志和二进制日志,而且为了避免数据出现讹误,记录数据时使用不同的ID,偏移位置是不同的,而且要注意服务器的ID号一定是不同的。
2、node2:
datadir = /mydata/data auto-increment-increment = 2 auto-increment-offset = 1 relay-log=mysql-relay relay-log-index=mysql-relay.index log-bin=mysql-bin server-id = 2
3、连接node1数据库,创建授权账号,由于两个数据库节点之间是复制数据的,所以可以在一个数据库上执行授权操作,另一个数据库只需要在指向主服务器时,指向的记录位置在创建账号之前就可以了。
MariaDB [(none)]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 245 | | | +------------------+----------+--------------+------------------+
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO repl@'172.16.%.%' IDENTIFIED BY 'repl'; MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'mmm_monitor'@'172.16.%.%' IDENTIFIED BY 'mmm_monitor'; MariaDB [(none)]> GRANT PROCESS,SUPER,REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'mmm_agent'@'172.16.%.%' IDENTIFIED BY 'mmm_agent'
4、连接node2数据库:执行CHANGE MASTER TO操作,要注意指向的数据库文件及pos!
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.16.103.2',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=245; MariaDB [(none)]> START SLAVE; MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.103.2 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 960 Relay_Log_File: mysql-relay.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 960 Relay_Log_Space: 819 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 1 row in set (0.00 sec)
之后,查看一下node2的Pos及二进制日志文件,以便在node1上指向到node2:
MariaDB [(none)]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 880 | | | +------------------+---------
在node1上执行操作:
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.16.103.3',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=880; MariaDB [(none)]> START SLAVE; MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.103.3 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 880 Relay_Log_File: mysql-relay.000002 Relay_Log_Pos: 529 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 880 Relay_Log_Space: 819 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2
双主的数据库配置完成。
三、在三台主机上安装mysql-mmm的程序包:
# yum install -y mysql-mmm*
1、在node1上配置:
[root@node1 ~]# cd /etc/mysql-mmm/ [root@node1 mysql-mmm]# vim mmm_agent.conf
在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 node1
编辑node1上的mmm_common.conf文件,配置内容为:
active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mysql-mmm/mmm_agentd.pid bin_path /usr/libexec/mysql-mmm/ replication_user repl replication_password repl agent_user mmm_agent agent_password mmm_agent </host> <host node1> ip 172.16.103.2 mode master peer node2 </host> <host node2> ip 172.16.103.3 mode master peer node1 </host> <host monitor> ip 172.16.103.1 mode slave </host> <role writer> hosts node1, node2 ips 172.16.103.200 mode exclusive </role> <role reader> hosts node1, node2 ips 172.16.103.201, 172.16.103.202 mode balanced </role>
mmm_common.conf文件在各个节点上内容相同,复制到其他的节点上去即可:
# scp mmm_common.conf monitor:/etc/mysql-mmm/ # scp mmm_common.conf node2:/etc/mysql-mmm/
2、在node2上编辑配置文件,内容如下:
[root@node2 mysql-mmm]# vim /etc/mysql-mmm/mmm_agent.conf include mmm_common.conf this node2
3、在监控节点上配置
mmm_agent.conf内容为:
[root@monitor mysql-mmm]# vim mmm_agent.conf include mmm_common.conf this monitor
include mmm_common.conf <monitor> ip 127.0.0.1 pid_path /var/run/mysql-mmm/mmm_mond.pid bin_path /usr/libexec/mysql-mmm status_path /var/lib/mysql-mmm/mmm_mond.status ping_ips 172.16.103.2,172.16.103.3 #这里配置的是监控用的IP地址,但不要设置本机的IP地址,其用途是是探测本机与外部通信的 auto_set_online 10 #这个参数的默认值是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 mmm_monitor </host> debug 0
至此两台数据库服务器主机以及在三台节点上配置mmm的过程完毕,现在可以启动数据库及mmm服务了。
# service mysqld start
node1和node2上:
# service mysql-mmm-agent start
monitor上:
# service mysql-mmm-monitor start
在全部启动完毕后,监控端可以查看到各数据库的工作状态,使用mmm_control命令查看:
[root@monitor mysql-mmm]# mmm_control show # Warning: agent on host monitor is not reachable monitor(172.16.103.1) slave/HARD_OFFLINE. Roles: node1(172.16.103.2) master/ONLINE. Roles: reader(172.16.103.201), writer(172.16.103.200) node2(172.16.103.3) master/ONLINE. Roles: reader(172.16.103.202)
在node1上查看IP地址的配置情况:
[root@node1 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:e1:37:51 brd ff:ff:ff:ff:ff:ff inet 172.16.103.2/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.201/32 scope global eth0 inet 172.16.103.200/32 scope global eth0 inet6 fe80::20c:29ff:fee1:3751/64 scope link valid_lft forever preferred_lft forever
在node2上启动的IP为:
[root@node2 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cf:64:8f brd ff:ff:ff:ff:ff:ff inet 172.16.103.3/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.202/32 scope global eth0 inet6 fe80::20c:29ff:fecf:648f/64 scope link valid_lft forever preferred_lft forever
如果服务器故障了,所有配置在主服务器上的VIP都会流转到另一个主服务器上:
[root@node2 mysql-mmm]# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:cf:64:8f brd ff:ff:ff:ff:ff:ff inet 172.16.103.3/16 brd 172.16.255.255 scope global eth0 inet 172.16.103.202/32 scope global eth0 inet 172.16.103.201/32 scope global eth0 inet 172.16.103.200/32 scope global eth0 inet6 fe80::20c:29ff:fecf:648f/64 scope link valid_lft forever preferred_lft forever
可以看到VIP 200,201,202都配置在了node2上。