赞
踩
ProxySQL 是一款可以实际用于生产环境的 MySQL 中间件,它有官方版和 percona 版两种。percona版是在官方版的基础上修改的,添加了几个比较实用的工具。生产环境建议用官方版。
ProxySQL 是用 C++ 语言开发的,虽然也是一个轻量级产品,但性能很好(据测试,能处理千亿级的数据),功能也足够,能满足中间件所需的绝大多数功能,包括:
最基本的读/写分离,且方式有多种
可定制基于用户、基于schema、基于语句的规则对SQL语句进行路由。换句话说,规则很灵活。基于schema和与语句级的规则,可以实现简单的sharding
可缓存查询结果。虽然ProxySQL的缓存策略比较简陋,但实现了基本的缓存功能,绝大多数时候也够用了。此外,作者已经打算实现更丰富的缓存策略
监控后端节点。ProxySQL可以监控后端节点的多个指标,包括:ProxySQL和后端的心跳信息,后端节点的read-only/read-write,slave和master的数据同步延迟性(replication lag)
需求说明
通过mysql中间件ProxySQL实现mysql数据库的读写分离
环境说明
ip | 服务器类型 |
---|---|
192.168.161.154 | mysql-mster |
192.168.161.155 | mysql-slave |
192.168.161.164 | ProxySQL |
mysql-master和mysql-slave都已经安装好mysql
操作步骤
配置proxysql的yum源,安装proxysql并启动
[root@proxysql ~]# vim /etc/yum.repos.d/proxysql.repo [proxysql_repo] name= ProxySQL baseurl=http://repo.proxysql.com/ProxySQL/proxysql-1.4.x/centos/7 gpgcheck=1 gpgkey=http://repo.proxysql.com/ProxySQL/repo_pub_key [root@proxysql ~]# yum -y install proxysql [root@proxysql ~]# systemctl start proxysql [root@proxysql ~]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:6032 *:* LISTEN 0 128 *:6033 *:* LISTEN 0 128 *:6033 *:* LISTEN 0 128 *:6033 *:* LISTEN 0 128 *:6033 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25
添加proxysql可以增删改查的账号
[root@master ~]# mysql -uroot -p
Enter password:
mysql> grant all on *.* to 'proxy'@'192.168.161.164' identified by 'proxy123!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
①.登陆proxysql管理端
[root@proxysql ~]# yum -y install mariadb [root@proxysql ~]# export MYSQL_PS1="(\u@\h:\p) [\d]>" [root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032 (admin@127.0.0.1:6032) [(none)]>show databases; +-----+---------------+-------------------------------------+ | seq | name | file | +-----+---------------+-------------------------------------+ | 0 | main | | | 2 | disk | /var/lib/proxysql/proxysql.db | | 3 | stats | | | 4 | monitor | | | 5 | stats_history | /var/lib/proxysql/proxysql_stats.db | +-----+---------------+-------------------------------------+ 5 rows in set (0.00 sec)
数据库说明
②.proxysql添加链接后端mysql主从数据库的配置
(admin@127.0.0.1:6032) [(none)]> show tables from main; +--------------------------------------------+ | tables | +--------------------------------------------+ | global_variables | # ProxySQL的基本配置参数,类似与MySQL | mysql_collations | # 配置对MySQL字符集的支持 | mysql_group_replication_hostgroups | # MGR相关的表,用于实例的读写组自动分配 | mysql_query_rules | # 路由表 | mysql_query_rules_fast_routing | # 主从复制相关的表,用于实例的读写组自动分配 | mysql_replication_hostgroups | # 存储MySQL实例的信息 | mysql_servers | # 存储MySQL用户 | mysql_users | # 存储ProxySQL的信息,用于ProxySQL Cluster同步 | proxysql_servers | # 运行环境的存储校验值 | runtime_checksums_values | | runtime_global_variables | | runtime_mysql_group_replication_hostgroups | | runtime_mysql_query_rules | | runtime_mysql_query_rules_fast_routing | | runtime_mysql_replication_hostgroups | # 与上面对应,但是运行环境正在使用的配置 | runtime_mysql_servers | | runtime_mysql_users | | runtime_proxysql_servers | | runtime_scheduler | | scheduler | # 定时任务表 +--------------------------------------------+ 20 rows in set (0.00 sec) (admin@127.0.0.1:6032) [(none)]>insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.161.154',3306,1,'Write Group'); //添加表示写组的服务器ip (admin@127.0.0.1:6032) [(none)]>insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'192.168.161.155',3306,1,'Read Group'); //添加表示读组的服务器ip (admin@127.0.0.1:6032) [(none)]>select * from mysql_servers; +--------------+-----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+ | hostgroup_id | hostname | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+-----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+ | 1 | 192.168.161.154 | 3306 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | Write Group | | 2 | 162.168.161.155 | 3306 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | Read Group | +--------------+-----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+ (admin@127.0.0.1:6032) [(none)]>load mysql servers to runtime; //加载到runtime Query OK, 0 rows affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]>save mysql servers to disk; //保存到disk Query OK, 0 rows affected (0.07 sec)
runtime_ 开头的是运行时的配置,这些是不能修改的。要修改 ProxySQL 的配置,需要修改了非 runtime_ 表,修改后必须执行 LOAD … TO RUNTIME 才能加载到 RUNTIME 生效,执行 save … to disk 才能将配置持久化保存到磁盘
下面语句中没有先切换到 main 库也执行成功了,因为 ProxySQL 内部使用的 SQLite3 数据库引擎,和 MySQL 的解析方式是不一样的。即使执行了 USE main 语句也是无任何效果的,但不会报错
使用 insert 语句添加 mysql 主机到 mysql_servers 表中,其中:hostgroup_id 1 表示写组,2表示读组
③.添加用于操作读写分离的账号到管理端
在 proxysql 主机的 mysql_users 表中添加刚才在 master 上创建的账号 proxysql,proxysql 客户端需要使用这个账号来访问数据库
default_hostgroup 默认组设置为写组,也就是1;
当读写分离的路由规则不符合时,会访问默认组的数据库;
(admin@127.0.0.1:6032) [(none)]> insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxy','proxy123!',1,1); Query OK, 1 row affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]> select * from mysql_users \G *************************** 1. row *************************** username: proxy # 后端mysql实例的用户名 password: proxy123! # 后端mysql实例的密码 active: 1 # active=1表示用户生效,0表示不生效 use_ssl: 0 default_hostgroup: 1 # 用户默认登录到哪个hostgroup_id下的实例 default_schema: NULL # 用户默认登录后端mysql实例时连接的数据库,这个地方为NULL的话,则由全局变量mysql-default_schema决定,默认是information_schema schema_locked: 0 transaction_persistent: 1 # 如果设置为1,连接上ProxySQL的会话后,如果在一个hostgroup上开启了事务,那么后续的sql都继续维持在这个hostgroup上,不论是否会匹配上其它路由规则,直到事务结束。虽然默认是0 fast_forward: 0 # 忽略查询重写/缓存层,直接把这个用户的请求透传到后端DB。相当于只用它的连接池功能,一般不用,路由规则 .* 就行了 backend: 1 frontend: 1 max_connections: 10000 # 该用户允许的最大连接数 1 row in set (0.00 sec) (admin@127.0.0.1:6032) [(none)]> load mysql users to runtime; Query OK, 0 rows affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]> save mysql users to disk; Query OK, 0 rows affected (0.00 sec)
添加健康检测账号,在master上创建一个只有读权限的账号
mysql> grant select on *.* to 'read'@'%' identified by 'read123!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
①.在proxysql管理端添加健康监测的账号
(admin@127.0.0.1:6032) [(none)]>set mysql-monitor_username='read';
Query OK, 1 row affected (0.00 sec)
(admin@127.0.0.1:6032) [(none)]>set mysql-monitor_password='read123!';
Query OK, 1 row affected (0.00 sec)
(admin@127.0.0.1:6032) [(none)]>load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)
(admin@127.0.0.1:6032) [(none)]>save mysql variables to disk;
Query OK, 97 rows affected (0.00 sec将 select 查询语句全部路由至 hostgroup_id=2 的组(也就是读组)
②.添加读写分离的路由规则
(admin@127.0.0.1:6032) [(none)]>insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^SELECT.*FOR UPDATE$',1,1); Query OK, 1 row affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]>insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',2,1); Query OK, 1 row affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]>select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules; +---------+--------+----------------------+-----------------------+-------+ | rule_id | active | match_digest | destination_hostgroup | apply | +---------+--------+----------------------+-----------------------+-------+ | 1 | 1 | ^SELECT.*FOR UPDATE$ | 1 | 1 | | 2 | 1 | ^SELECT | 2 | 1 | +---------+--------+----------------------+-----------------------+-------+ 2 rows in set (0.00 sec) (admin@127.0.0.1:6032) [(none)]>load mysql query rules to runtime; Query OK, 0 rows affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]>load admin variables to runtime; Query OK, 0 rows affected (0.00 sec) (admin@127.0.0.1:6032) [(none)]>save mysql query rules to disk; Query OK, 0 rows affected (0.01 sec) (admin@127.0.0.1:6032) [(none)]>save admin variables to disk; Query OK, 31 rows affected (0.00 sec)
验证读写分离
登陆proxysql客户端,使用我们之前创建的账号
创建一个数据库并查看一下表
[root@proxysql ~]# mysql -uproxysql -pproxy123! -h127.0.0.1 -P6033 (proxy@127.0.0.1:6033) [(none)]>create database test; Query OK, 1 row affected (0.01 sec) (proxy@127.0.0.1:6033) [(none)]>select user,host from mysql.user; +---------------+-----------------+ | user | host | +---------------+-----------------+ | read | % | | proxy | 192.168.161.164 | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+-----------------+ 5 rows in set (0.00 sec)
在proxysql管理端查看
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
(admin@127.0.0.1:6032) [(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 |
+-----------+--------------------+----------+--------------------+----------------------------------+------------+------------+------------+----------+----------+----------+
| 2 | information_schema | proxy | 0xD67B48164A6380F2 | select user from mysql.user | 1 | 1543200189 | 1543200189 | 27857 | 27857 | 27857 |
| 1 | information_schema | proxy | 0x30327C1D25D51434 | create database test | 1 | 1543200283 | 1543200283 | 5543 | 5543 | 5543 |
+-----------+--------------------+----------+--------------------+----------------------------------+------------+------------+------------+----------+----------+----------+
可以看到读操作是在hostgroup=2也就是读组上面进行,写操作是在hostgroup=1也就是写组上面进行的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。