数据库系列之MySQL基于proxySQL实现读写分离

MySQL主从复制读写分离的实现有很多种,比如使用中间件mysql-proxy、proxysql和mycat三种中间件实现读写分离并进行测试验证。本文主要讨论基于proxySQL中间件实现读写分离:

数据库系列之MySQL基于MySQL-proxy实现读写分离
数据库系列之MySQL基于proxySQL实现读写分离
数据库系列之MySQL基于Mycat实现读写分离


1.2 基于proxySQL
1.2.1 ProxySQL介绍

ProxySQL是基于MySQL的一款开源的中间件的产品,是一个灵活的 MySQL代理层,可以实现读写分离,支持Query路由功能,缓存查询结果、故障切换和一些SQL的过滤功能。

1.2.2 安装配置ProxySQL

1)安装ProxySQL,使用yum源安装

cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
name= ProxySQL
baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/7
gpgcheck=1
gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key
EOF

yum安装

[root@tango-01 ~]# yum install -y proxysql 
[root@tango-01 ~]# systemctl start proxysql
[root@tango-01 ~]# netstat -nltp|grep proxysql
tcp        0      0 0.0.0.0:6032            0.0.0.0:*               LISTEN      5755/proxysql       
tcp        0      0 0.0.0.0:6033            0.0.0.0:*               LISTEN      5755/proxysql

2)在192.168.112.101(主库)上添加proxysql可以增删查改的账号

[mysql@tango-centos01 mysql]$ ./bin/mysql -uroot -ppassword
mysql> grant all on *.* to 'proxysql'@'192.168.112.%' identified by 'password';
Query OK, 0 rows affected, 1 warning (0.41 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.27 sec)

3)登录proxysql管理端,默认端口6032

[root@tango-01 mysql]# ./bin/mysql -uadmin -padmin -h127.0.0.1 -P6032
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 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)

mysql>

4)使用insert语句添加mysql主机到mysql_servers表中,其中:hostgroup_id=1表示写组,2表示读组

mysql> use main;
mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.112.101',3306,1,'Write Group');
Query OK, 1 row affected (0.00 sec)

mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'192.168.112.102',3306,1,'Read Group');
Query OK, 1 row affected (0.00 sec)

mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'192.168.112.103',3306,1,'Read Group');
Query OK, 1 row affected (0.00 sec)

mysql> select * from mysql_servers;
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname        | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 1            | 192.168.112.101 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Write Group |
| 2            | 192.168.112.102 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
| 2            | 192.168.112.103 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
+--------------+-----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
3 rows in set (0.00 sec)

mysql>

#修改后,需要加载到RUNTIME,并保存到disk

mysql> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> save mysql servers to disk;
Query OK, 0 rows affected (0.18 sec)

5)在proxysql主机的mysql_users表中添加刚才在master上创建的账号proxysql,proxysql客户端需要使用这个账号来访问数据库。default_hostgroup默认组设置为写组,也就是1,当读写分离的路由规则不符合时,会访问默认组的数据库。

mysql> insert into mysql_users(username,password,default_hostgroup,transaction_persistent) values('proxysql','password',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from mysql_users \G
*************************** 1. row ***************************
              username: proxysql    # 后端mysql实例的用户名
              password: password   # 后端mysql实例的密码
                active: 1           # active=1表示用户生效,0表示不生效
               use_ssl: 0
     default_hostgroup: 1           # 用户默认登录到哪个hostgroup_id下的实例
        default_schema: NULL
         schema_locked: 0
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000
               comment: 
1 row in set (0.00 sec)

mysql> load mysql users to runtime;
Query OK, 0 rows affected (0.01 sec)

mysql> save mysql users to disk;
Query OK, 0 rows affected (0.01 sec)

mysql>
  • username:后端mysql实例的用户名
  • password:后端mysql实例的密码
  • active :active=1表示用户生效,0表示不生效
  • default_hostgroup :用户默认登录到哪个hostgroup_id下的实例
  • default_schema:用户默认登录后端mysql实例时连接的数据库,这个地方为NULL的话,则由全局变量mysql-default_schema决定,默认是information_schema
  • transaction_persistent:如果设置为1,连接上ProxySQL的会话后,如果在一个hostgroup上开启了事务,那么后续的sql都继续维持在这个hostgroup上,不论是否会匹配上其它路由规则,直到事务结束。默认是0
  • fast_forward:忽略查询重写/缓存层,直接把这个用户的请求透传到后端DB。相当于只用它的连接池功能,一般不用,路由规则 .* 就行了
  • max_connections:该用户允许的最大连接数

6)在proxysql主机端修改变量设置健康检测的账号

