您好,欢迎访问一九零五行业门户网

搭建mysql负载均衡及高可用环境_MySQL

bitscn.com
搭建mysql负载均衡及高可用环境
摘要: 使用 rhel5.8,mysql,keepalived,haproxy 搭建一个集高可用、负载均衡的集群; 也有使用到 mysql 的二进制复制来保持数据一致性; 避免了单节点故障,也提供设备的利用率; 虽然这个实验只有两台设备,但可以此为例,理解概念后再放大到其它环境也可以;
目标:使用两台主机实现 mysql 的负载均衡及冗余,并做到双主互备; 
环境:rhel5.8,mysql-5.0.77,keepalived-1.2.7,haproxy-1.4.20; 
说明: 
keepalived 实现通过 vrrp协议,通过使一个虚拟ip地址(或称浮动ip)在主备设备间的切换来达到主机冗余; 
而客户机通过访问这个虚拟ip 来获取服务; 
haproxy 是一款负载均衡软件,用于将请求按策略转发给不同主机,达到负载均衡的效果; 
可以实现网络层或应用层上的判断分配; 
mysql 开启二进制日志,做到数据库之间的双向复制,保持数据一致性;
#提醒一下,实际生产环境没人会这样搭建的,仅通过这个实验来理解这些概念,希望阅者能有所获;
server1_ip=192.168.5.11
server2_ip=192.168.5.12
server_vip=192.168.5.111
================================================
#此处关闭了防火墙,开启则另配置相应规则
service iptables stop
chkconfig iptables off
ls /opt/soft/ #提取准备软件到此处
haproxy-1.4.20.tar.gz  keepalived-1.2.7.tar.gz
mkdir /opt/keepalived
mkdir /opt/scripts/ #此实验用到脚本目录
mkdir /opt/log/ #此实验日志文件夹
=================================================
[install_mysql] 
#在两台主机上安装 mysql ,此处使用 rpm 包安装,yum环境可以搭本地源; 
yum install -y mysql-server 
service mysqld start 
======================================================= 
[create_mysql_test_table] 
#分别创建一张相同名称和字段的表,插入不同的值,方便中途测试 ha 和轮询是否成功; 
#还有分别创建一个相同的用户
#server1 
mysql 
>use test; 
>create table mywait(name char(9),phone char(14)); 
>insert into mywait(name,phone) values('wait',15000000000);
#server2 
>use test; 
>create table mywait(name char(9),phone char(14)); 
>insert into mywait(name,phone) values('chen',15611111111);
[new_mysql_test_user] 
>mysql 
>grant all on test.* to diaosi@'%' identified by '123456'; 
>flush privileges; 
======================================================= 
#从客户机上测试一下; 
mysql -udiaosi -p123456 -h 192.168.5.11 -e select * from test.mywait; 
mysql -udiaosi -p123456 -h 192.168.5.12 -e select * from test.mywait;
#至此,mysql 基础环境搭建完成; 
======================================================= 
[install_keepalived]
yum install -y libnl-devel #解决依赖关系
tar xf /opt/soft/keepalived-1.2.7.tar.gz -c /opt/soft 
cd /opt/soft/keepalived-1.2.7/ 
#with-kernel 指定内核版本时,根据本机情况使用tab键补全 
./configure --prefix=/opt/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-308.el5-i686/ 
make && make install
[keepalived_config] 
#因为没有安装在 / 目录下,所以这些启动和配置文件都需要再 copy 一下;
cp /opt/keepalived/sbin/keepalived /usr/sbin/ 
cp /opt/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ 
cp /opt/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ 
mkdir /etc/keepalived 
cp /opt/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
chkconfig keepalived on #设置开机启动 
======================================================= 
vim /etc/keepalived/keepalived.conf #keepalived 主配文件 
#以下的配置适合 keepalived 本身便是服务提供者的情况; 
01
! configuration file for keepalived
02
03
#简单的头部,这里主要可以做邮件通知报警等的设置,此处就暂不配置了;
04
global_defs {
05
        notificationd lvs_devel
06
}
07
08
#预先定义一个脚本,方便后面调用,也可以定义多个,方便选择;
09
vrrp_script mysql_chk {
10
        script /opt/scripts/mysql_chke.sh
11
        interval 2      #脚本循环运行间隔
12
        weight 2        #脚本的结果导致优先级变更,成功+2
13
}
14
#vrrp虚拟路由冗余协议配置
15
vrrp_instance vi_1 {            #vi_1 是自定义的名称;
16
        state master            #表明这是一台主设备,备用设备为 backup
17
        interface eth0              #指定vip需要绑定的物理网卡
18
        virtual_router_id 11        #vrid虚拟路由标识,也叫做分组名称,该组内的设备需要相同
19
        priority 150            #定义这台设备的优先级 1-254;
20
        advert_int 1            #生存检测时的组播信息发送间隔,组内一致
21
22
        authentication {        #设置验证信息,组内一致
23
                auth_type pass          #有pass 和 ah 两种,常用 pass
24
                auth_pass 111           #密码
25
        }
26
27
        virtual_ipaddress {     #指定vip地址,组内一致,可以设置多个ip
28
                192.168.5.111/24
29
        }
30
31
        track_script {      #使用在这个域中使用预先定义的脚本
32
                mysql_chk
33
        }
34
35
    #此部分所载入的脚本为外部脚本,不需要预先定义;
36
    #也可不添加,此实验在后半部分安装haproxy后,才有添加;
37
        notify_master /opt/scripts/start_haproxy.sh #表示当切换到master状态时,要执行的脚本
38
        notify_fault /opt/scripts/stop_keepalived.sh    #故障时执行的脚本
39
        notify_stop /opt/scripts/stop_haproxy.sh        #keepalived停止运行前运行的脚本
40
}
#keepalived 主和备的配置文件基本相同;只需要修改: 
state backup #修改为备份设备 
priority 100 #优先级要比主低 
#其它地方根据实际情况也可以做调整; 
======================================================= 
#新建刚才配置keepalived 时所定义的脚本,用于在mysql 死亡后结束 keepalived 
01
#!/bin/bash
02
#mysql_chke.sh
03
#
04
a=`ps -c mysqld --no-header | wc -l`
05
if [ $a -eq 0 ];then
06
        sleep 3
