MariaDB MaxScale 是一個數據庫代理,它擴展了 MariaDB Server 的高可用性,可伸縮性和安全性,同時經過將其與底層數據庫基礎架構分離來簡化應用程序開發,採用可擴展的體系結構設計,支持插件,將其功能擴展到透明負載平衡以外,成爲數據庫防火牆。 經過內置多個路由器,過濾器和協議的插件,MariaDB MaxScale 能夠配置爲根據業務和技術要求轉發數據庫請求和修改數據庫響應。例如,屏蔽敏感數據或擴展讀取,讀寫分離等等。php
MariaDB Galera Cluster 是 MariaDB 的同步多主集羣。 它僅在 Linux 上可用,而且僅支持 XtraDB / InnoDB 存儲引擎。簡單來講就是一個多主架構的數據庫集羣。前端
這裏使用 MaxScale 作數據庫代理,數據庫代理後端則使用 Galera Cluster,固然實際生產還須要 MaxScale 配合 Keepalived 作高可用,並使用 vip 地址作數據庫對外使用的地址。node
[root@db-proxy ~]# cat /etc/maxscale.cnf [maxscale] threads=4 log_debug=0 [db01] type=server address=db01.ssgwo.com port=3306 protocol=MySQLBackend priority=11 [db02] type=server address=db02.ssgwo.com port=3306 protocol=MySQLBackend priority=12 [db03] type=server address=db03.ssgwo.com port=3306 protocol=MySQLBackend priority=13 [MySQL Monitor] type=monitor module=galeramon servers=db01,db02,db03 user=root passwd=test123 monitor_interval=10000 use_priority=true [Select_Query_Filter] type=filter module=namedserverfilter match=select options=ignorecase server=db02 [Read-Write Service] type=service router=readwritesplit servers=db01,db02,db03 user=root passwd=test123 enable_root_user=true max_slave_connections=1 use_sql_variables_in=master router_options=master_accept_reads=true filters=Select_Query_Filter [MaxAdmin Service] type=service router=cli [Read-Write Listener] type=listener service=Read-Write Service protocol=MySQLClient port=3306 [MaxAdmin Listener] type=listener service=MaxAdmin Service protocol=maxscaled socket=default
[root@db-proxy ~]# maxadmin list servers Servers. -------------------+-----------------+-------+-------------+-------------------- Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- db01 | db01.ssgwo.com | 3306 | 0 | Master, Synced, Running db02 | db02.ssgwo.com | 3306 | 0 | Slave, Synced, Running db03 | db03.ssgwo.com | 3306 | 0 | Slave, Synced, Running -------------------+-----------------+-------+-------------+--------------------
[root@db01 ~]# cat /etc/my.cnf.d/server.cnf [server] [mysqld] [galera] wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_address="gcomm://172.16.27.131,172.16.27.132,172.16.27.133" default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 bind-address=0.0.0.0 wsrep_cluster_name="ssgwo" wsrep_node_address="172.16.27.131" wsrep_sst_method=rsync max_connections=20480 max_connect_errors=10240 max_allowed_packet=34M wsrep_causal_reads=ON skip-character-set-client-handshake collation-server=utf8_bin character-set-server=utf8 wsrep_sst_donor="172.16.27.133,172.16.27.132," innodb_log_file_size=256M innodb_buffer_pool_size=1024M binlog_format=row general_log general_log_file=/var/log/mysql/queries.log slow_query_log slow_query_log_file=/var/log/mysql/slow.log #server_id="131" #log_slave_updates=1 #log_bin=binlog #expire_logs_days=7 [embedded] [mariadb] transaction-isolation = READ-COMMITTED log_bin_trust_function_creators = 1 net_read_timeout = 180 net_retry_count = 2 net_write_timeout = 180 [mariadb-10.0]
[root@db02 mysql]# cat /etc/my.cnf.d/server.cnf [server] [mysqld] [galera] wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_address="gcomm://172.16.27.131,172.16.27.132,172.16.27.133" default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 bind-address=0.0.0.0 wsrep_cluster_name="ssgwo" wsrep_node_address="172.16.27.132" wsrep_sst_method=rsync max_connections=20480 max_connect_errors=10240 max_allowed_packet=34M wsrep_causal_reads=ON skip-character-set-client-handshake collation-server=utf8_bin character-set-server=utf8 wsrep_sst_donor="172.16.27.133,172.16.27.132," innodb_log_file_size=256M innodb_buffer_pool_size=1024M binlog_format=row general_log general_log_file=/var/log/mysql/queries.log slow_query_log slow_query_log_file=/var/log/mysql/slow.log #server_id="132" #log_slave_updates=1 #log_bin=binlog #expire_logs_days=7 [embedded] [mariadb] transaction-isolation = READ-COMMITTED log_bin_trust_function_creators = 1 net_read_timeout = 180 net_retry_count = 2 net_write_timeout = 180 [mariadb-10.0]
[root@db03 mysql]# cat /etc/my.cnf.d/server.cnf [server] [mysqld] [galera] wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_address="gcomm://172.16.27.131,172.16.27.132,172.16.27.133" default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 bind-address=0.0.0.0 wsrep_cluster_name="ssgwo" wsrep_node_address="172.16.27.133" wsrep_sst_method=rsync max_connections=20480 max_connect_errors=10240 max_allowed_packet=34M wsrep_causal_reads=ON skip-character-set-client-handshake collation-server=utf8_bin character-set-server=utf8 wsrep_sst_donor="172.16.27.133,172.16.27.132," innodb_log_file_size=256M innodb_buffer_pool_size=1024M binlog_format=row general_log general_log_file=/var/log/mysql/queries.log slow_query_log slow_query_log_file=/var/log/mysql/slow.log #server_id="133" #log_slave_updates=1 #log_bin=binlog #expire_logs_days=7 [embedded] [mariadb] transaction-isolation = READ-COMMITTED log_bin_trust_function_creators = 1 net_read_timeout = 180 net_retry_count = 2 net_write_timeout = 180 [mariadb-10.0]
MariaDB [(none)]> show status like '%wsrep%'; +------------------------------+----------------------------------------------------------+ | Variable_name | Value | +------------------------------+----------------------------------------------------------+ | wsrep_local_state_uuid | 501ee58e-b8a4-11e8-86d2-36e60e7d9c84 | | wsrep_protocol_version | 7 | | wsrep_last_committed | 8 | | wsrep_replicated | 3 | | wsrep_replicated_bytes | 1373 | | wsrep_repl_keys | 3 | | wsrep_repl_keys_bytes | 93 | | wsrep_repl_data_bytes | 1088 | | wsrep_repl_other_bytes | 0 | | wsrep_received | 12 | | wsrep_received_bytes | 3040 | | 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.000000 | | wsrep_local_recv_queue | 0 | | wsrep_local_recv_queue_max | 2 | | wsrep_local_recv_queue_min | 0 | | wsrep_local_recv_queue_avg | 0.083333 | | wsrep_local_cached_downto | 1 | | wsrep_flow_control_paused_ns | 0 | | wsrep_flow_control_paused | 0.000000 | | wsrep_flow_control_sent | 0 | | wsrep_flow_control_recv | 0 | | wsrep_cert_deps_distance | 1.000000 | | wsrep_apply_oooe | 0.000000 | | wsrep_apply_oool | 0.000000 | | wsrep_apply_window | 1.000000 | | wsrep_commit_oooe | 0.000000 | | wsrep_commit_oool | 0.000000 | | wsrep_commit_window | 1.000000 | | wsrep_local_state | 4 | | wsrep_local_state_comment | Synced | | wsrep_cert_index_size | 2 | | wsrep_causal_reads | 13 | | wsrep_cert_interval | 0.000000 | | wsrep_incoming_addresses | 172.16.27.132:3306,172.16.27.133:3306,172.16.27.131:3306 | | wsrep_evs_delayed | | | wsrep_evs_evict_list | | | wsrep_evs_repl_latency | 0/0/0/0/0 | | wsrep_evs_state | OPERATIONAL | | wsrep_gcomm_uuid | a9c25806-b8a5-11e8-a058-e2a4949e7de5 | | wsrep_cluster_conf_id | 3 | | wsrep_cluster_size | 3 | | wsrep_cluster_state_uuid | 501ee58e-b8a4-11e8-86d2-36e60e7d9c84 | | wsrep_cluster_status | Primary | | wsrep_connected | ON | | wsrep_local_bf_aborts | 0 | | wsrep_local_index | 2 | | wsrep_provider_name | Galera | | wsrep_provider_vendor | Codership Oy <info@codership.com> | | wsrep_provider_version | 3.12(r9921e73) | | wsrep_ready | ON | | wsrep_thread_count | 2 | +------------------------------+----------------------------------------------------------+
這裏說明幾個比較關注的參數:
wsrep_provider:wsrep 庫的路徑
wsrep_node_name:當前數據庫節點的名稱,在集羣中不能重複
wsrep_sst_method:數據快照進行同步的方式,例如能夠選擇 rsync、mysqldump 等
wsrep_sst_donor:數據恢復時指定的供體,也就是指定哪一個節點做爲數據同步的提供者
若是須要從該集羣作主從複製,除了開啓 binlog 外,必定別忘了添加 log_slave_updates=1 參數mysql
若是隻是集羣的個別節點掛掉,一般重啓數據庫服務便可。若是數據庫集羣 down 掉,關於如何選擇節點中數據較爲最新的節點,能夠根據 wsrep_last_committed 的值來找到值最大的,成功啓動之後,再逐一啓用其餘節點:sql
MySQL [(none)]> show status like '%wsrep_last_committed%'; +----------------------+-----------+ | Variable_name | Value | +----------------------+-----------+ | wsrep_last_committed | 509679719 | +----------------------+-----------+
可是在咱們生產中並非採起這種方式恢復集羣的,咱們默認是選擇一個節點當作恢復集羣的主庫,也就是最早啓動的一個數據庫。由於一般咱們的業務全部數據庫請求基本都是經過 MaxScale 請求到後端的數據庫集羣,可是個別的一些開發環境因爲對數據庫寫的數據較大,咱們是單獨指定到數據庫集羣中的一個指定的數據庫節點的,後面集羣出現問題,咱們也是以這個指定的數據庫節點做爲恢復集羣的起始節點開始恢復集羣的。
首先咱們在第一個節點進行數據庫集羣的恢復時,使用如下命令啓用數據庫:數據庫
[root@db01 ~]# /etc/init.d/mysql bootstrap Bootstrapping the cluster.. Starting MySQL.. SUCCESS!
其餘節點則正常啓動數據庫服務便可,若是直接啓動數據庫服務不正常,則須要執行如下命令:bootstrap
[root@db02 ~]# mysqld --user=mysql --wsrep-cluster-address="gcomm://172.16.27.131,172.16.27.132,172.16.27.133"
上述這個命令同步會依照 wsrep_sst_method=rsync 來使用 rsync 而後根據參數 wsrep_sst_donor=」172.16.27.133,172.16.27.132,」 根據順序選擇最優的服務器做爲同步源。在數據全量同步的時候,做爲同步源的數據庫是不能正常處理讀寫請求的,它此時的狀態是供體(Donor)。上述命令由於配置參數 wsrep_sst_method 配置爲 rsync,因此使用 rsync 同步,咱們生產中 120G 左右的數據同步大概不到 30 分鐘。在節點同步恢復的過程當中,能夠看到後臺有 rsync 在進行數據同步,數據同步完成後,須要再啓用數據庫服務。判斷數據同時,可根據日誌觀察同步狀況。
也可以使用如下命令來查看當前節點狀態,下面的輸出是我某個節點是正常狀況下的輸出結果:後端
MySQL [(none)]> show status like 'wsrep_local_state_comment'; +---------------------------+--------+ | Variable_name | Value | +---------------------------+--------+ | wsrep_local_state_comment | Synced | +---------------------------+--------+
狀態說明:
Open:節點啓動成功,嘗試鏈接到集羣,若是失敗則根據配置退出或建立新的集羣
Primary:節點已處於集羣中,在新節點加入時,選取 donor 進行數據同步時會產生的狀態
Joiner:節點處於等待接收/接收同步文件時的狀態
Joined:節點完成數據同步,但有部分數據沒跟上,在嘗試保持和集羣進度一致的過程狀態。例如某個節點故障後,從新加入集羣,在追趕集羣進度時的狀態
Synced:節點正常提供服務的狀態,表示已經同步完成並和集羣進度保持一致
Donor:節點處於爲新節點提供全量數據數據同步時的狀態。此時該節點對客戶端不提供服務
這幾個參數是參考:http://zjzone.cc/index.php/2017/04/16/galera-ji-qun-hui-fu-di-chang-jian-qi-zhong-chang-jing/安全
上述 MaxScale 和 Galera 的配置都是從生產環境中拷貝通過ip的修改後在虛擬機運行的,因此沒有進行過多的測試。服務器
生產環境中的 MaxScale 使用 keepalived 作高可用,經過 vip 來提供數據庫服務。keepalived 網上的配置實在太多,這裏就不在贅述。Galera 集羣節點之間的同步使用的是單獨一個網卡,前端的請求則是另一個網卡,也就是數據庫集羣服務器使用的是雙網卡。