ITPub博客

首页 > 数据库 > MySQL > CentOS7+ keepalived+ haproxy搭建Mycat高可用及负载均衡

CentOS7+ keepalived+ haproxy搭建Mycat高可用及负载均衡

原创 MySQL 作者:dba_sam 时间:2021-06-20 11:34:50 1 删除 编辑

   MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

   MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度

具体介绍请参考:

 

OS: CentOS Linux release 7.9.2009 (Core)

序号

主机

IP

部署内容

备注

1

mycat1

192.168.56.111

mycat 节点,使用xinetd进行mycat运行状态监测


2

mycat2

192.168.56.112

mycat 节点,使用xinetd进行mycat运行状态监测


3

keep1

192.168.56.111

部署keepalived + haproxy,主节点

与mycat1共用服务器,生产环境建议分开

4

keep2

192.168.56.112

部署keepalived + haproxy,备节点

与mycat2共用服务器,生产环境建议分开

5

VIP

192.168.56.113

准备一个同网段未被占用的ip地址用作VIP


6

mysql

192.168.56.109

准备一个可用的mysql库,并且创建1个database(test_db)


7

mysql

192.168.56.110

准备一个可用的mysql库,并且创建1个database(test_db)


 

关闭系统SELINUX 功能:

执行命令如下:

sed -i '/^SELINUX=.*/ s//SELINUX=disabled/' /etc/selinux/config

或vi 编辑/etc/selinux/config 文件,更改SELINUX=disabled

更改后,执行命令:reboot 重启系统生效

重启后,运行:getenforce 检查selinux状态是否为Disabled状态

 

*mysql 数据库服务器关闭SELINUX

* 运行在Linux下的mysql,需要配置 lower_case_table_names=1 不区分大小写

添加到mysql配置文件中 /etc/my.cnf

配置完成后,重启mysql数据库生效

安装

安装jdk1.8可以直接使用yum install java-1.8.0-openjdk.x86_64 -y 进行安装。

以下部署,采用手动部署jdk1.8,去官网下载jdk1.8的程序包,下载后文件为jdk-8u291-linux-x64.tar.gz

 

# 上传jdk1.8安装包至mycat服务器( 两节点同操作

# 上传到/usr/local 目录下,并进行解压

tar xzf jdk-8u291-linux-x64.tar.gz

# 配置系统环境变量

vi /etc/profile   # 编辑文件,在末尾处加入以下内容

export JAVA_HOME=/usr/local/jdk1.8.0_291

export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export PATH=$PATH:$JAVA_HOME/bin

 

# 保存并退出

# 使配置生效

source /etc/profile

 

# 验证版本

java -version

安装

* 以下配置在两个节点操作

# 创建软件存放目录

mkdir /opt/app

 

# 下载Mycat

cd /opt/app

wget

 

# 解压缩

tar xzf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz

 

# 设置Mycat环境变量

echo 'export MYCAT_HOME=/opt/app/mycat' >> /etc/profile

source /etc/profile

配置

* 以下配置在两个节点操作

# 配置数据源

/opt/app/mycat/conf/schema.xml 中定义了后端数据源、逻辑库/表等。

dataHost :Mycat后端连接的数据库(物理库,真实的数据库),即后端数据源,可以是mysql、oracle等。

schema :逻辑库,可以看做是一个或多个后端数据库集群构成的逻辑库。

dataNode :数据分片,逻辑库的构成,即一个逻辑库可能分为多个分片,数据分片最终会落在一个或多个物理库。

 

如下配置有2个dataHost分别对应后端一个mysql实例,mysql创建了1个database为test_db。一个逻辑库test中有一张app_users逻辑表,表中的数据分为2片,分别落在两个mysql的test_db上。

以上配置中schema sbux使用了auto-sharding-long分片策略,分片策略在/opt/app/mycat/conf/rule.xml中定义,如下