07
                /sbin/service keepalived stop
08
                echo `date +%c` stop keepalived >> /opt/log/stop_keepalived.log
09
        fi
10
fi
service keepalived start    #在两台设备上面启动
#开始测试
ip address 
#查看主设备 11 上是否有生成 vip 地址; 
#注意事项,keepalived 生成的 vip 对 ifconfig 命令不可见,所以需要使用 ip 命令;
mysql -udiaosi -p123456 -h 192.168.5.111 -e select * from test.mywait; 
#正常情况是只能查询到 master 的数据库的数据;
1、尝试将 master 的keepalived 停掉 
2、down 掉 master 的网卡 
3、让mysql 启动不了,比如先注释掉mysql这个用户,后killall mysqld , 
查看mysql_chke 脚本是否会把 keepalived 结束掉;
#这个时后 vip 地址会移动到 slave 主机上; ha 搭建的是否成功体现于查询所获取值的变化; 
#当将 master 恢复后,vip 又会回到 11 的设备上;
#至此 keepalived 为 mysql 做ha 模式成功; 
======================================================================== 
[install_haproxy] 
#用于将请求分别轮询到 192.168.5.11 192.168.5.12
tar xf /opt/soft/haproxy-1.4.20.tar.gz -c /opt/soft/ 
cd /opt/soft/haproxy-1.4.20/ 
make target=linux26 prefix=/opt/haproxy install
mkdir /opt/haproxy/conf 
mkdir /opt/haproxy/logs 
touch /opt/haproxy/conf/haproxy.cfg 
======================================================================== 
[mysql_config] 
#修改 mysql 监听,使 mysql 避开 192.168.5.111,因为 haproxy 也要监听 111:3306 这个ip地址和端口; 
vim /etc/my.cnf
#server1 
[mysqld] 
bind-address=192.168.5.11 #mysql 的监听,添加这一句就好了
#server2 
[mysqld] 
bind-address=192.168.5.12
#重启mysql 
service mysqld restart
#到现在已经不能通过 192.168.5.111 访问数据库了,接下来配置 haproxy 
======================================================================== 
[config_haproxy] 
#主备服务器的主配文件一致; 
vim /opt/haproxy/conf/haproxy.cfg 
01
global          #全局系统配置
02
        log 127.0.0.1 local0 info   #定义日志级别[err warning info debug]
03
                    #local0 是日志设备,必须为24种标准syslog设备之一;
04
        maxconn 4096        #最大链接数
05
        uid 0           #运行该程序的用户,此处没有其它用户了,就用的 root
06
        gid 0
07
        daemon          #以后台形式运行
08
        nbproc 1        #进程数量
09
10
defaults            #默认配置
11
        mode tcp        #所处理的类别 http | tcp | health
12
        option redispatch   #serverid对应的服务器挂掉后,强制定向到其他健康的服务器
13
        retries 3       #三次连接失败则服务器不用
14
        timeout connect 5000    #连接超时
15
        timeout client 50000    #客户端超时
16
        timeout server 50000    #服务器超时
