冰河,能不能講講如何實現MySQL數據存儲的無限擴容?

寫在前面

隨着互聯網的高速發展,企業中沉澱的數據也越來越多,這就對數據存儲層的擴展性要求越來越高。當今互聯網企業中,大部分企業使用的是MySQL來存儲關係型數據。如何實現MySQL數據存儲層的高度可擴展性成為了互聯網企業必須要解決的問題。那麼,如何實現真正意義上的MySQL無限擴容呢?今天,冰河就來以實戰的角度為大家講講如何實現MySQL數據庫的無限擴容。

文章已收錄到://github.com/sunshinelyz/technology-binghe//gitee.com/binghe001/technology-binghe,小夥伴們別忘記給個小星星哦~~

概述

本文是在《海量數據架構下如何保證Mycat的高可用?》一文的基礎上進一步擴展,從而實現數據存儲層每一個環節的高可用,從而實現MySQL的無限擴容。

要解決的問題

在《海量數據架構下如何保證Mycat的高可用?》一文中,我們的架構圖如下:

由上圖可以看出,HAProxy存在單點隱患,一旦這個HAProxy服務宕機,那麼整個服務架構將不可用。那麼,如何解決HAProxy存在的單點隱患問題呢?這就是這篇博文要解決的問題。

軟件版本

  • 操作系統:CentOS-6.8-x86_64
  • JDK版本:jdk1.8
  • HAProxy版本:haproxy-1.5.19.tar.gz
  • Mycat版本:Mycat-server-1.6(自行下載源碼編譯)
  • keepalived版本:keepalived-1.2.18.tar.gz
  • MySQL版本:mysql-5.7.tar.gz

部署規劃

高可用負載均衡集群部署架構

上圖中簡化了數據存儲部分的架構細節。例如,其中對於架構中的每一個部分,我們都可以單獨進行擴展,獨立成集群對外提供服務,而不會存在單點故障的問題。

圖解說明:

(1) HAProxy 實現了 Mycat 多節點的集群高可用和負載均衡, 而 HAProxy 自身的高可用則可以通過Keepalived 來實現。 因此, HAProxy 主機上要同時安裝 HAProxy 和 Keepalived, Keepalived 負責為該服務器搶佔 vip(虛擬 ip,圖中的 192.168.209.130),搶佔到 vip 後,對該主機的訪問可以通過原來的 ip(192.168.209.135)訪問,也可以直接通過 vip(192.168.209.130)訪問。

(2) Keepalived 搶佔 vip 有優先級, 在 keepalived.conf 配置中的 priority 屬性決定。但是一般哪台主機上的 Keepalived服務先啟動就會搶佔到 vip,即使是 slave,只要先啟動也能搶到(要注意避免 Keepalived的資源搶佔問題)。

(3) HAProxy 負責將對 vip 的請求分發到 Mycat 集群節點上, 起到負載均衡的作用。 同時 HAProxy 也能檢測到 Mycat 是否存活, HAProxy 只會將請求轉發到存活的 Mycat 上。

(4) 如果 Keepalived+HAProxy 高可用集群中的一台服務器宕機, 集群中另外一台服務器上的 Keepalived會立刻搶佔 vip 並接管服務, 此時搶佔了 vip 的 HAProxy 節點可以繼續提供服務。

(5) 如果一台 Mycat 服務器宕機, HAPorxy 轉發請求時不會轉發到宕機的 Mycat 上,所以 Mycat 依然可用。

綜上: Mycat 的高可用及負載均衡由 HAProxy 來實現,而 HAProxy 的高可用,由 Keepalived 來實現。

HAProxy 節點 2 的部署

HAProxy 主機 2(liuyazhuang136, 192.168.209.136)的安裝部署請參考博文《海量數據架構下如何保證Mycat的高可用?》,注意配置文件的調整:多節點部署時 haproxy.cfg 配置文件中的 node 、 description 配置的值要做相應調整。

HAProxy 主機 2(liuyazhuang136, 192.168.209.136)上的HAProxy配置如下:

## global配置中的參數為進程級別的參數,通常與其運行的操作系統有關

global

log 127.0.0.1 local0 info ## 定義全局的syslog服務器,最多可以定義2個

### local0是日誌設備,對應於/etc/rsyslog.conf中的配置,默認回收info的日誌級別

#log 127.0.0.1 local1 info

chroot /usr/share/haproxy ## 修改HAProxy的工作目錄至指定的目錄並在放棄權限之前執行

