导读:
在之前,我们搭建了MysqL组复制集群环境,MysqL组复制集群环境解决了MysqL集群内部的自动故障转移,但是,组复制并没有解决外部业务的故障转移。举个例子,在A、B、C 3台机器上搭建了组复制环境,且运行在单主模式下,这里假设A为主节点,应用程序连接A写数据,如果A节点发生宕机,主节点切换到B机器上,此时,应用程序是不会自动连接到B服务器上的,需要人工进行切换。
在这篇文章中,我们要介绍的Proxysql就能够解决上面的问题,Proxysql能够实现业务层面故障转移、读写分离功能,当然Proxysql不仅仅只有这两项功能,还有更多的其它功能。其架构如下:
我们不妨来了解一下。
Proxysql是一款MysqL代理软件,其核心特点为读写分离、故障转移,详细其功能如下:
- 应用层代理。Proxysql不仅能够实现负载均衡,还可提供端到端连接处理、实时信息统计和数据库流量检查;
- 零停机时间变更。Proxysql在内存中直接进行配置修改,然后可以持久存储到磁盘和推送到运行中;
- 数据库防火墙。可充当应用程序与数据库之间的防火墙,使DBA可以保护数据库免受恶意活动或有问题的程序的影响;
- 高级查询规则。使用Proxysql丰富的查询规则定义查询路由,有效的分发和缓存数据,从而最大的提高数据库服务缓存效率;
- 数据分片与转换
- 故障转移检测。Proxysql通过连续监视数据库后端并在拓扑更改时将流量重新路由到运行正常的节点。
这里,我们使用Proxysql来对MysqL组复制环境实现读写分离以及故障转移。我的环境如下:
IP地址 | 主机名 | 用途 |
192.168.10.11 | mgr-node1 | MysqL组复制成员 |
192.168.10.12 | mgr-node2 | MysqL组复制成员 |
192.168.10.13 | mgr-node3 | MysqL组复制成员 |
192.168.10.10 | proxysql | Proxysql代理服务器 |
MysqL采用多主模式,搭建过程见文档:《MySQL组复制MGR(二)-- 组复制搭建》,本文把重点放在Proxysql的搭建与配置上。
(二)安装Proxysql
安装Proxysql,有2种方法,如果有网络,可以直接使用yum安装,如果没有网络,可以下载Proxysql发行包安装,下载地址为:https://github.com/sysown/proxysql/releases。这里为了方便,直接使用yum在线安装。
添加yum源,使用Linux root用户执行如下配置:
cat <<EOF | tee /etc/yum.repos.d/proxysql.repo [proxysql_repo] name= Proxysql YUM repository baseurl=https://repo.proxysql.com/Proxysql/proxysql-2.0.x/centos/\$releasever gpgcheck=1 gpgkey=https:repo.proxysql.com/Proxysql/repo_pub_key EOF
安装proxysql:
如果要查看安装的文件在哪,可以使用如下命令:
[root@proxysql yum.repos.d]# rpm -ql proxysql /etc/logrotate.d/proxysql /etc/proxysql.cnf /etc/systemd/system/proxysql-initial.service /etc/systemd/system/proxysql.service /usr/bin/proxysql /usr/share/proxysql/tools/proxysql_galera_checker.sh /usr/share/proxysql/tools/proxysql_galera_writer.pl
查看Proxysql进程:
查看端口,6032是proxysql的管理端口,6033是对外服务端口
启动Proxysql
service proxysql start
service proxysql stop
重启Proxysql
service proxysql restart
查看Proxysql的状态
service proxysql status
(四)Proxysql基础知识了解
Proxysql的配置,相对而言还是比较复杂的。因此,在配置Proxysql之前,我们需要对其架构有一些了解,这样在配置的时候,才不会一脸懵逼。
(4.1)Proxysql多层配置系统
前面我们说到Proxysql具有“零停机时间变更”功能,它是通过3层配置来实现的,3层配置包括:Runtime、Memory、Disk & Configuration File。
- Runtime层表示Proxysql工作线程使用的内存数据结构;
- Memory(也被称为main)层经由一个MysqL兼容接口露出的内存数据库,用户可以使用MysqL客户端连接到管理界面,查看、编辑Proxysql配置表;
- Disk & Configuration File。Disk层是一个存放在磁盘上的sqlite3数据库,Disk层可将内存中的配置信息保存到磁盘,以便Proxysql重新启动后配置还可用。
3个层面的信息有什么区别呢?我个人的理解是:3个层面保存的都是Proxysql的配置信息,如果管理员未作修改,那么3个层面的配置信息是相同的。如果管理员要修改配置信息,首先需要修改Memory层,要让修改的信息立刻生效,则需要把Memory层的变更信息推到Runtime层;要让修改的配置信息在Proxysql重启后还能保存下来,则需要把Memory层的信息推到Disk层。Runtime层是Proxysql正在使用的配置信息,Memory层是用户可以编辑的信息,Disk层可以把配置信息永久保存在磁盘上。
各层之间数据如何同步呢?我们可以看上图的箭头部分,通过load/save命令来实现同步。具体命令如下:
[1] LOAD <item> FROM MEMORY/LOAD <item> TO RUNTIME 将配置项从内存数据库加载到运行时数据结构 [2] SAVE <item> TO MEMORY/SAVE <item> FROM RUNTIME 将配置项从运行时保存到内存数据库中 [3] LOAD <item> TO MEMORY/LOAD <item> FROM DISK 将持久性配置项目从磁盘数据库加载到内存数据库 [4] SAVE <item> FROM MEMORY/SAVE <item> TO DISK 将配置项从内存数据库保存到磁盘数据库 [5] LOAD <item> FROM CONFIG 将配置项从配置文件加载到内存数据库中
常用的配置有:
(4.2)Proxysql的配置管理接口
Proxysql有2种配置方式:
Proxysql管理界面使用的是MysqL协议的界面,通过使用MysqL客户端连接到sqlite3进行配置的查询、管理。可以使用默认的admin用户连接到proxysql数据库。
[root@proxysql ~]# MysqL -uadmin -padmin -h127.0.0.1 -P6032 MysqL> show databases; +-----+---------------+-------------------------------------+ | seq | name | file | | 0 | main | | 2 disk /var/lib/proxysql/proxysql.db 3 | stats 4 | monitor 5 | stats_history /proxysql_stats.db ---+---------------+-------------------------------------+
这些数据库作用如下:
- main:内存配置数据库,使用此数据库,可以方便的查询和更新Proxysql的配置。与上面所曾配置系统的Memory层对应;
- disk:“main”数据库的磁盘镜像。重新启动Proxysql时,main中的数据就是从该数据库加载的。与上面所曾配置系统的disk层对应;
- stats:Proxysql收集的一些指标。如每个查询规则的匹配次数,当前正在运行的查询等;
- monitor:包含于Proxysql连接的后端服务器的指标。如连接带后端服务器对其进行ping操作的最小、最大时间;
(五)一步一步配置Proxysql--基础配置
(5.1)检查配置信息
查看相关配置表是否存在信息,因为还没开始配置,所以是不存在信息的,如果已经配置过了,可以先删除信息。
MysqL> select * from MysqL_servers; Empty set (0.00 sec) MysqL MysqL_users; Empty 0.01 MysqL_query_rules; Empty MysqL_group_replication_hostgroups; Empty 0.00 sec)
(5.2)组的配置
所谓组的配置,即定义读组、写组等,可以使用如下两个表来定义读写组:
- MysqL_replication_hostgroups:该表用于传统的master/slave的异步复制或者半同步复制的配置。
- MysqL_group_replication_hostgroups:该表用于MysqL Group Replication、InnoDB Cluster or Galera/Percona XtraDB Cluster的配置
因为我们这里是使用proxysql来实现MGR集群业务层面的实现故障转移以及读写分离的,所以配置MysqL_group_replication_hostgroups表即可,该表定义如下:
show create table MysqL_group_replication_hostgroups; ---------------------------------------------------------- CREATE TABLE MysqL_group_replication_hostgroups ( writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,backup_writer_hostgroup CHECK (backup_writer_hostgroup0 AND backup_writer_hostgroup<>writer_hostgroup) NULLINT CHECK (reader_hostgroup<>writer_hostgroup <>reader_hostgroup AND reader_hostgroup>0),offline_hostgroup CHECK (offline_hostgroupAND offline_hostgroup<>offline_hostgroup CHECK (active IN (0,1)) DEFAULT 1CHECK (max_writers >= 0) CHECK (writer_is_also_reader 1,1); font-weight: bold">2)) CHECK (max_transactions_behindVARCHARUNIQUE (reader_hostgroup),1)"> (offline_hostgroup),1)">UNIQUE (backup_writer_hostgroup))
这些字段含义如下:
- write_hostgroup:默认情况下会将所有流量发送到这个组。具有read_only=0的节点也将分配到这个组;
- backup_writer_hostgroup:如果集群有多个写节点(read_only=0)且超过了max_writers规定数量,则会把多出来的写节点放到备用写组里面;
- reader_hostgroup:读取的流量应该发送到该组,只读节点(read_only=1)会被分配到该组;
- offline_hostgroup:当Proxysql监视到某个节点不正常时,会被放入该组;
- active:是否启用主机组,当启用时,Proxysql将监视主机在各族之间移动;
- max_writers:最大写节点的数量,超过该值的节点应该被放入backup_write_hostgroup;
- writer_is_also_reader:一个节点既做写节点也做读节点,如果该值为2,则backup_writer_hostgroup的节点做读写点,但是writer_hostgroup不会做读节点;
我们对该表进行如下配置:
(5.3)视图添加
如果Proxysql是与组复制MGR一起使用的,那么还需要在MGR集群添加如下视图:
然后授权给监控用户,这里需要特别注意,我的监控用户在5.5.1步才创建,因此这一步需要放到5.5.1后执行:
MysqL_server表是用来存储Proxysql路由转换的MysqL节点的信息。
然后执行下面的命令生效:
(5.5)监控配置及检查
这里配置监控信息,用来监控Proxysql与后端的MysqL通信是否正常。
(5.5.1)监控用户配置
在Proxysql的变量表里面设定监控用户密码,用于Proxysql监控后端MysqL服务器的用户信息
需要注意,既然使用该用户监控后台MysqL数据库,那么后台MysqL数据库也需要创建该用户并授权,monitor用户需要有usage权限去连接、ping和检查read_only信息,如果要检测复制延迟,还需要具有replication client权限。特别注意,不能使用MysqL_users里面的用户来做监控用户。
注意:因为Proxysql+组复制添加了新的视图,见”5.3 视图添加”,因此还需授权:
(5.5.2)配置监控间隔
这里把连接、ping、read_only监控间隔改为2s,也可以根据需要改成其它,也可以不做修改
MysqLupdate global_variables set variable_value2000' -> in(MysqL-monitor_connect_intervalMysqL-monitor_ping_intervalMysqL-monitor_read_only_interval); Query OK,1)">3 rows affected (0.00like MysqL-monitor%; ------------------------------------------------------------+----------------+ | variable_name -monitor_enabled | true -monitor_connect_timeout 600 -monitor_ping_max_failures 3 -monitor_ping_timeout 1000 -monitor_read_only_max_timeout_count -monitor_replication_lag_interval 10000 -monitor_replication_lag_timeout -monitor_groupreplication_healthcheck_interval 5000 -monitor_groupreplication_healthcheck_timeout 800 -monitor_groupreplication_healthcheck_max_timeout_count -monitor_groupreplication_max_transactions_behind_count -monitor_galera_healthcheck_interval -monitor_galera_healthcheck_timeout -monitor_galera_healthcheck_max_timeout_count -monitor_replication_lag_use_percona_heartbeat | -monitor_query_interval 60000 -monitor_query_timeout 100 -monitor_slave_lag_when_null 60 -monitor_threads_min 8 -monitor_threads_max 128 -monitor_threads_queue_maxsize -monitor_wait_timeout -monitor_writer_is_also_reader -monitor_username -monitor_password -monitor_history 600000 -monitor_connect_interval 2000 -monitor_ping_interval -monitor_read_only_interval -monitor_read_only_timeout 500 30 rows in 0.01 sec)
在修改完变量之后,一定要加载到内存中生效以及永久保存到磁盘中:
(5.5.3)检查监控信息是否存在异常
监控配置完成后,我们需要检查Proxysql与后端MysqL通信是否有异常,monitor数据库中的表用于存储监视信息,需要注意的是,这些表并非都已经被使用。
查看组复制是否正常,检查节点是否只读和交易滞后时间:
查看Proxysql ping后端MysqL服务器是否正常:
通过监控信息,我们可以得出结论,所有配置都是健康的,继续下一步。
(5.6)用户配置
如果使用了Proxysql来做中间路由,那么与我们平时登录数据库有一些区别:平时我们直接使用数据库的用户密码,即可访问到数据库,如果使用了Proxysql,则要先使用账号密码访问到Proxysql的数据库,然后再由Proxysql进行用户请求的转发,那么,Proxysql中的用户与数据库层的用户有什么关联呢?很奇怪,这部分Proxysql居然没在文档里面给出来。
只能自己测试了,经过个人测试,发现:当中间件用户与数据库用户以及密码一致时,才能正常访问数据库。测试结果如下:
MysqL数据库用户(MysqL.user表) | Proxysql用户(main.MysqL_users表) | 使用Proxysql的6033端口访问数据库 |
usera | usera | 正常访问 |
userb | 无法登入proxysql | |
userc | 可以登入proxysql,但是无法读写 |
这里是我的测试过程:
登入测试(分为2步:先登入,再查询):
(1)usera用户登入无问题,查询无问题
用户认证小结:只有Proxysql中的用户名密码与MysqL中的用户名密码相同时,才能正常访问底层MysqL数据库。因此,如果要使用Proxysql访问数据库,需要在MysqL和Proxysql中都要创建相同的账号,并且密码也要保持一致。
Proxysql的用户保存在MysqL_users表中,用户创建直接执行insert插入即可。如创建一个用户名为“lijiaman”,密码为“123456”,默认用户组为1的用户:
MysqL_users表最重要的字段为:
- username
- password
- default_hostgroup:默认组。如果此用户发送的查询没有匹配的规则,则它生成的流量将发送到指定的主机组
- transaction_persistent:如果为与MysqL客户端连接到Proxysql的用户设置了此选项,则在主机组内启动的事务将保留在该主机组内,而不管其他任何规则。例如,一个事务中存在读与写操作,如果不指定该选项,可能会把读与写请求分发到不同的主机上,造成数据不一致。
(六)故障转移(failover)测试
在上一节,我们已经配置了:
此时,Proxysql已经具备故障转移的能力了,我们进行测试一下。
STEP1:现在的配置如下,192.168.10.13主机是写节点,其它2个节点是备用写节点:
STEP2:关闭写节点
# 直接关闭主机 [root@mgr-node3 ~]# reboot
Connection closed by foreign host. Disconnected from remote host(mgr-node3) at 19:31. Type `help' to learn how to use Xshell prompt.
[c:\~]$ -- 需要注意的是,以前连接在主节点上的会话会断开,不会转移到新的主节点,很正常,Oracle也不会 MysqL> select * from test01; ERROR 2013 (HY000): Lost connection to MysqL server during query
STEP3:查看是否会有备用写节点转为写节点,可以看到192.168.10.12服务器已经转为写节点,而已经关闭的192.168.10.13服务器已经进入离线组。
MysqL> from runtime_MysqL_servers; +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 2 | 192.168.10.11 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 1 | 10.12 | 4 | 10.13 | 0 | SHUNNED | 0 | | +--------------+---------------+------+-----------+---------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ 3 rows in set (0.00 sec)
STEP4:再次使用Proxysql来访问MyQSL集群,发现可以支持读写,业务不会因主节点的改变而受影响。
通过上面的测试,可以看到,MGR结合Proxysql已经可以实现业务的自动故障转移。