该配置中指定了autopartition-long.txt文件为策略记录,选择的策略是按数值的范围路由数据,即0-500W在第一个分片,500W-1000W在第二个分片,这里我把第3个分片的注释掉了,我们没有配置第3个分片

# 配置mycat用户

/opt/app/mycat/conf/server.xml 中定义mycat的系统配置和用户等。可以通过xml新增和修改mycat用户信息。

以下为schema:test添加了两个用户root和user,应用使用这两个账号连接mycat进行数据的操作。

# mycat 启动

/opt/app/mycat/bin/mycat start

# mycat 运行端口查看

netstat -antup | grep 8066

# mycat 管理端口查看

netstat -antup | grep 9066

# 使用mysql客户端连接mycat 验证

mysql -u root -h 192.168.56.111 -P 8066 -p

# mycat 管理命令

管理命令需要连接mycat的9066默认端口

mysql -u root -h 192.168.56.111 -P 9066 -p

配置防火墙

添加防火墙过滤规则,允许8066与9066通过

firewall-cmd --permanent --zone=public --add-port=8066/tcp

firewall-cmd --permanent --zone=public --add-port=9066/tcp

firewall-cmd --reload

* 以下配置在两个mycat节点上操作

使用xinetd检测mycat进程是否正常,提供http接口给haproxy探测mycat运行情况。

 

安装xinetd

yum install -y xinetd

创建进程检测的脚本

创建/usr/local/bin/mycat_status 文件,内容如下:

#!/bin/bash

#/usr/local/bin/mycat_status

# This script checks if a mycat server is healthy running on localhost. It will

# return:

# "HTTP/1.x 200 OK\r" (if mycat is running smoothly)

# "HTTP/1.x 503 Internal Server Error\r" (else)

 

mycat=`/opt/app/mycat/bin/mycat status |grep 'not running'| wc -l`

if [ "$mycat" = "0" ];then

    /bin/echo -e "HTTP/1.1 200 OK\r\n"

else

    /bin/echo -e "HTTP/1.1 503 Service Unavailable\r\n"

fi

# 添加sh执行权限

chmod +x /usr/local/bin/mycat_status

修改xinetd配置文件

在xinetd配置中加入mycat的信息,创建文件/etc/xinetd.d/mycat_status。在48700端口启动服务,检测mycat进程是否存在并将结果返回,具体配置如下:

service mycat_status

{

    flags = REUSE

    socket_type = stream

    port = 48700

    wait = no

    user = root

    server = /usr/local/bin/mycat_status

    log_on_failure +=USERID

    disable = no

}

添加服务端口

编辑 /etc/services 文件,在末尾处添加以下内容

mycat_status    48700/tcp               # mycat status

# 重启xinetd

systemctl restart xinetd

# 验证结果

curl -i

返回200说明mycat服务是正常的,返回503代表mycat进程停止了,服务异常。

 

配置防火墙

firewall-cmd --permanent --zone=public --add-port=48700/tcp

firewall-cmd --reload

安装keepalived

* 主备节点都同样的操作(部分配置有不同),这里我使用mycat主备服务器为搭建keepalived,生产环境建议分开;

# 安装keepalived

# 使用yum安装keepalived

yum install -y keepalived

 

# 创建keepalived相关日志目录

mkdir -p /opt/app/keepalived/log

 

配置keepalived

cd /etc/keepalived/

cp keepalived.conf keepalived.conf_bak

vim 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 keep1

   #vrrp_skip_check_adv_addr

   #vrrp_strict

   vrrp_garp_interval 0

   vrrp_gna_interval 0

}

# 定期调用check_haproxy.sh脚本检查mycat运行状态

vrrp_script chk_http_port {

   script "/etc/keepalived/scripts/check_haproxy.sh"

   interval 3

   weight 2

}

