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 集群节点之间的同步使用的是单独一个网卡,前端的请求则是另一个网卡,也就是数据库集群服务器使用的是双网卡。