17
        timeout check 2000  #心跳检测超时
18
19
listen proxy
20
        bind 192.168.5.111:3306     #监听地址
21
        mode tcp
22
        balance roundrobin      #定义负载方式,此处为轮询
23
24
        log 127.0.0.1 local0 info   #定义日志类型
25
    #rise 3三次正确表示服务器可用,fall 3表示3次失败表示服务器不可用
26
        server db1 192.168.5.11:3306 check inter 1200 rise 2 fall 3 weight 1
27
        server db2 192.168.5.12:3306 check inter 1200 rise 2 fall 3 weight 1
28
29
#服务器状态监控配置,可以通过定义的地址查看集群状态;
30
listen haproxy_stats
31
        log 127.0.0.1 local0 info
32
        mode http
33
        bind 192.168.5.111:8888
34
        option httplog
35
        stats uri /status
36
        stats realm haproxy manager
37
        stats auth admin:admin      #设置监控地址的帐号与密码
#在keepalived 主配文件中添加刚才在其末端说明的外部定义脚本
#启动服务 
/opt/haproxy/sbin/haproxy -f /opt/haproxy/conf/haproxy.cfg
#说明事项,keepalived 的服务主备设备上都可以同时运行,实则只有获得vip的服务器才有效; 
#但是 haproxy 启动的时候需要监听 vip 地址,所以第一次备用设备是手动起不了服务的; 
#需要在 keepalived 的notify_master配置项中设定脚本,当此设备获得vip地址后才启动 haproxy;
#有个问题在这里,我们只设定了当keepalived 停止服务时,才结束 haproxy ,没有设定移交vip时是否结束; 
#其实这也不用担心,因为主机上已经没有vip地址了,即便是监听也无效果,并无干扰; 
======================================================================== 
##开始测试
#检测监听 
netstat -tunlp | grep ha 
netstat -tunlp | grep 3306 
# master 设备上才会有两个程序监听不同地址的 3306;
#暂未配置 mysql 互为主备就是为了方便这一阶段的排错,这样能更准确的测试; 
mysql -udiaosi -p123456 -h 192.168.5.111 -e select * from test.mywait; 
#返回值应该是在 server1 server2 之间徘徊;
sed -i 's/^mysql.*$/#&/' /etc/passwd     #注释掉mysql的用户 
service mysqld stop
#这个时候 mysql 服务已经启动不起了,mysql_chke.sh 脚本会把 keepalived 停止掉; 
keepalived 停止前,又会把 haproxy 杀死;当备份的设备获得 vip 后,则会通过start_haproxy.sh 脚本将 haproxy 启动起来; 
于是并不会因为服务器当机或mysql故障,影响我们客户端对 111 的查询操作,实验完成一半了;
#但是测试时,在vip地址切换过程中,客户端会有那么2-3秒不能访问到数据库,这个暂时忽略不计;
sed 's/^#//' /etc/passwd     #测试完后,记得恢复mysql用户哦; 
#恢复mysql 后,启动主设备的 mysqld keepalived ,然后使用 ip a 查看vip 地址是否有返回来;
#在其中一台设备上 killall haproxy ,之后查看集群状态; 
http://192.168.5.111:8888/status 
#查看后再将 haproxy 启动
#至此,已经完成 负载均衡 + 高可用 两部分,负载方式为轮询 
======================================================================== 
##三个脚本,很简单,就不再介绍了哈;主要是做日志和结束服务;
01
#!bin/bash
02
#start_haproxy.sh
03
04
sleep 5
05
get=`ip addr  |grep 192.168.5.111 |wc -l`
06
echo $get >> /opt/log/start_haproxy.log
07
08
if [ $get -eq 1 ]
09
then
10
        echo `date +%c` success to get vip >> /opt/log/start_haproxy.log
11
        /opt/haproxy/sbin/haproxy -f /opt/haproxy/conf/haproxy.cfg
12
else
13
        echo `date +%c` can not get vip >> /opt/log/start_haproxy.log
14
fi
1
#!bin/bash
2
#stop_haproxy.sh
3
4
pid=`pidof haproxy`
5
echo `date +%c` stop haproxy >> /opt/log/stop_haproxy.log
6
kill -9 $pid
01
#!bin/bash
02
#stop_keepalived.sh
03
04
pid=`pidof keepalived`
05
if [ $pid == ]
06
then
07
        echo `date +%c` no keepalived process id  >> /opt/log/stop_keepalived.log
08
else
09
        echo `date +%c` will stop keepalived  >> /opt/log/stop_keepalived.log
10
        /etc/init.d/keepalived stop
