CentOS7+ keepalived+ haproxy搭建Mycat高可用及負載均衡

dba_sam發表於2021-06-20

   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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章