MHA 高可用半同步主从复制 MYSQL 集群

 项目名称:MHA 高可用半同步主从复制 MYSQL 集群

        项目描述

简介
        模拟企业具体应用状态构建一个高可用并且高性能的MySQL集群项目,具备处理大并发的后端MySQL业务的能力。

  1. 进行四台mysql服务器的配置,安装mysql软件,并完成半同步相关插件的下载以及相关的配置
  2. 配置好ansible服务器,实现ansible和集群内部机器的双向免密通道
  3. 使用mysqldump将数据冷备至ansible服务器上,然后使用ansible服务将master数据传输至所有slave,完成集群数据统一
  4. 创建计划任务实现将master服务器的数据定时传入ansible,使ansible作为mysql集群的异地备份服务器
  5. 开启gtid服务,启动集群的主从复制,并且配置一台延时服务器slave3在slave1上获取数据,增强系统稳定性,便于出现问题时进行回档
  6. 使用MHA配置MYSQL集群的自动failover功能,从而实现集群的高可用性
  7. 启动MYSQLrouter服务,实现router服务器对于外部访问的转接,从而实现读写分离的负载均衡,提高mysql面对大并发时的处理能力
  8. 安装keepalive,通过vrrp协议实现mysqlrouter中间件的高可用
  9. 使用sysbench压力测试工具检验集群性能,确定集群系统资源的上限

项目架构图

        

项目ip规划

  • master 192.168.2.137
  • slave1 192.168.2.136
  • slave2 192.168.2.135
  • slave3 192.168.2.138
  • ansible 192.168.2.139
  • router1 192.168.2.140
  • router2 192.168.2.141
  • mha manager 192.168.2.142
  • sysbench 192.168.2.143
  • mha vip 192.168.2.200
  • keepalive vip 192.168.2.188

项目环境

  • CentOS:CentOS Linux release 7.9.2009 (Core)
  • MySQL:mysql Ver 14.14 Distrib 5.7.38, for linux-glibc2.12 (x86_64)
  • mha manager:mha4mysql-manager-0.58
  • mha node:mha4mysql-node-0.58
  • Keepalived: Keepalived v1.3.5 (03/19,2017)
  • sysbench:sysbench 1.0.17
  • Ansible:ansible 2.9.27

项目步骤

