【巨杉數據庫SequoiaDB】巨杉 Tech | SequoiaDB SQL實例高可用負載均衡實踐

1

前言

 

在應用程序中,應用配置連接的數據庫IP地址和端口號都是固定一個的,當所屬IP地址的服務器宕機後,需要人爲手工更改IP地址切換數據庫服務器。同時當應用接收到成千上萬的併發 http 請求時,會導致服務器消耗大量系統資源,輕則響應速度降低,嚴重的甚至會引發宕機。

 

爲了充分合理的利用服務器資源,提高數據服務的性能和穩定性,在較低成本的前提下,保證在部分服務器宕機或發生故障的情況下不影響業務的正常運作。本文主要介紹 Nginx+Keepalived 連接 SequoiaDB -MySQL 實例的高可用方案與實踐。

 

2

SequoiaDB 數據庫介紹

 

SequoiaDB 巨杉數據庫是一款完全自研的金融級分佈式數據庫產品,採用計算與存儲分離架構,由數據庫實例層和數據庫存儲引擎層組成。數據庫實例層負責解析請求並轉發至數據庫存儲引擎層處理,同時會將數據庫存儲引擎層的響應結果反饋給應用層,數據庫實例層支持包括針對結構化數據的 MySQL 實例、PostgreSQL 實例、SparkSQL 實例,以及針對非結構化數據的 S3 和 PosixFS 文件系統的對象存儲實例實例,而數據庫存儲引擎層是由 SequoiaDB 巨杉數據庫的協調節點、編目節點和數據節點組成。該數據庫集羣架構能方便用戶實現由傳統數據庫到巨杉數據庫的無縫遷移,減少應用開發者的開發和學習成本。

 

2.1

 

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

# This file controls the state of SELinux on the system.

# SELINUX= can take one of these three values:#     enforcing - SELinux security policy is enforced.#     permissive - SELinux prints warnings instead of enforcing.#     disabled - No SELinux policy is loaded.SELINUX=disabled# SELINUXTYPE= can take one of three two values:#     targeted - Targeted processes are protected,#     minimum - Modification of targeted policy. Only selected processes are protected. #     mls - Multi Level Security protection.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-streammake && make install

 

4.2.2 Nginx部署

 

打開 Nginx 配置文件

vi /usr/local/nginx/conf/nginx.conf

 

修改 Nginx 配置文件,新增以下內容,stream 段的配置要與 http 段在同級目錄。新增內容表示將134、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.0built 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 0nginx="/usr/local/nginx/sbin/nginx"prog=$(basename $nginx)NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"lockfile=/var/lock/subsys/nginxstart() {    [ -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 2esac

 

賦予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 5Server 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 itsaffiliates. Other names may be trademarks of their respectiveowners.
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/keepalivedmake && 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, <[email protected]>Built with kernel headers for Linux 3.10.0Running on Linux 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017configure options: --prefix=/usr/local/keepalivedConfig options:  LVS VRRP VRRP_AUTH OLD_CHKSUM_COMPAT FIB_ROUTINGSystem 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/bashA=`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    fifi

 

賦予檢查腳本可執行權限

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 foreverinet 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 5Server 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 itsaffiliates. Other names may be trademarks of their respectiveowners.
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 3307tcp        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 foreverinet 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 數據庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章