### chroot() 操作,可以提升 haproxy 的安全級別

group haproxy ## 同gid,不過這裡為指定的用戶組名

user haproxy ## 同uid,但這裡使用的為用戶名

daemon ## 設置haproxy後台守護進程形式運行

nbproc 1 ## 指定啟動的haproxy進程個數,

### 只能用於守護進程模式的haproxy;默認為止啟動1個進程,

### 一般只在單進程僅能打開少數文件描述符的場中中才使用多進程模式

maxconn 4096 ## 設定每個haproxy進程所接受的最大並發連接數,

### 其等同於命令行選項"-n","ulimit-n"自動計算的結果正式參照從參數設定的

# pidfile /var/run/haproxy.pid ## 進程文件(默認路徑 /var/run/haproxy.pid)

node liuyazhuang136 ## 定義當前節點的名稱,用於HA場景中多haproxy進程共享同一個IP地址時

description liuyazhuang136 ## 當前實例的描述信息

## defaults:用於為所有其他配置段提供默認參數,這默認配置參數可由下一個"defaults"所重新設定

defaults

log global ## 繼承global中log的定義

mode http ## mode:所處理的模式 (tcp:四層 , http:七層 , health:狀態檢查,只會返回OK)

### tcp: 實例運行於純tcp模式,在客戶端和服務器端之間將建立一個全雙工的連接,

#### 且不會對7層報文做任何類型的檢查,此為默認模式

### http:實例運行於http模式,客戶端請求在轉發至後端服務器之前將被深度分析,

#### 所有不與RFC模式兼容的請求都會被拒絕

### health:實例運行於health模式,其對入站請求僅響應「OK」信息並關閉連接,

#### 且不會記錄任何日誌信息 ,此模式將用於相應外部組件的監控狀態檢測請求

option httplog

retries 3

option redispatch ## serverId對應的服務器掛掉後,強制定向到其他健康的服務器

maxconn 2000 ## 前端的最大並發連接數(默認為2000)

### 其不能用於backend區段,對於大型站點來說,可以儘可能提高此值以便讓haproxy管理連接隊列,

### 從而避免無法應答用戶請求。當然,此最大值不能超過「global」段中的定義。

### 此外,需要留心的是,haproxy會為每個連接維持兩個緩衝,每個緩存的大小為8KB,

### 再加上其他的數據,每個連接將大約佔用17KB的RAM空間,這意味着經過適當優化後 ,

### 有着1GB的可用RAM空間時將維護40000-50000並發連接。

### 如果指定了一個過大值,極端場景中,其最終所佔據的空間可能會超過當前主機的可用內存,

### 這可能會帶來意想不到的結果,因此,將其設定一個可接受值放為明智絕對,其默認為2000

timeout connect 5000ms ## 連接超時(默認是毫秒,單位可以設置us,ms,s,m,h,d)

timeout client 50000ms ## 客戶端超時

timeout server 50000ms ## 服務器超時

## HAProxy的狀態信息統計頁面

listen admin_stats

bind :48800 ## 綁定端口

stats uri /admin-status ##統計頁面

stats auth admin:admin ## 設置統計頁面認證的用戶和密碼,如果要設置多個,另起一行寫入即可

mode http

option httplog ## 啟用日誌記錄HTTP請求

## listen: 用於定義通過關聯「前端」和「後端」一個完整的代理,通常只對TCP流量有用

listen mycat_servers

bind :3307 ## 綁定端口

mode tcp

option tcplog ## 記錄TCP請求日誌

option tcpka ## 是否允許向server和client發送keepalive

option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www ## 後端服務狀態檢測

### 向後端服務器的48700端口(端口值在後端服務器上通過xinetd配置)發送 OPTIONS 請求

### (原理請參考HTTP協議) ,HAProxy會根據返回內容來判斷後端服務是否可用.

### 2xx 和 3xx 的響應碼錶示健康狀態,其他響應碼或無響應表示服務器故障。

balance roundrobin ## 定義負載均衡算法,可用於"defaults"、"listen"和"backend"中,默認為輪詢方式

server mycat_01 192.168.209.133:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10

server mycat_02 192.168.209.134:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10

## 格式:server <name> <address>[:[port]] [param*]

### serser 在後端聲明一個server,只能用於listen和backend區段。

### <name>為此服務器指定的內部名稱,其將會出現在日誌及警告信息中