一. 进行四台mysql服务器的配置,安装mysql软件,并完成半同步相关插件的下载以及相关的配置

  1. 配置好相关环境
    [root@master ~]# ls
    install_exporter.sh  mha4mysql-node-0.58.tar.gz

    install_exporter.sh脚本如下

    [root@master ~]# cat onekey_install_mysql_binary.sh 
    #!/bin/bash
    #解决软件的依赖关系
    yum  install cmake ncurses-devel gcc  gcc-c++  vim  lsof bzip2 openssl-devel ncurses-compat-libs -y
     
    #解压mysql二进制安装包
    tar  xf  mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz
     
    #移动mysql解压后的文件到/usr/local下改名叫mysql
    #/usr/local/mysql 是mysql的安装目录--》门店
    mv mysql-5.7.38-linux-glibc2.12-x86_64 /usr/local/mysql
     
    #新建组和用户 mysql
    groupadd mysql
    #mysql这个用户的shell 是/bin/false 属于mysql组 
    useradd -r -g mysql -s /bin/false mysql
     
    #关闭firewalld防火墙服务,并且设置开机不要启动
    service firewalld stop
    systemctl  disable  firewalld
     
    #临时关闭selinux
    setenforce 0
    #永久关闭selinux
    sed -i '/^SELINUX=/ s/enforcing/disabled/'  /etc/selinux/config
     
    #新建存放数据的目录--》仓库
    mkdir  /data/mysql -p
    #修改/data/mysql目录的权限归mysql用户和mysql组所有,这样mysql用户启动mysql进程可以对这个文件夹进行读写了
    chown mysql:mysql /data/mysql/
    #只是允许mysql这个用户和mysql组可以访问,其他人都不能访问
    chmod 750 /data/mysql/
     
    #进入/usr/local/mysql/bin目录
    cd /usr/local/mysql/bin/
     
    #初始化mysql
    ./mysqld  --initialize --user=mysql --basedir=/usr/local/mysql/  --datadir=/data/mysql  &>passwd.txt
     
    #让mysql支持ssl方式登录的设置
    ./mysql_ssl_rsa_setup --datadir=/data/mysql/
     
    #获得临时密码
    tem_passwd=$(cat passwd.txt |grep "temporary"|awk '{print $NF}')
      #$NF表示最后一个字段
      # abc=$(命令)  优先执行命令,然后将结果赋值给abc 
     
    # 修改PATH变量,加入mysql bin目录的路径
    #临时修改PATH变量的值
    export PATH=/usr/local/mysql/bin/:$PATH
    #重新启动linux系统后也生效,永久修改
    echo  'PATH=/usr/local/mysql/bin:$PATH' >>/root/.bashrc
     
    #复制support-files里的mysql.server文件到/etc/init.d/目录下叫mysqld
    cp  ../support-files/mysql.server   /etc/init.d/mysqld
     
    #修改/etc/init.d/mysqld脚本文件里的datadir目录的值
    sed  -i '70c  datadir=/data/mysql'  /etc/init.d/mysqld
     
    #生成/etc/my.cnf配置文件
    cat  >/etc/my.cnf  <<EOF
    [mysqld_safe]
    [client]
    socket=/data/mysql/mysql.sock
    [mysqld]
    socket=/data/mysql/mysql.sock
    port = 3306
    open_files_limit = 8192
    innodb_buffer_pool_size = 512M
    character-set-server=utf8
    [mysql]
    auto-rehash
    prompt=\\u@\\d \\R:\\m  mysql>
    EOF
     
    #修改内核的open file的数量
    ulimit -n 1000000
    #设置开机启动的时候也配置生效
    echo "ulimit -n 1000000" >>/etc/rc.local
    chmod +x /etc/rc.d/rc.local
     
    #将mysqld添加到linux系统里服务管理名单里
    /sbin/chkconfig --add mysqld
    #设置mysqld服务开机启动
    /sbin/chkconfig mysqld on
     
    #启动mysqld进程
    service mysqld start
     
    #初次修改密码需要使用--connect-expired-password 选项
    #-e 后面接的表示是在mysql里需要执行命令  execute 执行
    #set password='123456';  修改root用户的密码为123456
    mysql -uroot -p$tem_passwd --connect-expired-password   -e  "set password='123456';"
     
     
    #检验上一步修改密码是否成功,如果有输出能看到mysql里的数据库,说明成功。
    mysql -uroot -p'123456'  -e "show databases;"

    在其余的slave机器上也重复进行操作即可

  2. 配置/etc/my.cnf文件
    [mysqld_safe]
    
    [client]
    socket=/data/mysql/mysql.sock
    
    [mysqld]
    socket=/data/mysql/mysql.sock
    port = 3306
    open_files_limit = 8192
    innodb_buffer_pool_size = 512M
    character-set-server=utf8
    #二进制日志
    log_bin
    server_id=1 #该数值不可重复,且master服务器上应当为1
    #设定日志数据清空的时间
    expire_logs_days = 15
    #半同步主从复制配置 需要提前安装半同步插件
    rpl_semi_sync_master_enabled=1
    log-slave-updates=ON
    
    
    [mysql]
    auto-rehash
    prompt=\u@\d \R:\m  mysql>
    
    完成之后进行service mysqld restart 重启服务
  3. 进入mysql,下载半主从复制相关插件

    [root@sc-master ~]# mysql -uroot -p'Sanchuang123#' #master服务器操作
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.38-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2022, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    root@(none) 20:29  mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    
    [root@sc-slave1 ~]# mysql -uroot -p'Sanchuang123#' #slave服务器操作
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 41
    Server version: 5.7.38-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2022, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    root@(none) 20:33  mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    