mysql> set mysql-monitor_username='monitor';
Query OK, 1 row affected (0.01 sec)

mysql> set mysql-monitor_password='monitor';
Query OK, 1 row affected (0.00 sec)

mysql> load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> save mysql variables to disk;
Query OK, 137 rows affected (0.03 sec)

7)添加读写分离的路由规则

将select查询语句全部路由至hostgroup_id=2的组(也就是读组),但是“select * from tb for update”这样的语句是会修改数据的,将它路由至hostgroup_id=1的组(也就是写组)。其他没有被规则匹配到的组将会被路由至用户默认的组(mysql_users表中的default_hostgroup)

mysql> 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)

mysql> 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)

mysql> 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)

mysql> load mysql query rules to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> load admin variables to runtime;
Query OK, 0 rows affected (0.00 sec)

mysql> save mysql query rules to disk;
Query OK, 0 rows affected (0.10 sec)

mysql> save admin variables to disk;
Query OK, 35 rows affected (0.03 sec)
1.2.3 测试读写分离效果

1)使用刚创建的proxysql用户连接proxysql,端口为6033

[root@tango-01 mysql]# ./bin/mysql -uproxysql -ppassword -h127.0.0.1 -P6033
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.30 (ProxySQL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
| test01             |
+--------------------+
6 rows in set (0.35 sec)

mysql>

2)尝试修改数据库和查询

mysql> insert into test01.tb01 values('user5','123');
Query OK, 1 row affected (0.34 sec)

mysql> select * from test01.tb01;
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
| user3    | 123      |
| user4    | 123      |
+----------+----------+
4 rows in set (0.29 sec)

3)验证读写分离是否成功

[root@tango-01 mysql]# ./bin/mysql -uproxysql -ppassword -h127.0.0.1 -P6033
mysql> select * from stats_mysql_query_digest;
+-----------+--------------------+----------+----------------+--------------------+-------------------------------------+------------+------------+------------+----------+----------+----------+-------------------+---------------+
| hostgroup | schemaname         | username | client_address | digest             | digest_text                         | count_star | first_seen | last_seen  | sum_time | min_time | max_time | sum_rows_affected | sum_rows_sent |
+-----------+--------------------+----------+----------------+--------------------+-------------------------------------+------------+------------+------------+----------+----------+----------+-------------------+---------------+
| 1         | information_schema | proxysql |                | 0x0EE8CA2FFE163603 | insert into test01.tb01 values(?,?) | 1          | 1608257652 | 1608257652 | 335934   | 335934   | 335934   | 1                 | 0             |
| 1         | information_schema | proxysql |                | 0x02033E45904D3DF0 | show databases                      | 1          | 1608256262 | 1608256262 | 349671   | 349671   | 349671   | 0                 | 6             |
| 2         | information_schema | proxysql |                | 0x1E990D5CC27107F6 | select * from test01.tb01           | 4          | 1608257594 | 1608257671 | 622788   | 8657     | 315769   | 0                 | 16            |
| 1         | information_schema | proxysql |                | 0x226CD90D52A2BA0B | select @@version_comment limit ?    | 2          | 1608256256 | 1608257631 | 0        | 0        | 0        | 0                 | 0             |
+-----------+--------------------+----------+----------------+--------------------+-------------------------------------+------------+------------+------------+----------+----------+----------+-------------------+---------------+
4 rows in set (0.07 sec)

从上面的hostgroup和digest_text值来看,所有的写操作都被路由至1组,读操作都被路由至2组,其中1组为写组,2组为读组,因此实现读写分离。

参考资料:

  1. https://proxysql.com/documentation/
  2. https://www.cnblogs.com/keme/p/12290977.html
  3. https://blog.csdn.net/qq_43094192/article/details/84900922

转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/117697624
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值