vrrp_instance VI_1 {

    state MASTER  # 备服务器用 BACKUP

    interface enp0s8  # 实际网卡的名称

    virtual_router_id 51  # 主备服务器这个ID必须一致才能切换

    priority 150   # 备服务器的值要低于主库的值

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    virtual_ipaddress {

        192.168.56.113 # VIP 地址

    }

    track_script {

    # 调用脚本 check_haproxy.sh 检查 haproxy 是否存活(mycat刚刚加的那个服务)

       chk_http_port

    }

# keepalived 状态变化时执行相应脚本

    # 当此keepalived节点变为主时执行

    notify_master /etc/keepalived/scripts/haproxy_master.sh

    # 当此keepalived节点变为备时执行

    notify_backup /etc/keepalived/scripts/haproxy_backup.sh

    # 当此keepalived节点fault时执行

    notify_fault  /etc/keepalived/scripts/haproxy_fault.sh

    # 当此keepalived节点停止时执行

    notify_stop   /etc/keepalived/scripts/haproxy_stop.sh

}

# haproxy 检测脚本

mkdir -p /etc/keepalived/scripts  # 创建存放脚本目录

vim /etc/keepalived/scripts/check_haproxy.sh   # 添加或编辑文件,添加以下内容,并保存

 

#!/bin/bash

STARTHAPROXY="systemctl start haproxy"

STOPKEEPALIVED="systemctl stop keepalived"

LOGFILE="/opt/app/keepalived/log/keepalived-haproxy-state.log"

A=`ps -C haproxy --no-header |wc -l`

echo "[check_haproxystatus]" >>$LOGFILE

date >>$LOGFILE

if [ $A -eq 0 ];then

echo $STARTHAPROXY>> $LOGFILE

$STARTHAPROXY >> $LOGFILE  2>&1

sleep 2

fi

if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then

# 如果haproxy启动2秒后,检查还是未启动,可能是haproxy无法启动,可以去掉以下命令的注释,用于关闭keepalived,让备节点转成主节点

#echo $STOPKEEPALIVED>> $LOGFILE

#$STOPKEEPALIVED >> $LOGFILE  2>&1

exit 0

else

exit 1

fi

# 状态变化执行脚本

/etc/keepalived/scripts/haproxy_master.sh ,当本节点变为主节点时调用

vim /etc/keepalived/scripts/haproxy_master.sh  # 添加或编辑文件,添加以下内容,并保存

 

#!/bin/bash

STARTHAPROXY="/bin/systemctl restart haproxy"

# 检测haproxy进程已存在就kill掉

STOPHAPROXY=`ps -ef |grep /usr/sbin/haproxy | grep -v grep|awk '{print $2}'|xargs kill -s 9`

LOGFILE="/opt/app/keepalived/log/keepalived-haproxy-state.log"

 

echo "[master]" >> $LOGFILE

date >> $LOGFILE

echo "Being master...." >> $LOGFILE 2>&1

echo "stop haproxy...." >> $LOGFILE 2>&1

$STOPHAPROXY >> $LOGFILE 2>&1

echo "start haproxy...." >> $LOGFILE 2>&1

$STARTHAPROXY >> $LOGFILE 2>&1

echo "haproxy stared ..." >> $LOGFILE

/etc/keepalived/scripts/haproxy_backup.sh ,当本节点变为备节点时调用

vim /etc/keepalived/scripts/haproxy_backup.sh  # 添加或编辑文件,添加以下内容,并保存

 

#!/bin/bash

STARTHAPROXY="/bin/systemctl restart haproxy"

STOPHAPROXY=`ps -ef |grep /usr/sbin/haproxy | grep -v grep|awk '{print $2}'|xargs kill -s 9`

LOGFILE="/opt/app/keepalived/log/keepalived-haproxy-state.log"

 

echo "[backup]" >> $LOGFILE

date >> $LOGFILE

echo "Being backup...." >> $LOGFILE 2>&1

echo "stop haproxy...." >> $LOGFILE 2>&1