二.配置ansible服务器,打通ansible和集群内部机器的双向免密通道

  1. 在ansible服务器上生成密钥对
     
    [root@ansible ~]# ssh-keygen
    
  2. 将ansible服务器上的密钥对发到各个mysql服务器上
     
    ssh-copy-id root@192.168.2.137
    ssh-copy-id root@192.168.2.136
    ssh-copy-id root@192.168.2.135
  3. 安装部署ansible服务
    [root@ansible ~]# yum install -y epel-release
    [root@ansible ~]# yum install ansible
    
  4. 配置好/etc/ansible/hosts文件
    [root@ansible ~]# cd /etc/ansible/
    [root@ansible ansible]# ls
    ansible.cfg  hosts  roles
    [root@ansible ansible]# vim hosts 
    [db]
    192.168.2.135
    192.168.2.136
    192.168.2.137
    192.168.2.138
    
    
    [dbslaves]
    192.168.2.135
    192.168.2.136
    192.168.2.138
    

三. 使用mysqldump将数据冷备至ansible服务器上,然后使用ansible服务将master数据传输至所有slave,完成集群数据统一

  1. 使用mysqldump对master服务器的数据进行提取
    [root@master backup]# mysqldump -uroot -p'1232456' --all-databases >/backup/all_db.sql
    mysqldump: [Warning] Using a password on the command line interface can be insecure.#该报错并不会产生影响
    
  2. 使用scp命令,将数据传输到ansible服务器
    [root@master backup]# scp ./all_db.sql ansible:/root
  3. 在ansible服务器上通过ansible服务将数据传输至slave中
    [root@localhost ~]# ansible -m copy -a "src=/root/all_db.sql dest=/root" dbslaves
  4. 在各个slave服务器上将数据导入至mysql
    [root@sc-slave2 ~]# mysql -uroot -p'Sanchuang123#' <all_db.sql
    

    此时在mysql集群中数据达成一致

四. 创建计划任务实现将master服务器的数据定时传入ansible,使ansible作为mysql集群的异地备份服务器

  1. 在master上编写脚本,利用mysqldump实现数据的备份,并对ansible服务器进行传输
    [root@sc-master backup]# vim backup_alldb.sh 
    
    #!/bin/bash
    mkdir -p /backup
    mysqldump -uroot -p'Sanchuang123#' --all-databases --triggers --routines --events >/backup/$(date +%Y%m%d%H%M%S)_all_db.SQL
    scp /backup/$(date +%Y%m%d%H%M%S)_all_db.SQL  192.168.2.139:/backup
    
  2. 制定计划任务,实现对于脚本的定期实行,使得数据定时被传入到ansible服务器中
    [root@sc-master backup]# crontab -e
    
    30 2 * * * bash /backup/backup_alldb.sh
    
    #需要提前在ansible服务器上建立好对应文件夹进行接收,否则会报错

