1mysql
前言linux
在應用程序中,應用配置鏈接的數據庫IP地址和端口號都是固定一個的,當所屬IP地址的服務器宕機後,須要人爲手工更改IP地址切換數據庫服務器。同時當應用接收到成千上萬的併發 http 請求時,會致使服務器消耗大量系統資源,輕則響應速度下降,嚴重的甚至會引起宕機。nginx
爲了充分合理的利用服務器資源,提升數據服務的性能和穩定性,在較低成本的前提下,保證在部分服務器宕機或發生故障的狀況下不影響業務的正常運做。本文主要介紹 Nginx+Keepalived 鏈接 SequoiaDB -MySQL 實例的高可用方案與實踐。web
2算法
SequoiaDB 數據庫介紹sql
SequoiaDB 巨杉數據庫是一款徹底自研的金融級分佈式數據庫產品,採用計算與存儲分離架構,由數據庫實例層和數據庫存儲引擎層組成。數據庫實例層負責解析請求並轉發至數據庫存儲引擎層處理,同時會將數據庫存儲引擎層的響應結果反饋給應用層,數據庫實例層支持包括針對結構化數據的 MySQL 實例、PostgreSQL 實例、SparkSQL 實例,以及針對非結構化數據的 S3 和 PosixFS 文件系統的對象存儲實例實例,而數據庫存儲引擎層是由 SequoiaDB 巨杉數據庫的協調節點、編目節點和數據節點組成。該數據庫集羣架構能方便用戶實現由傳統數據庫到巨杉數據庫的無縫遷移,減小應用開發者的開發和學習成本。數據庫
2.1bash
SequoiaDB MySQL實例 的關係服務器
如圖所示是 SequoiaDB 巨杉數據庫集羣的邏輯架構圖,用戶由圖可知,應用程序實際是經過計算層的實例節點鏈接、訪問數據庫。例如圖中所示,應用程序能夠直接經過 MySQL 的 JDBC 驅動鏈接、訪問 SequoiaDB 數據庫集羣。網絡
SequoiaDB 數據庫的存儲層是一個可以支持分佈式事務、多中心容災的分佈式存儲集羣。
SequoiaDB 的分佈式存儲層,其中包括:協調節點、編目節點和數據庫節點三類角色節點。分佈式存儲層中的全部節點均支持多節點部署,支持分佈式水平擴展和高可用容災功能。
計算層中的 MySQL 實例和分佈式存儲引擎的鏈接,能夠經過多協調節點的負載均衡功能實現高可用和避免單點故障。而在傳統的應用程序中,應用程序經過 JDBC 鏈接 MySQL 時,通常只會填寫一個服務器的IP 地址和端口號。在這種架構中,爲了解決 MySQL 鏈接的單點故障隱患,會在應用服務器和數據庫服務器中間,搭建一層負載均衡服務,以實現應用程序和數據庫鏈接的高可用切換。
2.2
傳統解決方案
在過去企業級解決方案中,爲了解決數據庫的高可用問題,通常會在數據庫服務器與外部網絡之間安裝負載均衡器(如F5),從而避免由於某臺服務器宕機而對業務形成影響。
雖然這種硬件負載均衡技術較爲成熟,在過去的企業重要系統中均有部署使用,但該種方案須要額外購買價格高昂的負載均衡設備,成本比較高。
3
Nginx+Keepalived 解決方案
3.1
總體架構
本方案與傳統解決方案的思路一致,在數據庫服務器與外部網絡之間新增負載均衡層,惟一不一樣的是傳統解決方案使用負載均衡器,而本方案採用 Nginx+Keepalived 來實現負載均衡。該種解決方案採用純軟件的方式,實現多機器的數據庫服務器統一固定一個IP 地址和服務端口,部署方式靈活。
具體部署架構以下圖所示,Nginx 反向代理三臺數據庫服務器的 MySQL 及負載使用實例,將3306端口映射到3307端口,而應用程序服務器會經過 Keepalived 虛擬IP地址的 Nginx 反向代理端口3307來鏈接三臺數據庫服務器的 MySQL 實例。
VRRP 技術能夠將兩臺或者多臺物理路由器設備虛擬成一個虛擬路由器,這個虛擬路由器經過虛擬IP(192.168.81.100)對外提供服務。
在虛擬路由器內部,同一時間只有一臺物理路由器在對外提供服務,這臺物理路由器被稱爲主路由器(Master),通常而言Master經過選舉算法產生,它擁有對外服務的虛擬IP,提供各類網絡功能。而其餘物理路由器不擁有對外的虛擬IP,僅僅接收 Master 的 VRRP 狀態通告信息,這部分路由器叫作備份路由器(Slave)。
當主路由器失效的時候,備份路由器從新進行選舉,產生一個新的路由器成爲 Master。以下圖所示,當主路由器(Master)宕機後,備份路由器(Slave)進行選舉成爲Master,而後接管虛擬IP,繼續對外提供服務,對應用程序服務器而言,整個切換過程是對應用程序透明,無任何影響。
3.2
Nginx 產品介紹
Nginx (engine x) 是一個高性能的 HTTP 和反向代理 web 服務器,同時也提供了 IMAP/POP3/SMTP 服務。Nginx是一款輕量級的 Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,在 BSD-like 協議下發行。其特色是佔有內存少,併發能力強,事實上Nginx的併發能力在同類型的網頁服務器中表現較好。
Nginx 有很強的代理功能,可是僅在一臺服務器部署 Nginx 服務,依然存在 Nginx 單點故障的問題,所以在高可用負載均衡解決方案中,Nginx 須要結合 Keepalived 軟件解決單點故障問題。
Nginx+Keepalived 雙機實現 Nginx 反向代理服務的高可用,保證任意服務器宕機,或者是任何 Nginx 服務被意外中止,也會不影響業務的正常運做。
3.3
Keepalived 產品介紹
Keepalived 軟件的做用是檢測服務器的狀態。
在部署了 Keepalived 服務的軟件中,若是一臺服務器意外宕機,或工做出現故障, Keepalived 軟件將會檢測到該問題服務器,並將有故障的服務器從系統中剔除。
同時,Keepalived 軟件會自動使用其餘服務器代替該問題服務器的工做。當問題服務器從新正常工做後,Keepalived 軟件又會自動將原來問題服務器加入到服務器列表中。整個高可用切換工做所有由 Keepalived 軟件自動感知,自動切換,無任何需人工干涉。
4
Nginx+Keepalived 安裝部署
假設存在如下的服務器環境環境,後續內容將介紹如何經過 Keepalived + Nginx 軟件實現 SequoiaDB 數據庫的 MySQL 實例高可用部署:
4.1
部署前環境檢查
檢查 selinux 狀態是否爲 disabled
sestatus
使用 root 權限,打開 /etc/selinux/config 文件
vi /etc/selinux/config
將 SELINUX 調整成 disabled
SELINUX=disabled
SELINUXTYPE=targeted
重啓操做系統以使SELINUX 設置生效
reboot
安裝依賴插件
yum install -y gcc pcre pcre-devel openssl openssl-devel gd gd-devel net-snmp-agent-libs
4.2
Nginx 安裝與部署
4.2.1 Nginx 安裝
經過如下命令下載 Nginx 安裝包
wget https://nginx.org/download/nginx-1.16.0.tar.gz
解壓並安裝
tar -zxvf nginx-1.16.0.tar.gz
cd nginx-1.16.0
./configure --prefix=/usr/local/nginx --with-stream
make && make install
4.2.2 Nginx部署
打開 Nginx 配置文件
vi /usr/local/nginx/conf/nginx.conf
修改 Nginx 配置文件,新增如下內容,stream 段的配置要與 http 段在同級目錄。新增內容表示將13四、135和136 服務器的 3306 服務加入到 Nginx 的負載均衡中,而且 Nginx 對外發布 3307 的服務端口。
stream {
upstream sequoiadb-mysql {
server 192.168.81.134:3306 weight=1;
server 192.168.81.135:3306 weight=1;
server 192.168.81.136:3306 weight=1;
}
server { listen 3307; proxy_connect_timeout 5s; proxy_timeout 300s; proxy_pass sequoiadb-mysql; }
}
添加全局命令
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
測試安裝
nginx -V
預期返回結果
nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
configure arguments: --prefix=/usr/local/nginx
新建Nginx服務腳本
vi /etc/init.d/nginx
新增如下內容
#!/bin/sh
#nginx - this script starts and stops the nginx daemin
# chkconfig: - 85 15
description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
processname: nginx
config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
賦予nginx服務腳本權限
chmod 755 /etc/init.d/nginx
添加Nginx到系統服務
chkconfig --add nginx
啓動 Nginx 服務
systemctl start nginx.service
設置 Nginx 爲開機自啓動
systemctl enable nginx.service
檢查 Nginx 服務
systemctl status nginx.service
預期返回結果
● nginx.service - SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server
Loaded: loaded (/etc/rc.d/init.d/nginx; bad; vendor preset: disabled)
Active: active (running) since Fri 2020-01-17 01:03:12 PST; 36s ago
Docs: man:systemd-sysv-generator(8)
Main PID: 407 (nginx)
CGroup: /system.slice/nginx.service
├─407 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
└─409 nginx: worker process
Jan 17 01:03:12 sdb2 systemd[1]: Starting SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server...
Jan 17 01:03:12 sdb2 nginx[394]: Starting nginx: [ OK ]
Jan 17 01:03:12 sdb2 systemd[1]: PID file /usr/local/nginx/logs/nginx.pid not readable (yet?) after start.
Jan 17 01:03:12 sdb2 systemd[1]: Started SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server.
經過 Nginx 登陸 MySQL 實例
mysql -h 192.168.81.134 -uroot -P 3307 -proot
預期返回結果
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 5
Server version: 5.7.25 Source distribution
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
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.
mysql>
4.3
Keepalived 安裝與部署
4.3.1 Keepalived 安裝
用戶經過如下命令下載 Keepalived 安裝包
wget https://www.keepalived.org/software/keepalived-2.0.19.tar.gz
解壓並安裝
tar -zxvf keepalived-2.0.19.tar.gz
cd keepalived-2.0.19
./configure --prefix=/usr/local/keepalived
make && make install
4.3.2 Keepalived 部署
添加全局命令
ln -s /usr/local/keepalived/sbin/keepalived /usr/bin/keepalived
測試安裝
keepalived -v
預期返回結果
Keepalived v2.0.19 (10/19,2019)
Copyright(C) 2001-2019 Alexandre Cassen, <acassen@gmail.com>
Built with kernel headers for Linux 3.10.0
Running on Linux 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017
configure options: --prefix=/usr/local/keepalived
Config options: LVS VRRP VRRP_AUTH OLD_CHKSUM_COMPAT FIB_ROUTING
System options: PIPE2 SIGNALFD INOTIFY_INIT1 VSYSLOG EPOLL_CREATE1 IPV6_ADVANCED_API RTA_ENCAP RTA_EXPIRES FRA_TUN_ID RTAX_CC_ALGO RTAX_QUICKACK FRA_OIFNAME IFA_FLAGS IP_MULTICAST_ALL NET_LINUX_IF_H_COLLISION LIBIPTC_LINUX_NET_IF_H_COLLISION VRRP_VMAC IFLA_LINK_NETNSID CN_PROC SOCK_NONBLOCK SOCK_CLOEXEC O_PATH GLOB_BRACE INET6_ADDR_GEN_MODE SO_MARK SCHED_RT SCHED_RESET_ON_FORK
新建 Nginx 檢查腳本
vi /usr/local/keepalived/nginx_check.sh
添加如下內容
#!/bin/bash
A=ps -C nginx --no-header |wc -l
if [ $A -eq 0 ];then
/usr/sbin/nginx
sleep 2
if [ ps -C nginx --no-header |wc -l
-eq 0 ];then
killall keepalived
fi
fi
賦予檢查腳本可執行權限
chmod +x /usr/local/keepalived/nginx_check.sh
打開 Keepalived 配置文件
vi /usr/local/keepalived/etc/keepalived/keepalived.conf
修改主 Keepalived 的配置文件
! Configuration File for keepalived
global_defs {
router_id sdb1
}
vrrp_script chk_nginx {
script "/usr/local/keepalived/nginx_check.sh"
interval 3
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 66
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.81.100
}
}
修改備 Keepalived 的配置文件
! Configuration File for keepalived
global_defs {
router_id sdb2
}
vrrp_script chk_nginx {
script "/usr/local/keepalived/nginx_check.sh"
interval 3
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 66
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.81.100
}
}
修改配置文件路徑vi /usr/local/keepalived/etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -f /usr/local/keepalived/etc/keepalived/keepalived.conf"
啓動 Keepalived 服務
systemctl start keepalived.service
設置 Keepalived 爲開機自啓動
systemctl enable keepalived.service
檢查 Keepalived 服務
systemctl status keepalived.service
預期返回結果
keepalived.service - LVS and VRRP High Availability Monitor
Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2020-01-17 07:52:10 PST; 1min 45s ago
Process: 76416 ExecStart=/usr/local/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 76417 (keepalived)
CGroup: /system.slice/keepalived.service
├─76417 /usr/local/keepalived/sbin/keepalived -D -f /usr/local/keepalived/etc/keepalived/keepalived.conf
└─76418 /usr/local/keepalived/sbin/keepalived -D -f /usr/local/keepalived/etc/keepalived/keepalived.conf
檢查 Master 和 Backup 的虛擬IP地址
ip addr show ens33
Master 預期返回結果,部分截取inet 192.168.81.134/24 brd 192.168.81.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.81.100/32 scope global ens33
valid_lft forever preferred_lft forever
Backup 預期返回結果,部分截取
inet 192.168.81.135/24 brd 192.168.81.255 scope global ens33
valid_lft forever preferred_lft forever
經過虛擬IP地址登陸 MySQL 實例
mysql -h 192.168.81.100 -uroot -P 3307 -proot
預期返回結果
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 5
Server version: 5.7.25 Source distribution
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
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.
mysql>
4.4
Keepalived + Nginx 實現負載均衡高可用
用戶經過 Navicat 鏈接MySQL數據庫,IP 使用Keepalived 提供的虛擬IP 地址,MySQL實例的端口爲Nginx 提供的3307 服務端口。
由於 sdb1 服務器部署的 Keepalived 爲 Master,因此 Navicat 鏈接的是這臺機器,經過執行 netstat 命令能夠確認
[root@sdb1 ~]# netstat -nap|grep 3307
tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 1393/nginx: master
tcp 0 0 192.168.81.100:3307 192.168.81.1:53385 ESTABLISHED 1395/nginx: worker
tcp 0 0 192.168.81.100:3307 192.168.81.1:53380 ESTABLISHED 1395/nginx: worker
若是主動關閉 sdb1 服務器
shutdown -h now
而後繼續檢查sdb2的虛擬IP地址
ip addr show ens33
預期返回結果,部分截取
inet 192.168.81.135/24 brd 192.168.81.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.81.100/32 scope global ens33
valid_lft forever preferred_lft forever
若是此時主動關閉sdb2 服務器的MySQL服務
service sequoiasql-mysql stop
在Navicat 中繼續查詢一張表的數據,顯示查詢成功。
81.136:3306 192.168.81.135:49646 ESTABLISHED 1388/mysqld
unix 2 [ ACC ] STREAM LISTENING 22202 1388/mysqld /opt/sequoiasql/mysql/database/3306/mysqld.sock
經過以上驗證步驟,能夠證實 Keepalived 軟件可以實現多服務器之間虛擬 IP 地址自動漂移,Nginx 服務可以自動實現 MySQL 實例的負載均衡。用戶用過 Keepalived 軟件和 Nginx 服務,最終實現了在對應用零影響的狀況下,實現了 SequoiaDB 數據庫集羣的多 MySQL 實例的負載均衡高可用功能。
5
總結
本文介紹瞭如何經過 Nginx+Keepalived 雙機實現數據庫實例的高可用,用戶能夠經過 Nginx+Keepalived 解決方案來實現應用經過一個 IP 地址和端口號來訪問多個 MySQ 實例,保證在任意一臺機器宕機或 MySQL 服務中止的時候,應用也能基於同一個 IP 地址來訪問 SequoiaDB 數據庫。