11
fi
=======================================================
[mysql manager slave]
#mysql 主备配置;两台设备上添加用户哦;
root#mysql 
create database db1; 
grant replication slave on *.* to 'diaosi1'@'%' identified by '123456'; 
#此处注意哦,slave 权限必须的,我最初使用 all 权限,结果主备始终不同步,改成 slave 就ok了; 
flush privileges; 
show grants for mydiaosi1@'%'; 
================================================================== 
#server1 的 mysql 配置 
server_id=1 #服务器标识,唯一 
log_bin=mysqlbinlog #启用二进制日志 
log_bin_index=mysqlbinlog-index #日志索引文件 
log_slave_updates=1 #让从服务器把自身复制的事件和记录都写到自己的二进制日志里 
relay_log=relay-log #中继日志位置;存放slave端获取到master端的二进制文件信息 
replicate_do_db=db1 ##指定需要同步的数据库
#server2 的 mysql 配置 
server_id=2 
log_bin=mysqlbinlog 
log_bin_index=mysqlbinlog-index 
log_slave_updates=1 
relay_log=relay-log 
replicate_do_db=db1
#分别重启两服务 
service mysqld restart
mysql> show master status; #查看mysql 的当前二进制日志文件
+--------------------+----------+--------------+------------------+
| file               | position | binlog_do_db | binlog_ignore_db |
+--------------------+----------+--------------+------------------+
| mysqlbinlog.000001 |       98 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.28 sec)
#分别连接对方 mysql 日志,开始备份;记得替换 master_host 和日志名及master_log_pos;
>change master to master_host='192.168.5.12',master_port=3306,master_user='mywait',master_password='123456',master_log_file='mysqlbinlog.000001',master_log_pos=98;
>start slave; #开始同步
mysql> show slave status/g #查看mysql同步状态
*************************** 1. row ***************************
             slave_io_state: waiting for master to send event
                master_host: 192.168.5.11
                master_user: mywait
                master_port: 3306
              connect_retry: 60
            master_log_file: mysqlbinlog.000001
        read_master_log_pos: 98
             relay_log_file: relay-log.000002
              relay_log_pos: 237
      relay_master_log_file: mysqlbinlog.000001
           slave_io_running: yes #表明获取对方日志文件的连接成功;
          slave_sql_running: yes #将获取到的日志转成sql语句回写本地数据库成功;
            replicate_do_db: db1
        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: 98
            relay_log_space: 237
            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
1 row in set (0.00 sec)
#主要就是看 slave_io_running,slave_sql_running
#这里错误的话,多数情况是 slave_io_running 的问题,防火墙,用户权限,日志是否有启用等都需要判断;
=====================================================================
=====================================================================
#至此 mysql 双主互备搭建完成,我们的全部实验规划也全部完成;
#进入全面测试阶段;
#在 server1 的db1里新建一张表,并赋值
>use db1;
>create table mywait(name char(9),phone char(14));
>insert into mywait(name,phone) values('wait',15888888888);
#新建一个具有 db1 权限的用户
grant all on db1.* to diaosi2@'%' identified by '123456';
>flush privileges;
#切换到 test 库,在mywait 表中插入一条数据;
use test;
insert into mywait(name,phone) values ('diaosi',15002839961);
#在 server2做验证;
>use db1;
>show tables;
>select * from mywait;
#此时数据与 server1 的会数据一致,表示mysql同步成功;
select user,host,password from mysql.user;
#在 server1 创建的用户也会被 server2 所同步;
#select * from test.mywait
#可以看到 server1上的 test 库并没有被同步;
#客户机上测试
mysql -udiaosi2 -p123456 -h 192.168.5.111 -e select * from db1.mywait;
#完毕;
=======================================================
#存在的问题;
在做mysql_chke 脚本时,本打算使用检查进程的形式判断服务是否启动;
`ps -c mysqld --no-header | wc -l`
当检查mysql 进程不存在的时候,先试着启动一次mysqld ,然后再检测,如果还是启动不了服务,再结束 keepalived ;
但是在使用 /etc/rc.d/init.d/mysqld start 启动后,出现一些问题;
比如mysql 配置文件错误或是注销用户等,mysql服务已然起不来了,虽然手动起不来服务;
但使用 ps -c mysqld 还是可以检查出一条mysqld 的进程来,这是什么情况没弄明白,希望能得到指点;
可优化项,haproxy 的功能很多,可以做成基于权重的分配方式,或是根据访问地址的,甚至可以使用 cookie 做判断;
大家都可以多测试一下;
有些地方是需要在两台服务器上同时配置的,大家看的时候多留意一下,测试过程中多看日志是最好的排错方式;
#ip a | ip addr | ip address 效果是一样的;
bitscn.com
其它类似信息

推荐信息