五. 开启gtid服务,启动集群的主从复制,并且配置一台延时服务器slave3在slave1上获取数据,增强系统稳定性,便于出现问题时进行回档

  1. 对mysql服务器的/etc/my.cnf文件进行配置,开启gtid功能
    [root@sc-master backup]# vim /etc/my.cnf
    
    
    [mysqld_safe]
    
    [client]
    socket=/data/mysql/mysql.sock
    
    [mysqld]
    socket=/data/mysql/mysql.sock
    port = 3306
    open_files_limit = 8192
    innodb_buffer_pool_size = 512M
    character-set-server=utf8
    #二进制日志
    log_bin
    server_id=1
    
    #半同步主从复制配置 需要提前安装半同步插件
    rpl_semi_sync_master_enabled=1
    log-slave-updates=ON
    
    #新增配置
    gtid-mode=ON
    enforce-gtid-consistency=ON
    [mysql]
    auto-rehash
    prompt=\u@\d \R:\m  mysql>

  2. 在master服务器上进入mysql,并且创建一个具备访问日志文件权限的用户,使得slave服务器可以通过该用户获取master上的日志数据
    root@(none) 21:34  mysql>grant replication slave on *.* to 'slave'@'192.168.2.%' identified by '123456'; #允许2网段的IO线程通过用户slave密码123456来拿取二进制日志
    Query OK, 0 rows affected, 1 warning (0.01 sec)
    
    root@(none) 21:38  mysql>select user,host from mysql.user;
    +---------------+--------------+
    | user          | host         |
    +---------------+--------------+
    | slave         | 192.168.2.% |
    | mysql.session | localhost    |
    | mysql.sys     | localhost    |
    | root          | localhost    |
    +---------------+--------------+
    4 rows in set (0.00 sec)
    
  3. 在slave机器上配置master信息
    root@(none) 21:42  mysql>stop slave;
    root@(none) 21:42  mysql>change master to master_host='192.168.2.137',master_user='slave',master_password='123456',master_port=3306,master_auto_position=1;
    

    master_host=‘192.168.2.137’ #master ip地址
    master_user=‘slave’ #master授权的用户
    master_password=‘123456’ #授权用户密码
    master_port=3306 #master端口号
    master_auto_position=1 #gtid中事务数自增量为1
     

    #在slave3上将master改为slave1的ip,并且增加MASTER_DELAY=10(单位为秒),从而实现slave3的延时备份
    root@(none) 21:42  mysql>stop slave;
    root@(none) 21:42  mysql>change master to master_host='192.168.2.136',master_user='slave',master_password='123456',master_port=3306,master_auto_position=1,master_delay=600; #mysql中大小写不敏感
  4. 查看master信息,确认连接效果
    root@(none) 15:43  mysql>start slave;
    root@(none) 15:43  mysql>show slave status\G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.2.137
                      Master_User: slave
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: master-bin.000002
              Read_Master_Log_Pos: 154
                   Relay_Log_File: slave-relay-bin.000004
                    Relay_Log_Pos: 369
            Relay_Master_Log_File: master-bin.000002
                 Slave_IO_Running: Yes  # 这两个是yes说明io线程正确联通,可以获得数据
                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: 154
                  Relay_Log_Space: 791
                  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  
                      Master_UUID: e1ae3fd1-db8f-11ee-859f-000c2974ba51
                 Master_Info_File: /data/mysql/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
               Master_Retry_Count: 600
                      Master_Bind: 
          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 
                Executed_Gtid_Set: 
                    Auto_Position: 1  ##表示gtid功能开启了
             Replicate_Rewrite_DB: 
                     Channel_Name: 
               Master_TLS_Version: 
    

    此时可以使用master服务器进入mysql进行一些操作,验证主从复制实现效果