### <address>此服務器的IPv4地址,也支持使用可解析的主機名,但要在啟動時需要解析主機名至響應的IPV4地址

### [:[port]]指定將客戶端連接請求發往此服務器時的目標端口,此為可選項

### [param*]為此server設定的一系列參數,均為可選項,參數比較多,下面僅說明幾個常用的參數:

#### weight:權重,默認為1,最大值為256,0表示不參與負載均衡

#### backup:設定為備用服務器,僅在負載均衡場景中的其他server均不可以啟用此server

#### check:啟動對此server執行監控狀態檢查,其可以藉助於額外的其他參數完成更精細的設定

#### inter:設定監控狀態檢查的時間間隔,單位為毫秒,默認為2000,

##### 也可以使用fastinter和downinter來根據服務器端專題優化此事件延遲

#### rise:設置server從離線狀態轉換至正常狀態需要檢查的次數(不設置的情況下,默認值為2)

#### fall:設置server從正常狀態轉換至離線狀態需要檢查的次數(不設置的情況下,默認值為3)

#### cookie:為指定server設定cookie值,此處指定的值將會在請求入站時被檢查,

##### 第一次為此值挑選的server將會被後續的請求所選中,其目的在於實現持久連接的功能

#### maxconn:指定此服務器接受的最大並發連接數,如果發往此服務器的連接數目高於此處指定的值,

#####其將被放置於請求隊列,以等待其他連接被釋放

HAProxy 節點 1 的狀態信息頁://192.168.209.135:48800/admin-status

HAProxy 節點 2 的狀態信息頁://192.168.209.136:48800/admin-status

Keepalived 介紹

官網: //www.keepalived.org/

Keepalived 是一種高性能的服務器高可用或熱備解決方案, Keepalived 可以用來防止服務器單點故障的發生,通過配合 Haproxy 可以實現 web 前端服務的高可用。Keepalived 以 VRRP 協議為實現基礎,用 VRRP 協議來實現高可用性(HA)。 VRRP(Virtual Router Redundancy Protocol)協議是用於實現路由器冗餘的協議, VRRP 協議將兩台或多台路由器設備虛擬成一個設備,對外提供虛擬路由器 IP(一個或多個),而在路由器組內部,如果實際擁有這個對外 IP 的路由器如果工作正常的話就是 MASTER,或者是通過算法選舉產生。 MASTER 實現針對虛擬路由器 IP 的各種網絡功能,如 ARP 請求, ICMP,以及數據的轉發等;其他設備不擁有該虛擬 IP,狀態是 BACKUP,除了接收 MASTER 的VRRP 狀態通告信息外,不執行對外的網絡功能。當主機失效時, BACKUP 將接管原先 MASTER 的網絡功能。VRRP 協議使用多播數據來傳輸 VRRP 數據, VRRP 數據使用特殊的虛擬源 MAC 地址發送數據而不是自身網卡的 MAC 地址, VRRP 運行時只有 MASTER 路由器定時發送 VRRP 通告信息,表示 MASTER 工作正常以及虛擬路由器 IP(組), BACKUP 只接收 VRRP 數據,不發送數據,如果一定時間內沒有接收到 MASTER 的通告信息,各 BACKUP 將宣告自己成為 MASTER,發送通告信息,重新進行 MASTER 選舉狀態。

Keepalived 的安裝

注意:需要在192.168.209.135、 192.168.209.136兩台服務器上安裝Keepalived。

