Practical experience: MySQL master master mode + Keepalived achieve high availability

I have nothing to do today, and plan to build a MySQL high-availability architecture, using the main structure of MySQL, plus Keepalived, to provide a unified external virtual IP. Let’s talk about the background first. For high availability, current projects avoid the existence of a single node. For example, our application deploys multiple nodes and uses Nginx for load balancing. A node has a problem, and Will not affect the overall application. So how does the database layer build a highly available architecture? Today we will take a look.

Overall structure

MySQL adopts the main main structure, we use two machines is enough, and then install Keepalived on these two machines, using vrrp technology, virtual out an IP. The two machines are as follows:

  • 192.168.73.141:MySQL(主1)、Keepalived(MASTER)
  • 192.168.73.142:MySQL(主2)、Keepalived(BACKUP)
  • 192.168.73.150: virtual IP

The overall architecture diagram is as follows:

 

MySQL master build

We install MySQL on two machines respectively, using yum method to install, first download the rpm package from the MySQL official website, select the corresponding system, here, we choose the prm package of CentOS7, mysql80-community-release-el7-3.noarch. rpm. Then upload the rpm files to the two machines, and then we will use yum to install MySQL.

Execute the following command at 192.168.73.141 (main 1),

# 使用yum安装rpm包
yum install mysql80-community-release-el7-3.noarch.rpm

# 安装MySQL社区版 时间较长 耐心等待
yum install mysql-community-server

#启动MySQL服务
service mysqld start

At this point, MySQL is installed and started normally. Then, we log in to MySQL with the root account and create an available account.

# 从MySQL的日志中 找到root账号的临时密码
grep 'temporary password' /var/log/mysqld.log

# 使用root账号登录 输入临时密码 登录成功
mysql -uroot -p

# 修改root账号的密码 使用MYSQL_NATIVE_PASSWORD的加密方式 这种方式大多数客户端都可以连接
ALTER USER 'root'@'localhost' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'MyNewPass4!';

# 创建MySQL账号
CREATE USER 'USER'@'%' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'USER_PWD';
# 对USER账号授权
GRANT ALL ON *.* TO 'USER'@'%';
# 刷新权限
FLUSH PRIVILEGES;

Well, here, MySQL is successfully installed on 192.168.73.141, and the USER account is created, we can use NAVICAT and other clients to connect.

Execute the above command on 192.168.73.142 (Master 2) , so that we have installed MySQL on both machines. Next, we have to configure the main structure of MySQL.

First, we modify the my.cnf file on 192.168.73.141 (main 1).

vim /etc/my.cnf


datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# 配置server-id 每个MySQL实例的server-id都不能相同
server-id=1
# MySQL的日志文件的名字
log-bin=mysql_master
# 作为从库时 更新操作是否写入日志 on:写入  其他数据库以此数据库做主库时才能进行同步
log-slave-updates=on

# MySQL系统库的数据不需要同步 我们这里写了3个  更加保险
# 同步数据时忽略一下数据库 但是必须在使用use db的情况下才会忽略;如果没有使用use db 比如create user  数据还是会同步的
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
# 使用通配符忽略MySQL系统库的表  这样在create user时也不会进行同步了
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=performance_schema.%
replicate_wild_ignore_table=sys.%
# MySQL系统库的日志不计入binlog 这样更加保险了
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

Also modify the my.cnf file on 192.168.73.142 (main 2), we copy it directly, and only need to modify two of them, as follows:

# 配置server-id=2
server-id=2
# MySQL的日志文件的名字 不改名字也可以 这里主要为了区分
log-bin=mysql_slave

The configuration files have been modified, we restart the MySQL service on 192.168.73.141 (main 1) and 192.168.73.142 (main 2),

service mysqld restart

Next, we will configure the master-slave. In fact, the master-master mode is to configure two master-slaves. First configure the master-slave of 192.168.73.141 (master 1) -> 192.168.73.142 (master 2), and then configure 192.168.73.142 in reverse. (Master 2) -> 192.168.73.141 (Master 1) master-slave, so the master-master mode is configured.

Let's first configure the master-slave of 192.168.73.141 (master 1) -> 192.168.73.142 (master 2)

First log in to the database of 192.168.73.141 (main 1), and execute the following commands:

# 创建备份的账号 使用MYSQL_NATIVE_PASSWORD的方式加密
mysql> CREATE USER 'repl_master'@'%' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'password';
# 对repl_master授予备份的权限
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_master'@'%';
# 刷新权限
mysql> FLUSH PRIVILEGES;