六. 使用MHA配置MYSQL集群的自动failover功能,从而实现集群的高可用性

  1. 在ansible服务器上编写MHA主机清单,增加四个mha node节点和一个mha manager节点的ip地址
    [root@ansible ansible]# vim /etc/ansible/hosts
    [mha_manager]
    192.168.2.142  #mha manager
    [mha_node]
    192.168.2.142   #mha manager
    192.168.2.137  #master 
    192.168.2.136   #slave1
    192.168.2.135   #slave2
    
  2. 准备好所需的部分软件包,并制作一键安装的脚本
    node 脚本
    [root@ansible ~]# cat onekey_install_mha_node.sh 
    #查看可以安装或者已安装的rpm包,并且作缓存
    yum list
    #下载epel源
    yum install epel-release --nogpgcheck -y
    #下载依赖包
    yum install -y perl-DBD-MySQL \
    perl-Config-Tiny \
    perl-Log-Dispatch \
    perl-Parallel-ForkManager \
    perl-ExtUtils-CBuilder \
    perl-ExtUtils-MakeMaker \
    perl-CPAN
    #软件包mha4mysql-node-0.58.tar.gz放入/root目录下
    cd ~
    tar zxvf mha4mysql-node-0.58.tar.gz
    cd mha4mysql-node-0.58
    #编译安装
    perl Makefile.PL
    make && make install
    
    manager脚本
    #需要先运行node脚本,故而省略了部分依赖包
    [root@ansible ~]# cat onekey_install_mha_manager.sh 
    #软件包mha4mysql-manager-0.58.tar.gz放入/root目录下
    tar zxvf mha4mysql-manager-0.58.tar.gz
    cd mha4mysql-manager-0.58
    #编译安装
    perl Makefile.PL
    make && make install
    
  3. 在ansible上编写playbook,直接远程执行本地脚本完成安装
    [root@ansible ansible]# cat mha_install.yaml 
    - hosts: mha_node
      remote_user: root
      tasks: 
      - name: copy file
        copy: src=/root/mha4mysql-node-0.58.tar.gz dest=/root/
      - name: install mha_node
        script: /root/onekey_install_mha_node.sh
    - hosts: mha_manager
      remote_user: root
      tasks:
      - name: copy file
        copy: src=/root/mha4mysql-manager-0.58.tar.gz dest=/root/
      - name: install mha_manager
        script: /root/onekey_install_mha_manager.sh 
    
    [root@ansible ansible]# ansible-playbook mha_install.yaml 
    
  4. MHA服务器之间建立免密通道
    #manager对node建立免密通道
    [root@mha_manager bin]# ssh-keygen
    [root@mha_manager bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.137
    [root@mha_manager bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.136
    [root@mha_manager bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.135
    
    master对slave1,slave2建立免密通道
    [root@mha_master bin]# ssh-keygen
    [root@mha_master bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.135
    [root@mha_master bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.136
    
    slave1对master,slave2建立免密通道
    [root@mha_slave1 bin]# ssh-keygen
    [root@mha_slave1 bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.137
    [root@mha_slave1 bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.135
    
    slave2对slave1,master建立免密通道
    [root@mha_slave2 bin]# ssh-keygen
    [root@mha_slave2 bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.137
    [root@mha_slave2 bin]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.136
  5. 搭建好主从复制后,配置mha相关信息
    1. 配置各服务器的/etc/my.cnf
      #开启二进制日志
      log_bin
      server_id = 1 
      #主从切换时,主从服务器身份都可能对换,从服务器重演relay_log日志操作时,也写入自己的log_bin中
      log-slave-updates
      
      

      配置完成后记得刷新配置文件

    2. mysql服务器(master、slave1、slave2)将mysql命令和mysqlbinlog命令软链接到/usr/sbin,方便manager管理节点

      [root@master ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
      [root@master ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
      
      [root@slave1 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
      [root@slave1 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
      
      [root@slvae2 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
      [root@slave2 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
      

    3. 在mha服务器上配置用户,使得manager可以使用其进行访问
      root@(none) 11:16  mysql>grant all on *.* to 'mha'@'192.168.2.%' identified by '123456';
      Query OK, 0 rows affected, 1 warning (0.03 sec)
      
      root@(none) 11:19  mysql>grant all on *.* to 'slave'@'192.168.2.%' identified by '123456';
      Query OK, 0 rows affected, 1 warning (0.01 sec)
      
      root@(none) 11:18  mysql>grant all on *.* to 'mha'@'192.168.2.137' identified by '123456';
      Query OK, 0 rows affected, 1 warning (0.01 sec)
      
      root@(none) 11:19  mysql>grant all on *.* to 'mha'@'192.168.2.136' identified by '123456';
      Query OK, 0 rows affected, 1 warning (0.00 sec)
      
      root@(none) 11:19  mysql>grant all on *.* to 'mha'@'192.168.2.135' identified by '123456';
      Query OK, 0 rows affected, 1 warning (0.01 sec)
      
      
      
      root@(none) 11:19  mysql>select user,host from mysql.user;
      +---------------+----------------+
      | user          | host           |
      +---------------+----------------+
      | mha           | 192.168.2.%    |
      | slave         | 192.168.2.%    |
      | mha           | 192.168.2.137  |
      | mha           | 192.168.2.136  |
      | mha           | 192.168.2.135  |
      | mysql.session | localhost      |
      | mysql.sys     | localhost      |
      | root          | localhost      |
      +---------------+----------------+
      8 rows in set (0.00 sec)
      
      

  6. 在mha_manager服务器上配置好服务器相关脚本
    1. 在mha_manager上复制相关脚本
      [root@mha_manager bin]# cp -rp /root/mha4mysql-manager-0.58/samples/scripts/ /usr/local/bin/
      [root@mha_manager bin]# cd /usr/local/bin/
      [root@mha_manager bin]# ls
      apply_diff_relay_logs  masterha_check_repl  masterha_check_status  masterha_manager         masterha_master_switch    masterha_stop     save_binary_logs
      filter_mysqlbinlog     masterha_check_ssh   masterha_conf_host     masterha_master_monitor  masterha_secondary_check  purge_relay_logs  scripts
      [root@mha_manager bin]# cd scripts/
      [root@mha_manager scripts]# ls
      master_ip_failover  master_ip_online_change  power_manager  send_report
      
    2. 复制管理自动切换vip的脚本
       

      [root@mha_manager scripts]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin/
      
    3. 修改master_ip_failover文件,配置vip
       

      [root@mha_manager scripts]# >/usr/local/bin/master_ip_failover  #清空文件内容,复制以下内容
      [root@mha_manager scripts]# vim /usr/local/bin/master_ip_failover 
      #!/usr/bin/env perl
      use strict;
      use warnings FATAL => 'all';
      
      use Getopt::Long;
      
      my (
      $command, $ssh_user, $orig_master_host, $orig_master_ip,
      $orig_master_port, $new_master_host, $new_master_ip, $new_master_port
      );
      #################添加内容部分(使用时需要将注释全部删除包括空格)#############################
      my $vip = '192.168.2.200';								#指定vip的地址,自己指定
      my $brdc = '192.168.2.255';								#指定vip的广播地址
      my $ifdev = 'ens33';										#指定vip绑定的网卡
      my $key = '1';												#指定vip绑定的虚拟网卡序列号
      my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";		#代表此变量值为ifconfig ens33:1 192.168.2.200
      my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";		#代表此变量值为ifconfig ens33:1 192.168.2.200 down
      my $exit_code = 0;											#指定退出状态码为0
      #my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
      #my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
      ##################################################################################
      GetOptions(
      'command=s' => \$command,
      'ssh_user=s' => \$ssh_user,
      'orig_master_host=s' => \$orig_master_host,
      'orig_master_ip=s' => \$orig_master_ip,
      'orig_master_port=i' => \$orig_master_port,
      'new_master_host=s' => \$new_master_host,
      'new_master_ip=s' => \$new_master_ip,
      'new_master_port=i' => \$new_master_port,
      );
      
      exit &main();
      
      sub main {
      
      print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
      
      if ( $command eq "stop" || $command eq "stopssh" ) {
      
      my $exit_code = 1;
      eval {
      print "Disabling the VIP on old master: $orig_master_host \n";
      &stop_vip();
      $exit_code = 0;
      };
      if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
      }
      exit $exit_code;
      }
      elsif ( $command eq "start" ) {
      
      my $exit_code = 10;
      eval {
      print "Enabling the VIP - $vip on the new master - $new_master_host \n";
      &start_vip();
      $exit_code = 0;
      };
      if ($@) {
      warn $@;
      exit $exit_code;
      }
      exit $exit_code;
      }
      elsif ( $command eq "status" ) {
      print "Checking the Status of the script.. OK \n";
      exit 0;
      }
      else {
      &usage();
      exit 1;
      }
      }
      sub start_vip() {
      `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
      }
      ## A simple system call that disable the VIP on the old_master
      sub stop_vip() {
      `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
      }
      
      sub usage {
      print
      "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
      }
      
      
      
      
    4. 创建 MHA 软件目录并复制配置文件,使用app1.cnf配置文件来管理 mysql 节点服务器,配置文件一般放在/etc/目录下
      tip:脚本使用过程中需要将注释包括空格全部删除

      [root@mha_manager scripts]# mkdir /etc/masterha
      [root@mha_manager scripts]# cp /root/mha4mysql-manager-0.58/samples/conf/app1.cnf /etc/masterha/
      [root@mha_manager scripts]# cd /etc/masterha/
      [root@mha_manager masterha]# ls
      app1.cnf
      [root@mha_manager masterha]# >app1.cnf #清空原有内容
      [root@mha_manager masterha]# vim app1.cnf 
      
      [server default]
      manager_log=/var/log/masterha/app1/manager.log       #manager日志(产生报错可以选择自建)
      manager_workdir=/var/log/masterha/app1.log    		#manager工作目录
      master_binlog_dir=/data/mysql/          #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
      master_ip_failover_script=/usr/local/bin/master_ip_failover            #设置自动failover时候的切换脚本,也就是上面的那个脚本
      master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
      user=mha					#设置监控用户mha
      password=123456			#设置mysql中mha用户的密码,这个密码是前文中创建监控用户的那个密码
      ping_interval=1				#设置监控主库,发送ping包的时间间隔1秒,默认是3秒,尝试三次没有回应的时候自动进行failover
      remote_workdir=/tmp			#设置远端mysql在发生切换时binlog的保存位置
      repl_user=slave			#设置复制用户的用户slave
      repl_password=123456		#设置复制用户slave的密码
      report_script=/usr/local/send_report     #设置发生切换后发送的报警的脚本
      secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.31.222 -s 192.168.31.223	#指定检查的从服务器IP地址
      shutdown_script=""			#设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
      ssh_user=root				#设置ssh的登录用户名
      
      [server1]
      #master
      hostname=192.168.2.137
      port=3306
      
      [server2]
      #slave1
      hostname=192.168.2.136
      port=3306
      candidate_master=1
      #设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中最新的slave
      
      check_repl_delay=0
      #默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master, 因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
      
      [server3]
      #slave2
      hostname=192.168.2.135
      port=3306
      
  7. 在master服务器上手动开启vip
    [root@master mysql]# ifconfig ens33:1 192.168.2.200/24
    

    ip add 时出现该ip则说明运行成功

  8. 在manager服务器上测试ssh免密通道,如果正常最后会输出successfully
    [root@mha_manager masterha]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
    Mon May  8 11:50:00 2023 - [info] All SSH connection tests passed successfully.
    
  9. 在manager服务器上测试测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常
    [root@mha_manager masterha]# masterha_check_repl -conf=/etc/masterha/app1.cnf
    MySQL Replication Health is OK.
    
  10. manager开启MHA
    [root@localhost ~]#  nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
    [1] 42889
    
     
    1. 查看MHA状态
      [root@mha_manager masterha]# masterha_check_status --conf=/etc/masterha/app1.cnf
      app1 (pid:42889) is running(0:PING_OK), master:192.168.2.137
      
    2. 查看MHA日志
      [root@mha_manager masterha]# cat /var/log/masterha/app1/manager.log | grep "current master"
      Mon May  8 11:57:07 2023 - [info] Checking SSH publickey authentication settings on the current master..
      192.168.2.137(192.168.2.137:3306) (current master)
      
  11. 测试故障转移效果,将master宕机,将slave指定为新的master
    1. manager查看监控日志记录
      [root@mha_manager bin]# tail -f /var/log/masterha/app1/manager.log 
      
    2. 将master宕机(顺序错误会导致报错)
      [root@master mysql]# service mysqld stop
      
    3. ip add查看slave1上是否有vip,如果有出现则说明漂移成功
    4. 查看/etc/masterha/app1.cnf

      原来的server1以及被删除了
    5. 查看slave2的master信息

      会发现master已经改成了slave1的ip地址

        此时已经成功完成了vip的飘移,集群中剩余的机器会从slave1中获取日志文件,此时MHA已经成功配置,实现了mysql集群的高可用

七. 启动MYSQLrouter服务,实现router服务器对于外部访问的转接,从而实现读写分离的负载均衡,提高mysql面对大并发时的处理能力

  1. 首先准备好MYSQLrouter相关安装包
  2. 修改相关的配置文件
    cd /etc/mysqlrouter/
    vim mysqlrouter.conf
    #read-only
    [routing:slaves] 
    bind_address = 192.168.2.141:7001
    destinations = 192.168.2.135:3306,192.168.2.136:3306
    mode = read-only
    connnect_timeout = 1
    #write and read
    [routing:masters]
    bind_address = 192.168.2.141:7002 
    destinations = 192.168.2.137:3306
    mode = read-write
    connect_timeout =  2	
    
  3. 手动开启mysqlrouter服务
    service mysqlrouter start
  4. 在mysql服务器上创建读写用户和只读用户,用于外部访问
    grant all on *.* to 'write'@'%' identified by 'Sanchuang1234#';
    grant select on *.* to 'read'@'%' identified by 'Sanchuang1234#';
    
  5. 使用一台集群外的服务器,试图通过router对集群进行访问检查转发效果
    mysql -h 192.168.2.141 -P 7002 -uwrite -p'Sanchuang1234#'

    当成功进入mysql后,说明MYSQLrouter服务配置成功,需要注意的是,mysqlrouter服务器的端口并不决定用户的具体权限,用户访问时具体拥有的权限仅与登录时所采用的mysql用户所具备的权限相关,至此mysql集群完成读写分离,提高了应对大并发时的处理能力,减轻master服务器压力

八. 安装keepalive,通过vrrp协议实现mysqlrouter中间件的高可用

  1. 配置环境,在router机上安装keepalive
    [root@mysqlroute1 mysqlrouter]# yum install keepalived
  2. 修改keepalive配置文件
    在master上的配置
    [root@mysqlroute1 keepalived]# cat keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       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
    }
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 51
        priority 200
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.2.188
        }
    }
    
    在backup上的配置
    [root@mysqlroute2 keepalived]# cat keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       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
    }
    
    vrrp_instance VI_1 {
        state backup
        interface ens33
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.2.188
        }
    }
    
  3. 配置完成后刷新服务
    [root@mysqlroute1 keepalived]# service keepalived restart
  4. ip add查看是否出现vip 出现即为成功配置

九. 使用sysbench压力测试工具检验集群性能,确定集群系统资源的上限

  1. 安装sysbench并进行相关配置
    [root@sysbench ~]# yum install -y sysbench
    
  2. 调整内核资源数据
    [root@sysbench ~]# ulimit -n 50000
    [root@sysbench ~]# ulimit -u 50000
    [root@sysbench ~]# ulimit -s 50000
    
  3. 进行压力测试
    1. 写请求,准备1000个客户在10秒内访问
      [root@sysbench ~]# sysbench --threads=1000 --time=10 --report-interval=5 --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-port=8066 --mysql-host=192.168.2.188 --mysql-db=test1 oltp_insert prepare
      #–threads:并发数,这里模拟的是1000个客户端;
      #–time:测试时间,单位为秒;
      #–report-interval:每隔几秒输出一次详细结果;
      #–db-driver:测试的数据库,可以是mysql,postgresql等,
      #–mysql-user:数据库用户(因为这里测试入口是mycat,所以也创建也mycat用户);
      #–mysql-password:数据库密码;
      #–mysql-port:数据库端口号;
      #–mysql-host:数据库ip地址;
      #–mysql-db:针对哪个库进行测试(这里我使用的之前建立的逻辑库test1);
      #oltp_insert:测试的sql语句类型,因为场景为高并发写入,肯定是insert语句,所以选择oltp_insert;
      
      [root@sysbench ~]# sysbench --threads=1000 --time=60 --report-interval=5 --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-port=8066 --mysql-host=192.168.2.188 --mysql-db=test1 oltp_insert run
      #运行测试
      
      [root@sysbench ~]# sysbench --threads=1000 --time=60 --report-interval=5 --db-driver=mysql --mysql-user=root --mysql-password=123456 --mysql-port=8066 --mysql-host=192.168.2.188 --mysql-db=test1 oltp_insert cleanup
      #测试完成后清理数据
    2. io性能测试
      router1上安装sysbench
      准备好10个文件,总体大小为1G
      [root@mysqlroute1 ~]# sysbench fileio --file-num=10 --file-total-size=1G prepare
      
      [root@mysqlroute1 ~]#  sysbench --events=5000 --threads=16 fileio --file-num=10 --file-total-size=1G --file-test-mode=rndrw --file-fsync-freq=0 --file-block-size=16384 run
    3. cpu性能测试
      ​​​​​​​
      [root@mysqlroute1 ~]#  sysbench cpu --threads=40 --events=5000 --cpu-max-prime=20000 run

项目心得

  • 项目开始前需要整理好服务器的关系,作好规划,可以使执行项目时的过程条理更加清晰,便于溯源和纠错
  • 执行前可以定期进行存档,方便出现错误时通过回档进行规避
  • 出错后仔细检查操作是否无误,配置是否出现问题,应当多根据日志和报错信息的提示来进行纠错
  • 总体完成之后对于数据库主从复制的了解更加深入
  • 对于如何应对大并发和实现高可用有了更加深刻的理解
  • 掌握了sysbench压力测试软件的使用,对于系统的负载能力和具体资源情况的认知更加清楚
  • 合理使用ansible服务可以避免很多的重复操作,但对于使用过程中个体化操作的应用应该更加谨慎
  • 进行文件的配置时需要更加细致,记得要重启服务,并在重启出现问题时及时对于出现问题的部分进行查询和修改

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值