Keepalived (//www.keepalived.org/download.html

上傳或下載 keepalived

上傳或下載 keepalived(keepalived-1.2.18.tar.gz) 到 /usr/local/src 目錄

解壓安裝

安裝 keepalived 需要用到 openssl

# yum install gcc gcc-c++ openssl openssl-devel
# cd /usr/local/src
# tar -zxvf keepalived-1.2.18.tar.gz
# cd keepalived-1.2.18
# ./configure --prefix=/usr/local/keepalived
# make && make install

將 keepalived 安裝成 Linux 系統服務

因為沒有使用 keepalived 的默認路徑安裝(默認是/usr/local) ,安裝完成之後,需要做一些工作
複製默認配置文件到默認路徑

# mkdir /etc/keepalived
# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

複製 keepalived 服務腳本到默認的地址

# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
# ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/
# ln -s /usr/local/keepalived/sbin/keepalived /sbin/

設置 keepalived 服務開機啟動

# chkconfig keepalived on

修改 Keepalived 配置文件

(1) MASTER 節點配置文件(192.168.209.135)

! Configuration File for keepalived
global_defs {
## keepalived 自帶的郵件提醒需要開啟 sendmail 服務。建議用獨立的監控或第三方 SMTP
	router_id liuyazhuang135 ## 標識本節點的字條串,通常為 hostname
}
## keepalived 會定時執行腳本並對腳本執行的結果進行分析,動態調整 vrrp_instance 的優先級。
## 如果腳本執行結果為 0,並且 weight 配置的值大於 0,則優先級相應的增加。
## 如果腳本執行結果非 0,並且 weight 配置的值小於 0,則優先級相應的減少。
## 其他情況,維持原本配置的優先級,即配置文件中 priority 對應的值。
vrrp_script chk_haproxy {
	script "/etc/keepalived/haproxy_check.sh" ## 檢測 haproxy 狀態的腳本路徑
	interval 2 ## 檢測時間間隔
	weight 2 ## 如果條件成立,權重+2
}
## 定義虛擬路由, VI_1 為虛擬路由的標示符,自己定義名稱
vrrp_instance VI_1 {
	state BACKUP ## 默認主設備(priority 值大的)和備用設備(priority 值小的)都設置為 BACKUP,
	## 由 priority 來控制同時啟動情況下的默認主備,否則先啟動的為主設備
	interface eth3 ## 綁定虛擬 IP 的網絡接口,與本機 IP 地址所在的網絡接口相同,我的是 eth3
	virtual_router_id 35 ## 虛擬路由的 ID 號,兩個節點設置必須一樣,可選 IP 最後一段使用,
	## 相同的 VRID 為一個組,他將決定多播的 MAC 地址
	priority 120 ## 節點優先級,值範圍 0-254, MASTER 要比 BACKUP 高
	nopreempt ## 主設備(priority 值大的)配置一定要加上 nopreempt,否則非搶佔也不起作用
	advert_int 1 ## 組播信息發送間隔,兩個節點設置必須一樣,默認 1s
	## 設置驗證信息,兩個節點必須一致
	authentication {
		auth_type PASS
		auth_pass 1111 ## 真實生產,按需求對應該過來
	}
	## 將 track_script 塊加入 instance 配置塊
	track_script {
		chk_haproxy ## 檢查 HAProxy 服務是否存活
	}
	## 虛擬 IP 池, 兩個節點設置必須一樣
	virtual_ipaddress {
		192.168.209.130 ## 虛擬 ip,可以定義多個,每行一個
	}
}

(2)BACKUP 節點配置文件(192.168.209.136)

! Configuration File for keepalived
global_defs {
	router_id liuyazhuang136
}
vrrp_script chk_haproxy {
	script "/etc/keepalived/haproxy_check.sh"
	interval 2
	weight 2
}
vrrp_instance VI_1 {
	state BACKUP
	interface eth3
	virtual_router_id 35
	priority 110
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	track_script {
		chk_haproxy
	}
	virtual_ipaddress {
		192.168.209.130
	}
}

特別注意: 如果非搶佔模式不生效, 在 Keepalived 的故障節點恢復後會再次導搶佔 vip,從而因 vip 切換而閃斷帶來的風險(視頻解說)。 按以上配置,配置了 Keepalived 非搶佔模式, 配置及注意點如下:
(1) 主設備、 從設備中的 state 都設置為 BACKUP
(2) 主設備、從設備中都不要配置 mcast_src_ip (本機 IP 地址)
(3) 默認主設備(priority 值大的 Keepalived 節點) 配置一定要加上 nopreempt,否則非搶佔不起作用
(4) 防火牆配置允許組播(主、備兩台設備上都需要配置, keepalived 使用 224.0.0.18 作為 Master 和Backup 健康檢查的通信 IP)

# iptables -I INPUT -i eth3 -d 224.0.0.0/8 -p vrrp -j ACCEPT
# iptables -I OUTPUT -o eth3 -d 224.0.0.0/8 -p vrrp -j ACCEPT
(eth3 為主機的網卡設備名稱,生產環境服務器可以用獨立網卡來處理組播和心跳檢測等)
# service iptables save
重啟防火牆:
# service iptables restart

編寫 Haproxy 狀態檢測腳本

我們編寫的腳本為/etc/keepalived/haproxy_check.sh (已在 keepalived.conf 中配置)
腳本要求:如果 haproxy 停止運行,嘗試啟動,如果無法啟動則殺死本機的 keepalived 進程,keepalied將虛擬 ip 綁定到 BACKUP 機器上。

內容如下:

# mkdir -p /usr/local/keepalived/log
# vi /etc/keepalived/haproxy_check.sh

haproxy_check.sh腳本內容如下:

#!/bin/bash
START_HAPROXY="/etc/rc.d/init.d/haproxy start"
STOP_HAPROXY="/etc/rc.d/init.d/haproxy stop"
LOG_FILE="/usr/local/keepalived/log/haproxy-check.log"
HAPS=`ps -C haproxy --no-header |wc -l`
date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE
echo "check haproxy status" >> $LOG_FILE
if [ $HAPS -eq 0 ];then
echo $START_HAPROXY >> $LOG_FILE
$START_HAPROXY >> $LOG_FILE 2>&1
sleep 3
if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
echo "start haproxy failed, killall keepalived" >> $LOG_FILE
killall keepalived
fi
fi

保存後,給腳本賦執行權限:

# chmod +x /etc/keepalived/haproxy_check.sh

啟動 Keepalived

# service keepalived start
Starting keepalived: [ OK ]

Keepalived 服務管理命令:

停止: service keepalived stop
啟動: service keepalived start
重啟: service keepalived restart
查看狀態: service keepalived status

高可用測試

(1)關閉 192.168.209.135 中的 Haproxy, Keepalived 會將它重新啟動

# service haproxy stop

(2)關閉 192.168.209.135 中的 Keepalived, VIP(192.168.209.130) 會被 192.168.209.136 搶佔

# service keepalived stop

由上圖可知:Keepalived 停止後, 192.168.209.135 節點的網絡接口中的 VIP(192.168.209.130) 將消失

此時,由上圖可知:在192.168.209.136節點的網絡接口中會出現 VIP(192.168.209.130)。

查看此時 VIP 對應的 MAC, Windows 下使用 CMD 命令查看:

說明此時 VIP 已經漂移到物理主機 192.168.209.136上了

再通過 VIP(192.168.209.130) 來訪問 Haproxy 集群, 訪問到的也是 192.168.209.136

(3)重新啟動 192.168.209.135 中的 Keepalived

重新啟動 192.168.209.135 中的 Keepalived, vip(192.168.209.130)保留在 192.168.209.136 主機上, 不會出現 135 啟動搶佔 vip 的情況。

# service keepalived start

(4)模擬搶佔了 vip 的節點(192.168.209.136) 中的 HAProxy 故障或啟動失敗

方式:把 192 節點中的 haproxy.cfg 文件重命名為 haproxy.cfg_bak, 並把 haproxy 服務進行 kill 掉,此時 keepalived 會嘗試去啟動 haproxy,會由於找不到配置文件而啟動失敗,此時就會進行 haproxy_check.sh腳本中的 killall keepalived 命令,結束 keepalived 進行。隨後就是 192.168.209.135 節點重新搶佔 vip

說明此時 VIP 已經漂移到物理主機 192.168.209.135上了

再通過 VIP(192.168.209.130) 來訪問 Haproxy 集群, 訪問到的也是 192.168.209.135

驗證數據庫訪問

通過 vip 訪問數據庫、驗證 vip 切換後的數據庫訪問

(1)命令行訪問數據庫

(2)Navicat訪問數據庫

至此,Mycat高可用負載均衡集群的實現(HAProxy + Keepalived + Mycat)搭建完畢

大家可以到鏈接//download.csdn.net/detail/l1028386804/9915621下載搭建Mycat高可用負載均衡集群的實現(HAProxy + Keepalived + Mycat)使用的Keepalived

其他推薦文章

重磅福利

微信搜一搜【冰河技術】微信公眾號,關注這個有深度的程序員,每天閱讀超硬核技術乾貨,公眾號內回復【PDF】有我準備的一線大廠面試資料和我原創的超硬核PDF技術文檔,以及我為大家精心準備的多套簡歷模板(不斷更新中),希望大家都能找到心儀的工作,學習是一條時而鬱鬱寡歡,時而開懷大笑的路,加油。如果你通過努力成功進入到了心儀的公司,一定不要懈怠放鬆,職場成長和新技術學習一樣,不進則退。如果有幸我們江湖再見!

另外,我開源的各個PDF,後續我都會持續更新和維護,感謝大家長期以來對冰河的支持!!