$STOPHAPROXY >> $LOGFILE 2>&1

echo "start haproxy...." >> $LOGFILE 2>&1

$STARTHAPROXY >> $LOGFILE 2>&1

echo "haproxy stared ..." >> $LOGFILE

/etc/keepalived/scripts/haproxy_fault.sh ,当fault时调用

vim /etc/keepalived/scripts/haproxy_fault.sh  # 添加或编辑文件,添加以下内容,并保存

 

#!/bin/bash

LOGFILE="/opt/app/keepalived/log/keepalived-haproxy-state.log"

echo "[fault]" >> $LOGFILE

date >> $LOGFILE

/etc/keepalived/scripts/haproxy_stop.sh ,当节点停止时调用

vim /etc/keepalived/scripts/haproxy_stop.sh  # 添加或编辑文件,添加以下内容,并保存

 

#!/bin/bash

LOGFILE="/opt/app/keepalived/log/keepalived-haproxy-state.log"

echo "[stop]" >> $LOGFILE

date >> $LOGFILE

systemctl enable keepalived

systemctl restart keepalived

 

# 查看主节点网卡上绑定的VIP

inet 192.168.56.113/32 scope global enp0s8 为keepalived新增的虚ip

以上步骤相同,配置文件如下

! 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 keep2

   #vrrp_skip_check_adv_addr

   #vrrp_strict

   vrrp_garp_interval 0

   vrrp_gna_interval 0

}

 

# 定期调用check_haproxy.sh脚本检查mycat运行状态

vrrp_script chk_http_port {

   script "/etc/keepalived/scripts/check_haproxy.sh"

   interval 3

   weight 2

}

 

vrrp_instance VI_1 {

    state BACKUP  # 备服务器用 BACKUP

    interface enp0s8  # 实际网卡的名称

    virtual_router_id 51  # 主备服务器这个ID必须一致才能切换

    priority 100   # 备服务器的值要低于主库的值

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    virtual_ipaddress {

        192.168.56.113 # VIP 地址

    }

 

    track_script {

    # 调用脚本 check_haproxy.sh 检查 haproxy 是否存活(mycat刚刚加的那个服务)

       chk_http_port

    }

# keepalived 状态变化时执行相应脚本

    # 当此keepalived节点变为主时执行

    notify_master /etc/keepalived/scripts/haproxy_master.sh

    # 当此keepalived节点变为备时执行

    notify_backup /etc/keepalived/scripts/haproxy_backup.sh

    # 当此keepalived节点fault时执行

    notify_fault  /etc/keepalived/scripts/haproxy_fault.sh

    # 当此keepalived节点停止时执行

    notify_stop   /etc/keepalived/scripts/haproxy_stop.sh

}

 

# 启动keepalived

systemctl enable keepalived

systemctl restart keepalived

 

# 验证keepalived

* 在主备keepalived服务器上安装haproxy主备

安装haproxy

yum install -y haproxy

修改haproxy的配置文件

cd /etc/haproxy

cp haproxy.cfg haproxy.cfg_bak

vim haproxy.cfg

 

global

    log         127.0.0.1 local2

 

    chroot      /var/lib/haproxy

    pidfile     /var/run/haproxy.pid

    maxconn     4000

    user        haproxy

    group       haproxy

    daemon

    stats socket /var/lib/haproxy/stats

 

defaults

    mode                    http

    log                     global

    option                  httplog

    option                  dontlognull

    option http-server-close

    #option forwardfor       except 127.0.0.0/8

    option                  redispatch

    retries                 3

    timeout http-request    10s

    timeout queue           1m

    timeout connect         10s

    timeout client          1m

    timeout server          1m

    timeout http-keep-alive 10s

    timeout check           10s

timeout tunnel          1h

    timeout client-fin      30s

    maxconn                 3000

# 绑定到keep1主机的本地网卡上,该页面为haproxy的统计页面,用于查看请求转发等状态

