MariaDB集羣搭建(Galera)

這裡分享一篇mysql集群部署方式,採用的是MariaDB多主方式(Multi-Master),適合用在高可用環境中。一般3個節點之上有一個高可用VIP(HAProxy + Keepalived),對開發者而言,只有一個數據庫IP。3個節點掛掉一個,不會影響使用,運維及時恢復即可。那麼我們先看看集群需要的菜譜:

  • 三臺服務器ubuntu14.04

  • 192.168.3.1

  • 192.168.3.2

  • 192.168.3.3

  • MariaDB(10.1,因為10.1之後自帶Gelera,無需單獨安裝)

  • Gelera(10.1之前版本需要單獨安裝)

  • rsync (集群互相學習使用的默認同步方式)

MariaDB集群搭建(Galera)

1. 軟件安裝

sudo apt-get install software-properties-common

sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://mirrors.tuna.tsinghua.edu.cn/mariadb/repo/10.1/ubuntu trusty main'

sudo apt-get update

sudo apt-get install rsync mariadb-server

安裝軟件後,首先把mysql服務停掉,完成配置後在啟動。

2. 配置項

這裡集群最少3臺服務器,防止網絡波動出現腦裂問題。3個服務器配置是相同的,如下:

vim /etc/mysql/my.cnf

# * Galera-related settings

#

[galera]

# Mandatory settings

wsrep_on=ON

wsrep_provider=/usr/lib/libgalera_smm.so

wsrep_cluster_address="gcomm://192.168.3.1,192.168.3.2,192.168.3.3"

binlog_format=row

default_storage_engine=InnoDB

innodb_autoinc_lock_mode=2

wsrep_cluster_name="MariaDB_Cluster"

#

# Allow server to accept connections on all interfaces.

#

bind-address=0.0.0.0

#

# Optional setting

#wsrep_slave_threads=1

#innodb_flush_log_at_trx_commit=0

3. 啟動集群

這裡順序比較重要,在其中一臺服務器上執行語句:

service mysql start --wsrep-new-cluster

該語句是利用此節點創建一個集群節點,作為初始節點。其他兩臺服務器使用正常的啟動就可以了,不需要使用其他參數:如下

service mysql start

如果遇到問題:ERROR 1045 (28000): Access denied for user 'debian-sys-maint'@'localhost' (using password: YES)

因為集群中使用debian-sys-maint用戶登錄,而用戶的密碼是配置在debian.cnf中的,所有解決辦法:

  1. 找到debian.cnf中的password,並修改成例如newxxx

  2. 使用語句重新設置debian-sys-maint的密碼。語句見下面

  3. 重新啟動集群。

set password for 'debian-sys-maint'@'localhost'=password('newxxx');

4. 驗證集群

分別登錄3個節點

mysql -uxxx -pxxxx

使用語句查看集群狀態,wsrep_cluster_size = 3,其他參數注意觀察,對後續運維很重要。

show status like 'wsrep_*';

MariaDB集群搭建(Galera)

last_comitted故障恢復使用

MariaDB集群搭建(Galera)

箭頭參數,運維注意

5.集群說明(有看頭)

雖然多個數據庫節點實現了高可用,但這裡帶來一個架構問題,數據一致性問題,在併發較高,對事務要求比較嚴格的應用中會出現問題。

業務場景:

會員A在平臺預定了一個產品,在9點整自動下單,此時會從會員中扣除費用。如果在扣費的過程中,A也充值了,很可能就會出現問題。

最根本的原因:事務沒有鎖住會員賬戶。這裡牽扯到了兩個事務,分別是扣費事務和充值事務。而這兩個事務很可能不在同一個數據庫節點上,例如扣費事務在01節點鎖住賬戶,並更新餘額。02節點沒來得及學習,充值事務就來了,02節點也鎖住了賬戶,完成了更新,並釋放鎖後學習了01的更新,導致02節點丟失了充值事務的操作。

有頻繁更新且對事務要求比較嚴格的時候,就不要考慮使用這種方式,這種方式適合寫多、併發更新少的場景。

Q:有辦法避免事務不一致的問題嗎?

A:改為讀寫分離的代碼實現,完美解決上述問題。選擇其中兩個節點做VIP,另外一個做Master。注意使用sharding-jdbc,引入maven後數據源配置如下。

代碼示例:

MariaDB集群搭建(Galera)

用圖片看代碼更爽

注意:同一線程且同一數據庫連接內,如有寫入操作,以後的讀操作均從主庫讀取,用於保證數據一致性。所有使用這種方式,能滿足絕大多數業務場景了。

感謝您的閱讀,不足之處,還望指正。有疑問,可留言。


分享到:


相關文章: