一、前言
ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎,其特性主要由:读写分离、负载均衡、规则路由器等等,相关介绍可参考下述链接:
http://seanlook.com/2017/04/10/mysql-proxysql-install-config/
本次实验按照上述拓扑部署实现ProxySQL的读写分离,MySQL主从复制这里不再介绍配置过程,本次实验只演示ProxySQL的配置过程。
配置完成ProxySQL后,使得读取Mysql数据的连接会话通过ProxySQL被调度到后端slave1和slave2上获取,而写入操作等则调度到Master上进行处理。
proxysql的下载链接:https://www.percona.com/downloads/proxysql/
二、构建ProxySQL
1、安装ProxySQL服务
首先安装ProxySQL服务,此次我安装的为最新版proxysql-1.4.8:
[root@proxysql ~]# yum install -y https://www.percona.com/downloads/proxysql/proxysql-1.4.8/binary/redhat/7/x86_64/proxysql-1.4.8-1.1.el7.x86_64.rpm
2、ProxySQL的初始化配置
proxysql有个配置文件 /etc/proxysql.cnf,只在第一次启动的时候有用,后续所有的配置修改都是对SQL数据库操作,并且不会更新到proxysql.cnf文件中。ProxySQL绝大部分配置都可以在线修改,配置存储在 /var/lib/proxysql/proxysql.db 中。
在编辑配置proxySQL的配置文件前,我们先要在Master上创建ProxySQL的授权账号,用于proxySQL连接监控后端服务器:
MariaDB [(none)]> grant all on *.* to 'proxysql'@'192.168.0.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
接着我们来配置proxysql的初始化配置:
[root@proxysql ~]# vim /etc/proxysql
admin_variables=
{
admin_credentials="admin:admin" #proxysql的管理接口登录账号和密码
mysql_ifaces="0.0.0.0:6032" #proxysql的管理接口监听地址及端口
}
mysql_variables=
{
.....
interfaces="0.0.0.0:6033" #proxysql代理mysql的Ip和端口,默认为6033,不过通常建议更改为3306
default_schema="information_schema"
stacksize=1048576
server_version="5.5.30"
connect_timeout_server=3000
monitor_username="proxysql" #proxysql用于监控后端服务器的账号及密码
monitor_password="123456"
......
}
mysql_servers =
(
{
address = "192.168.0.82" #指定后端服务器的Ip
port = 3306
hostgroup = 0 #为后端服务器分配一个hostgroup id
status = "ONLINE"
weight = 1
compression = 0
},
{
address = "192.168.0.89"
port = 3306
hostgroup = 1
status = "ONLINE"
weight = 1
compression = 0
{
address = "192.168.0.87"
port = 3306
hostgroup = 1
status = "ONLINE"
weight = 1
compression = 0
}
)
mysql_users:
(
{
username = "proxysql" # no default , required
password = "123456" # default: ''
default_hostgroup = 0 # default: 0
default_schema="hellodb"
active = 1 # default: 1
}
)
mysql_query_rules: #配置路由规则
(
{
rule_id=1
active=1
match_pattern="^INSERT"
destination_hostgroup=0
apply=1
},
{
rule_id=2
active=1
match_pattern="^SELECT"
destination_hostgroup=1
apply=1
}
)
配置完成后即可启动proxysql服务:
[root@proxysql ~]# systemctl start proxysql
启动完成后即可通过连接访问mysql的管理端口6032来管理proxysql服务,如:
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.30 (ProxySQL Admin Module)
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
#查看后端服务器的状态
MySQL [(none)]> select * from mysql_servers;
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 0 | 192.168.0.82 | 3306 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | |
| 1 | 192.168.0.89 | 3306 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | |
| 1 | 192.168.0.87 | 3306 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
3 rows in set (0.00 sec)
此时通过访问连接6033端口即可访问到后端的数据库服务器。
[root@localhost ~]# mysql -uproxysql -p123456 -h192.168.0.81 -P6033
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.30 (ProxySQL)
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
MySQL [(none)]>
MySQL [(none)]> show databases; #正常查看到相应的数据库信息
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
#通过proxysql插入数据
MySQL [(none)]> insert into mydb.account(name) values ('tony'),('stark');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
MySQL [(none)]> select * from mydb.account;
+----+---------+
| id | name |
+----+---------+
| 1 | charlie |
| 3 | jack |
| 5 | alice |
| 6 | Ops |
| 8 | IT |
| 10 | Manager |
| 11 | Web |
| 12 | tony |
| 13 | stark |
+----+---------+
9 rows in set (0.00 sec)
通过连接到proxysql的6033端口,proxysql服务会将相关的SQL操作代理到后端的mysql服务器,此处我的设置为将insert操作代理到Master主机,select查询相关的操作代理到后端的两个slave主机上,这样子就能适当减轻下Master主机的负载压力。
3、ProxySQL的管理接口
此前提到过,proxysql的配置文件/etc/proxysql.cnf只有在第一次启动时才有用,后续的所有配置的修改均是通过对SQL数据库操作的,这里的操作指的就是通过连接到Proxysql的管理Ip和端口上来进行修改操作。
例如,上述我们在/etc/proxysql.cnf所配置的初始化配置,在管理接口上我们可以下述的命令来修改。
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032 #默认的admin账号只允许在proxysql本地服务器上登录
#添加proxysql用于访问后端数据库的账号
MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','123456',0,1);
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> select * from mysql_users\G
*************************** 1. row ***************************
username: proxysql
password: 123456
active: 1
use_ssl: 0
default_hostgroup: 0
default_schema: NULL
schema_locked: 0
transaction_persistent: 1
fast_forward: 0
backend: 1
frontend: 1
max_connections: 10000
1 row in set (0.00 sec)
#添加用于做健康检测的账号
MySQL [(none)]> set mysql-monitor_username='proxysql';
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> set mysql-monitor_password='123456';
Query OK, 1 row affected (0.00 sec)
#添加后端数据库主机,hostgroup_id 0表示写组,1表示读组
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(0,'192.168.0.82',3306,1,'Write Group');
Query OK, 1 row affected (0.01 sec)
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.87',3306,1,'Read Group');
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.89',3306,1,'Read Group');
Query OK, 1 row affected (0.01 sec)
#将insert这样的修改语句路由到0组(写组)
MySQL [(none)]> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^INSERT.*',0,0);
#将select语句全部路由至hostgroup_id=1的组(也就是读组)
MySQL [(none)]> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',1,0);
MySQL [(none)]> select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;
+---------+--------+----------------------+-----------------------+-------+
| rule_id | active | match_digest | destination_hostgroup | apply |
+---------+--------+----------------------+-----------------------+-------+
| 1 | 1 | ^INSERT.* | 0 | 0 |
| 2 | 1 | ^SELECT | 1 | 0 |
+---------+--------+----------------------+-----------------------+-------+
#加载刚才添加的配置
MySQL [(none)]> load mysql users to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load admin variables to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load mysql query rules to runtime;
Query OK, 0 rows affected (0.01 sec)
#保持配置至db文件中
MySQL [(none)]> save mysql users to disk;
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]> save mysql servers to disk;
Query OK, 0 rows affected (0.02 sec)
MySQL [(none)]> save mysql query rules to disk;
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]> save mysql variables to disk;
Query OK, 95 rows affected (0.01 sec)
MySQL [(none)]> save admin variables to disk;
Query OK, 31 rows affected (0.01 sec)
按照上述的命令配置完成后,此时应该能通过proxysql的6033端口访问后端的数据库服务了。
此时可以通过下述命令查看相关路由规则的匹配情况:
MySQL [(none)]> select active,hits, mysql_query_rules.rule_id, schemaname, match_digest, match_pattern, replace_pattern,destination_hostgroup hostgroup,s.comment,flagIn,flagOUT FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules JOIN mysql_servers s on destination_hostgroup=hostgroup_id ORDER BY mysql_query_rules.rule_id;
+--------+------+---------+------------+--------------+---------------+-----------------+-----------+-------------+--------+---------+
| active | hits | rule_id | schemaname | match_digest | match_pattern | replace_pattern | hostgroup | comment | flagIN | flagOUT |
+--------+------+---------+------------+--------------+---------------+-----------------+-----------+-------------+--------+---------+
| 1 | 2 | 1 | NULL | ^INSERT.* | NULL | NULL | 0 | Write Group | 0 | NULL |
| 1 | 1 | 2 | NULL | ^SELECT | NULL | NULL | 1 | Read Group | 0 | NULL |
| 1 | 1 | 2 | NULL | ^SELECT | NULL | NULL | 1 | Read Group | 0 | NULL |
+--------+------+---------+------------+--------------+---------------+-----------------+-----------+-------------+--------+---------+
3 rows in set (0.00 sec)
另外proxysql提供了一个类似于审计的功能,可以查看各类SQL的执行分离情况:
#此命令需要在proxySQL 的管理端口执行
MySQL [(none)]> select * from stats_mysql_query_digest;
+-----------+--------------------+----------+--------------------+---------------------------------------------------------------------------------------------------------+------------+------------+------------+----------+----------+----------+
| hostgroup | schemaname | username | digest | digest_text | count_star | first_seen | last_seen | sum_time | min_time | max_time |
+-----------+--------------------+----------+--------------------+---------------------------------------------------------------------------------------------------------+------------+------------+------------+----------+----------+----------+
| 1 | information_schema | proxysql | 0xCAEE33E27FE8899C | select * from mydb.account | 3 | 1530186285 | 1530186734 | 8191 | 1273 | 3634 |
| 0 | information_schema | proxysql | 0x20A90DAB1FD06917 | insert into mydb.account(name) values (?),(?) | 3 | 1530185541 | 1530186569 | 19155 | 5161 | 8142 |
| 0 | information_schema | proxysql | 0x3375EBC9A89AA861 | insert into mysql.account(name) values (?),(?) | 2 | 1530185533 | 1530186564 | 1874 | 798 | 1076 |
| 0 | information_schema | proxysql | 0xF8BB084D36148187 | insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(?,?,?,?,?) | 1 | 1530185979 | 1530185979 | 926 | 926 | 926 |
| 0 | information_schema | proxysql | 0x9461F19B72760588 | create database testdb | 1 | 1530186704 | 1530186704 | 3408 | 3408 | 3408 |
相关的select语句成功被路由到1组进行处理,因此只要编写好相关的路由规则,ProxySQL便能很好地将Mysql读写分离。
相关链接:http://blog.51cto.com/l0vesql/2090721
http://seanlook.com/2017/04/17/mysql-proxysql-route-rw_split/
http://seanlook.com/2017/04/10/mysql-proxysql-install-config/