MariaDB Galera Cluster介紹
Galera Cluster是Codership公司開發的一套免費開源的高可用方案,Galera Cluster即安裝了Galera的Mariadb集羣。其本身具有multi-master特性,支持多點寫入。Galera Cluster的三個(或多個)節點是對等關係,每個節點均支持寫入,集羣內部會保證寫入數據的一致性與完整性。
官網:
http://galeracluster.com
文檔:
https://galeracluster.com/library/documentation/index.html
官方給出的特性如下:
- 真正的多主集羣,Active-Active架構,即所有節點可以同時讀寫數據庫;
- 同步複製,沒有複製延遲;
- 多線程複製;
- 沒有主從切換操作,無需使用虛IP;
- 熱備份,單個節點故障期間不會影響數據庫業務;
- 支持節點自動加入,無需手動拷貝數據,自動的節點成員控制,失效節點自動被清除;新節點加入數據自動複製;
- 支持InnoDB存儲引擎;
- 對應用程序透明,原生MySQL接口;
- 無需做讀寫分離;
- 部署使用簡單。
galera集羣缺點:
- 加入新節點時開銷大,需要複製完整數據;
- 不能有效地解決寫擴展的問題,所有的寫操作都發生在所有的節點;
- 有多少個節點,就有多少份重複的數據;
- 由於事務提交需要跨節點通信,即涉及分佈式事務操作,因此寫入會比主從複製慢很多,節點越多,寫入越慢,死鎖和回滾也會更加頻繁;
- 對網絡要求比較高,如果網絡出現波動不穩定,則可能會造成兩個節點失聯,Galera Cluster集羣會發生腦裂,服務將不可用.
- 僅支持InnoDB/XtraDB存儲引擎,任何寫入其他引擎的表,包括mysql.*表都不會被複制,DDL語句可以複製,但是insert into mysql.user(MyISAM存儲引擎)之類的插入數據不會被複制;
- Delete操作不支持沒有主鍵的表,因爲沒有主鍵的表在不同的節點上的順序不同,如果執行select … limit …將出現不同的結果集;
- 整個集羣的寫入吞吐量取決於最弱的節點限制,集羣要使用同一的配置.
mariadb galera mult-master replication集羣
基於認證的複製原理
https://galeracluster.com/library/documentation/tech-desc-introduction.html
Galera集羣的複製功能基於Galeralibrary實現,爲了讓MySQL與Galera library通訊,特別針對MySQL開發了wsrep API。
Galera插件保證集羣同步數據,保持數據的一致性,靠的就是可認證的複製,工作原理如下圖:
Galera集羣的複製功能是基於認證的複製,其流程如下:
- 當客戶端發出一個commit的命令,在事務被提交之前,所有對數據庫的更改都會被write-set收集起來,並且將write-set紀錄的內容發送給其他節點。
- write-set將在每個節點進行認證測試,測試結果決定着節點是否應用write-set更改數據。
- 如果認證測試失敗,節點將丟棄write-set;如果認證測試成功,則事務提交。
mariadb Galera集羣部署
參考:https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/
準備3個centos 7節點部署galera集羣。
關閉防火牆和selinxu
systemctl disable --now firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0
配置主機名
hostnamectl set-hostname xxx
配置主機名解析
cat > /etc/hosts <<EOF
192.168.93.11 galera1
192.168.93.12 galera2
192.168.93.13 galera3
EOF
安裝mariadb
https://mariadb.com/kb/en/yum/#installing-mariadb-galera-cluster-with-yum
#配置yum源
cat > /etc/yum.repos.d/mariadb.repo <<EOF
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF
#替換爲中科大源
sed -i 's#yum\.mariadb\.org#mirrors.ustc.edu.cn/mariadb/yum#' /etc/yum.repos.d/mariadb.repo
#安裝mariadb、galera和rsync,其中galera作爲依賴自動安裝
yum install -y MariaDB-server MariaDB-client rsync
配置mariadb-galera-cluste
https://mariadb.com/kb/en/configuring-mariadb-galera-cluster/
https://galeracluster.com/library/training/tutorials/galera-on-aws.html
galera1節點
cat > /etc/my.cnf.d/server.cnf <<EOF
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
bind-address=0.0.0.0
user=mysql
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=128M
binlog_format=ROW
log-error=/var/log/mysqld.log
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
wsrep_node_name='galera1'
wsrep_node_address="192.168.93.11"
wsrep_cluster_name='galera-cluster'
wsrep_cluster_address="gcomm://192.168.93.11,192.168.93.12,192.168.93.13"
wsrep_provider_options="gcache.size=300M; gcache.page_size=300M"
wsrep_slave_threads=4
wsrep_sst_method=rsync
EOF
galera2節點
cat > /etc/my.cnf.d/server.cnf <<EOF
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
bind-address=0.0.0.0
user=mysql
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=128M
binlog_format=ROW
log-error=/var/log/mysqld.log
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
wsrep_node_name='galera2'
wsrep_node_address="192.168.93.12"
wsrep_cluster_name='galera-cluster'
wsrep_cluster_address="gcomm://192.168.93.11,192.168.93.12,192.168.93.13"
wsrep_provider_options="gcache.size=300M; gcache.page_size=300M"
wsrep_slave_threads=4
wsrep_sst_method=rsync
EOF
galera3節點
cat > /etc/my.cnf.d/server.cnf <<EOF
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
bind-address=0.0.0.0
user=mysql
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=128M
binlog_format=ROW
log-error=/var/log/mysqld.log
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
wsrep_node_name='galera3'
wsrep_node_address="192.168.93.13"
wsrep_cluster_name='galera-cluster'
wsrep_cluster_address="gcomm://192.168.93.11,192.168.93.12,192.168.93.13"
wsrep_provider_options="gcache.size=300M; gcache.page_size=300M"
wsrep_slave_threads=4
wsrep_sst_method=rsync
EOF
當使用xtrabackup方式進行熱備時,需要修改wsrep_sst_method並創建同步賬號,而rsync方式不需要。
啓動集羣,在集羣任意一個節點上執行
galera_new_cluster
systemctl enable mariadb
另外2個節點執行
systemctl enable --now mariadb
驗證集羣狀態,默認未配置密碼直接回車:
[root@galera1 ~]# mysql -uroot -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"
Enter password:
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
驗證數據同步
在galera1節點新建數據庫galera_test,然後在galera2和galera3節點查詢,如果可以查詢到galera_test庫,說明數據同步成功,集羣運行正常。
[root@galera1 ~]# mysql -e "create database galera_test"
[root@galera2 ~]# mysql -e "show databases;"
+--------------------+
| Database |
+--------------------+
| galera_test |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
[root@galera3 ~]# mysql -e "show databases;"
+--------------------+
| Database |
+--------------------+
| galera_test |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
配置lb
參考:
https://galeracluster.com/library/documentation/ha-proxy.html
https://www.shuzhiduo.com/A/QW5YywmY5m/
3個節點安裝haproxy和keepalived
yum install -y haproxy keepalived
修改keepalived配置文件,使用非搶佔模式,每個節點配置相同,注意修改interface參數和virtual_ipaddress地址
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id galera
}
vrrp_script check_haproxy {
script "pidof haproxy"
interval 2
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.93.20
}
track_script {
check_haproxy
}
}
EOF
修改haproxy配置文件,每個節點配置相同
cat > /etc/haproxy/haproxy.cfg <<EOF
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen haproxy_stats
bind *:1080
mode http
balance roundrobin
stats uri /haproxy-stats
stats auth admin:admin
listen galera
bind *:3307
balance roundrobin
mode tcp
option tcpka
option mysql-check user haproxy
server galera1 192.168.93.11:3306 check weight 1
server galera2 192.168.93.12:3306 check weight 1
server galera3 192.168.93.13:3306 check weight 1
EOF
任意節點創建haproxy針對數據庫檢查用戶haproxy
CREATE USER 'haproxy'@'%';
3個節點啓動啓動haproxy和keepalived服務
systemctl enable --now haproxy keepalived
查看vip在哪個節點,可以停止某個節點或vip所在節點haproxy服務,驗證vip會發生漂移:
[root@galera1 ~]# ip a | grep 93
inet 192.168.93.11/24 brd 192.168.93.255 scope global ens33
inet 192.168.93.20/32 scope global ens33
查看haproxy狀態:http://192.168.93.20:8084/haproxy-stats,用戶名密碼admin/admin。
配置maraidb root用戶允許遠程連接,任意節點執行即可:
#默認未配置密碼,直接回車即可
mysql -uroot -p
#配置遠程連接
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
客戶端通過vip的3307端口可以成功訪問galera集羣
mysql -uroot -p123456 -h192.168.93.20 -P 3307
重新啓動集羣
MariaDB galera cluster 所有節點服務全部停止後再次啓動會報錯,需要按照以下方法啓動集羣
[root@galera1 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid: 8460aa9c-9c82-11ea-b458-0a6235722174
seqno: -1
safe_to_bootstrap: 1
修改safe_to_bootstrap參數改爲1,然後在該節點執行以下命令啓動第一個節點,執行以下命令後參數會被重新置爲0:
galera_new_cluster
然後啓動另外2個節點:
systemctl start mariadb
集羣狀態監控
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'wsrep_%';
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_local_state_uuid | 8460aa9c-9c82-11ea-b458-0a6235722174 |
| wsrep_protocol_version | 10 |
| wsrep_last_committed | 10 |
| wsrep_replicated | 0 |
| wsrep_replicated_bytes | 0 |
| wsrep_repl_keys | 0 |
| wsrep_repl_keys_bytes | 0 |
| wsrep_repl_data_bytes | 0 |
| wsrep_repl_other_bytes | 0 |
| wsrep_received | 4 |
| wsrep_received_bytes | 568 |
| wsrep_local_commits | 0 |
| wsrep_local_cert_failures | 0 |
| wsrep_local_replays | 0 |
| wsrep_local_send_queue | 0 |
| wsrep_local_send_queue_max | 1 |
| wsrep_local_send_queue_min | 0 |
| wsrep_local_send_queue_avg | 0 |
| wsrep_local_recv_queue | 0 |
| wsrep_local_recv_queue_max | 2 |
| wsrep_local_recv_queue_min | 0 |
| wsrep_local_recv_queue_avg | 0.25 |
| wsrep_local_cached_downto | 4 |
| wsrep_flow_control_paused_ns | 0 |
| wsrep_flow_control_paused | 0 |
| wsrep_flow_control_sent | 0 |
| wsrep_flow_control_recv | 0 |
| wsrep_cert_deps_distance | 0 |
| wsrep_apply_oooe | 0 |
| wsrep_apply_oool | 0 |
| wsrep_apply_window | 0 |
| wsrep_commit_oooe | 0 |
| wsrep_commit_oool | 0 |
| wsrep_commit_window | 0 |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |
| wsrep_cert_index_size | 0 |
| wsrep_causal_reads | 0 |
| wsrep_cert_interval | 0 |
| wsrep_open_transactions | 0 |
| wsrep_open_connections | 0 |
| wsrep_incoming_addresses | AUTO,AUTO,AUTO |
| wsrep_cluster_weight | 3 |
| wsrep_desync_count | 0 |
| wsrep_evs_delayed | |
| wsrep_evs_evict_list | |
| wsrep_evs_repl_latency | 0/0/0/0/0 |
| wsrep_evs_state | OPERATIONAL |
| wsrep_gcomm_uuid | 67444d22-9c91-11ea-9774-cbf0d4795cf0 |
| wsrep_applier_thread_count | 4 |
| wsrep_cluster_capabilities | |
| wsrep_cluster_conf_id | 3 |
| wsrep_cluster_size | 3 |
| wsrep_cluster_state_uuid | 8460aa9c-9c82-11ea-b458-0a6235722174 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_local_bf_aborts | 0 |
| wsrep_local_index | 0 |
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <[email protected]> |
| wsrep_provider_version | 26.4.4(r4599) |
| wsrep_ready | ON |
| wsrep_rollbacker_thread_count | 1 |
| wsrep_thread_count | 5 |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
65 rows in set (0.001 sec)
單獨查看cluster_status
MariaDB [(none)]> SHOW STATUS LIKE 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+
1 row in set (0.001 sec)
參數說明:
- wsrep_local_index = 2 在集羣中的索引值
- wsrep_cluster_status爲Primary,表示節點爲主節點,正常讀寫。
- wsrep_ready爲ON,表示集羣正常運行。
- wsrep_connected: 如果該值爲Off,且wsrep_ready的值也爲Off,則說明該節點沒有連接到集羣
- wsrep_cluster_size爲3,表示集羣有三個節點。
- wsrep_cluster_state_uuid:在集羣所有節點的值應該是相同的,有不同值的節點,說明其沒有連接入集羣。
- wsrep_cluster_conf_id:正常情況下所有節點上該值是一樣的.如果值不同,說明該節點被臨時”分區”了.當節點之間網絡連接恢復的時候應該會恢復一樣的值。
- wsrep_flow_control_paused:表示複製停止了多長時間.即表明集羣因爲Slave延遲而慢的程度.值爲0~1,越靠近0越好,值爲1表示複製完全停止.可優化wsrep_slave_threads的值來改善.
- wsrep_flow_control_sent:表示該節點已經停止複製了多少次.