listen admin_status 0.0.0.0:48800 ##VIP

    stats uri /admin-status ## 统计页面

    stats auth admin:admin

    mode http

    option httplog

# 转发到mycat 8066业务端口,服务绑定在VIP上

listen allmycat_service 192.168.56.113:8067 ## 转发到 mycat 的 8066 端口,即 mycat 的服务端口

    mode tcp

    option tcplog

    option tcpka

    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www

    balance roundrobin

    server mycat_1 192.168.56.111:8066 check port 48700 inter 5s rise 2 fall 3

    server mycat_2 192.168.56.112:8066 check port 48700 inter 5s rise 2 fall 3

    timeout server 20000

# 转发到mycat 9066管理端口,服务绑定在VIP上

listen allmycat_admin 192.168.56.113:9067 ## 转发到 mycat 的 9066 端口,及 mycat 的管理控制台端口

    mode tcp

    option tcplog

    option tcpka

    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www

    balance roundrobin

    # 48700 为mycat主机利用xinetd提供的状态check服务,5s检查一次

    server mycat_1 192.168.56.111:9066 check port 48700 inter 5s rise 2 fall 3

    server mycat_2 192.168.56.112:9066 check port 48700 inter 5s rise 2 fall 3

    timeout server 20000

# 如下图所示,图中标示1与2 修改了高可用IP对外监听的端口,因为跟mycat部署在一台,必须要修改成其它的端口,否则haproxy启动不起来

启动haproxy

systemctl start haproxy

配置haproxy日志记录

默认情况haproxy是不记录日志的,为了记录日志还需要配置 syslog 模块,在 linux 下是 rsyslogd 服务

yum install –y rsyslog

修改/etc/rsyslog.conf配置文件最后加上

local2.*     /var/log/haproxy.log

新增文件 /etc/rsyslog.d/haproxy.conf,内容如下

$ModLoad imudp

$UDPServerRun 514

local2.* /var/log/haproxy.log


# 重启

systemctl restart rsyslog

systemctl restart haproxy

查看日志 /var/log/haproxy.log

tail -f /var/log/haproxy.log

防火墙配置

firewall-cmd --permanent --zone=public --add-port=48800/tcp

firewall-cmd --permanent --zone=public --add-port=8067/tcp

firewall-cmd --permanent --zone=public --add-port=9067/tcp

firewall-cmd --reload


登陆任意同一局域网主机(需要有mysql客户端工具)

# ping VIP 可以通

# 通过VIP连接到了mycat集群的管理端口

mysql -u root -h 192.168.56.113 -P 9067 -p

# 查看mycat连接

show @@connection;

mysql -u root -h 192.168.56.113 -P 8067 -p

use test;

CREATE TABLE app_users (

     id BIGINT ( 20 ) NOT NULL ,

     `name` VARCHAR ( 20 ) NOT NULL ,

     ` desc ` VARCHAR ( 100 ),

     PRIMARY KEY ( id )

     ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

 

# 插入数据测试

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 1 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 2 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 10 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 5000000 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 5000001 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 5000002 , 'xiemus' , 'goods' );

INSERT INTO app_users(id,`name`,` desc `) VALUES ( 8000000 , 'xiemus' , 'goods' );

# 如下语句解析,实际发送到两个dn进行查询

explain select * from app_users;

# 根据分片键精准定位到dn1

explain select * from app_users where id =1;

# 根据分片键精准定位到dn2

explain select * from app_users where id =5000001;



----------------------END---------------------------------

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/70000068/viewspace-2777485/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
本人从事oracle、mysql、postgresql等数据库管理多年,具备丰富的实战经验,同时维护大型企业的Linux操作系统、vmware虚拟化、openstack云计算平台,具有部署、优化、故障处理等经验。

注册时间:2021-05-16

  • 博文量
    49
  • 访问量
    34186