這裡分享一篇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 (集群互相學習使用的默認同步方式)
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中的,所有解決辦法:
找到debian.cnf中的password,並修改成例如newxxx
使用語句重新設置debian-sys-maint的密碼。語句見下面
重新啟動集群。
set password for 'debian-sys-maint'@'localhost'=password('newxxx');
4. 驗證集群
分別登錄3個節點
mysql -uxxx -pxxxx
使用語句查看集群狀態,wsrep_cluster_size = 3,其他參數注意觀察,對後續運維很重要。
show status like 'wsrep_*';
5.集群說明(有看頭)
雖然多個數據庫節點實現了高可用,但這裡帶來一個架構問題,數據一致性問題,在併發較高,對事務要求比較嚴格的應用中會出現問題。
業務場景:
會員A在平臺預定了一個產品,在9點整自動下單,此時會從會員中扣除費用。如果在扣費的過程中,A也充值了,很可能就會出現問題。
最根本的原因:事務沒有鎖住會員賬戶。這裡牽扯到了兩個事務,分別是扣費事務和充值事務。而這兩個事務很可能不在同一個數據庫節點上,例如扣費事務在01節點鎖住賬戶,並更新餘額。02節點沒來得及學習,充值事務就來了,02節點也鎖住了賬戶,完成了更新,並釋放鎖後學習了01的更新,導致02節點丟失了充值事務的操作。
有頻繁更新且對事務要求比較嚴格的時候,就不要考慮使用這種方式,這種方式適合寫多、併發更新少的場景。
Q:有辦法避免事務不一致的問題嗎?
A:改為讀寫分離的代碼實現,完美解決上述問題。選擇其中兩個節點做VIP,另外一個做Master。注意使用sharding-jdbc,引入maven後數據源配置如下。
代碼示例:
注意:同一線程且同一數據庫連接內,如有寫入操作,以後的讀操作均從主庫讀取,用於保證數據一致性。所有使用這種方式,能滿足絕大多數業務場景了。
感謝您的閱讀,不足之處,還望指正。有疑問,可留言。
閱讀更多 吳濤分享 的文章