# 查看MySQL主节点的状态
mysql> SHOW MASTER STATUS;

+-------------------+---------+--------------+---------------------------------------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB                             | Executed_Gtid_Set |
+-------------------+---------+--------------+---------------------------------------------+------------------+
| mysql_master.000001 |     516 |              | information_schema,mysql,performance_schema,sys |                  |
+-------------------+---------+--------------+---------------------------------------------+------------------+
1 row in set

We have to remember the name of the binlog file, which is mysql_master.000001, and the location, which is 516.

Then, we log in to the database of 192.168.73.142 (main 2) and execute the following command:

mysql> CHANGE MASTER TO
		   # MySQL主的IP
    ->     MASTER_HOST='192.168.73.141',
           # MySQL主的端口
    ->     MASTER_PORT=3306
           # MySQL主的备份账号
    ->     MASTER_USER='repl_master',
           # MySQL主的备份账号密码
    ->     MASTER_PASSWORD='password',
           # 日志文件 通过show master status得到的
    ->     MASTER_LOG_FILE='mysql_master.000001',
           # 日志文件位置 通过show master status得到的
    ->     MASTER_LOG_POS=516;
    
# 开启从库
mysql> START SLAVE;
# 查看从库的状态
mysql> SHOW SLAVE STATUS;

In this way, the master-slave of 192.168.73.141 (master 1) -> 192.168.73.142 (master 2) is built. Then, we turn it around and build a master-slave of 192.168.73.142 (master 2) -> 192.168.73.141 (master 1) .

First log in to the database of 192.168.73.142 (main 2) and execute the following command:

# 创建备份的账号 使用MYSQL_NATIVE_PASSWORD的方式加密
mysql> CREATE USER 'repl_slave'@'%' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'password';
# 对repl_slave授予备份的权限
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_slave'@'%';
# 刷新权限
mysql> FLUSH PRIVILEGES;

# 查看MySQL主节点的状态
mysql> SHOW MASTER STATUS;

+-------------------+---------+--------------+---------------------------------------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB                             | Executed_Gtid_Set |
+-------------------+---------+--------------+---------------------------------------------+------------------+
| mysql_slave.000001 |     379 |              | information_schema,mysql,performance_schema,sys |                  |
+-------------------+---------+--------------+---------------------------------------------+------------------+
1 row in set

Log in to the database of 192.168.73.141 (main 1) and execute the following command:

mysql> CHANGE MASTER TO
		   # MySQL主的IP
    ->     MASTER_HOST='192.168.73.142',
           # MySQL主的端口
    ->     MASTER_PORT=3306
           # MySQL主的备份账号
    ->     MASTER_USER='repl_slave',
           # MySQL主的备份账号密码
    ->     MASTER_PASSWORD='password',
           # 日志文件 通过show master status得到的
    ->     MASTER_LOG_FILE='mysql_slave.000001',
           # 日志文件位置 通过show master status得到的
    ->     MASTER_LOG_POS=379;
    
# 开启从库
mysql> START SLAVE;
# 查看从库的状态
mysql> SHOW SLAVE STATUS;

In this way, the master-slave of 192.168.73.142 (master 2)->192.168.73.141 (master 1) is also set up. We can use Navicat to connect to 192.168.73.141 (main 1) and 192.168.73.142 (main 2) respectively, and execute table building and insert statements to verify whether the master-master synchronization is successful. I won't demonstrate it here.

Keepalived high availability

The MySQL master structure has been built, no matter which MySQL data is inserted from, it will be synchronized to another MySQL. Although there is a main structure of MySQL, high availability cannot be guaranteed. For example, our application is connected to 192.168.73.141 (main 1). If MySQL of 192.168.73.141 (main 1) fails, our application does not Can not automatically switch to 192.168.73.142 (main 2), our application is also unavailable. To do this, it is necessary to resort to Keepalived.

Keepalived has two main functions:

  • Provide virtual IP to realize dual-system hot backup
  • Realize load balancing through LVS

We use Keepalived here, and only need to use one of the functions to provide virtual IP to achieve dual-system hot backup. We need to install Keepalived on both 192.168.73.141 (main 1) and 192.168.73.142 (main 2), execute the command as follows:

yum install keepalived

We directly use yum to install. After installation, edit the configuration file of keepalived, first edit the configuration file on 192.168.73.141 (main 1), as follows:

vim /etc/keepalived/keepalived.conf

# 全局配置 不用动  只需注释掉vrrp_strict
global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #必须注释掉 否则报错
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

# 检查mysql服务是否存活的脚本
vrrp_script chk_mysql {
    script "/usr/bin/killall -0 mysqld"
}
# vrrp配置虚IP
vrrp_instance VI_1 {
    # 状态:MASTER  另外一台机器为BACKUP
    state MASTER
    # 绑定的网卡
    interface ens33
    # 虚拟路由id  两台机器需保持一致
    virtual_router_id 51
    # 优先级 MASTER的值要大于BACKUP
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    # 虚拟IP地址 两台keepalived需要一致
    virtual_ipaddress {
        192.168.73.150
    }
    # 检查脚本 vrrp_script的名字
    track_script {
        chk_mysql
    }
}

###后边的virtual_server全部注释掉 它是和LVS做负载均衡用的  这里用不到
###

Then edit the configuration file on 192.168.73.142 (main 2), just change the state MASTER to state BACKUP, as follows:

state BACKUP

Through the configuration of keepalived, we provide the IP of 192.168.73.150, which actually points to 192.168.73.141 (master 1) because its state is MASTER. When keepalived detects that MySQL on 192.168.73.141 (primary 1) is unavailable, it will automatically switch to 192.168.73.142 (primary 2). It is unaware of external users, because the external unified use is 192.168.73.150.

Let's take a look at the detected script /usr/bin/killall -0 mysqld. The killall command is not built in the system and needs to be installed. We still use yum to install it, as follows:

# 先查询一下killall
yum search killall

#找到了psmisc.x86_64
Loading mirror speeds from cached hostfile
===============Matched: killall ================================
psmisc.x86_64 : Utilities for managing processes on your system

# 安装psmisc
yum install psmisc

So we can use the killall command. killall -0 is not to kill the process, but to check whether the process exists, if it exists, it returns 0, if it does not exist, it returns 1. When it returns 1, keepalived will switch between active and standby states.

Ok, killall is also introduced, we start keepalived on two machines, as follows:

# 启动keepalived
service keepalived start

Then, we check whether the IP has 192.168.73.150 on 192.168.73.141 (main 1), as follows:

ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:57:8c:cd brd ff:ff:ff:ff:ff:ff
    inet 192.168.73.141/24 brd 192.168.73.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.73.150/32 scope global ens33  # 我们看到了192.168.73.150
       valid_lft forever preferred_lft forever
    inet6 fe80::720b:92b0:7f78:57ed/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

At this point, the configuration of keepalived is complete. We connect to 192.168.73.150 through Navicat, and we can connect to the database normally. In fact, it connects to the database of 192.168.73.141, and we operate the database normally.

Then, we stop the MySQL service on 192.168.73.141 (master 1),

service mysqld stop

# 再用 ip addr查看一下
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:57:8c:cd brd ff:ff:ff:ff:ff:ff
    inet 192.168.73.141/24 brd 192.168.73.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::720b:92b0:7f78:57ed/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

The IP of 192.168.73.150 can't be found, let's go to 192.168.73.142 (main 2) to check, we can find the IP of 192.168.73.150. We operate the database on Navicat and it can be used normally. But at this time, the actual connection is the database of 192.168.73.142 (main 2). We are unaware. If we restart the mysql service on 192.168.73.141 (main 1), 192.168.73.150 will also switch to 192.168.73.141 (main 1).

to sum up

We have realized the high availability of MySQL through the MySQL master main structure + keepalived dual machine hot standby. Our application can connect to the virtual IP. The actual MySQL connected to the specific connection does not need us to care. If we do read and write separation again, we can use MySQL (master 2) as the master to configure the master-slave relationship of the database. At this time, the virtual IP is connected to MySQL (master 1), MySQL (master 1) synchronizes the data to MySQL (master 2), and then MySQL (master 2) synchronizes the data to other slave databases. If MySQL (master 1) fails, the virtual IP points to MySQL (master 2), and MySQL (master 2) will synchronize the data to other slave databases.

Author: Cattle ninth day

Original link: https://www.cnblogs.com/boboooo/p/13891447.html

If you think this article is helpful to you, you can forward it and follow it for support

Guess you like

Origin blog.csdn.net/weixin_50205273/article/details/109336396