Proxysql实现MySQL读写分离

环境:


主机名 IP 应用
proxysql 172.16.78.125 proxysql
master 172.16.78.128 mariadb
slave 172.16.78.129 mariadb

配置步骤:


1. 在master和slave上安装mariadb

[root@master ~]# yum -y install mariadb*
[root@master ~]# systemctl enable --now mariadb  
[root@master ~]# ss -antl |grep 3306
LISTEN     0      50           *:3306                     *:*

[root@slave ~]# yum -y install mariadb*
[root@slave ~]# systemctl enable --now mariadb
[root@slave ~]# ss -antl |grep 3306
LISTEN     0      50           *:3306                     *:*

2. 在master和slave上配置主从

//在主库中创建一个同步账号给从库使用
[root@master ~]# mysql
MariaDB [(none)]> grant replication slave on *.* to 'repl'@'172.16.78.129' identified by 'repl123';              
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

//配置主数据库
[root@master ~]# vim /etc/my.cnf
//在mysqld段添加下面两行内容
server-id = 10 
log-bin = mysql_bin
...
[root@master ~]# systemctl restart mariadb

//查看主库的状态
[root@master ~]# mysql
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000001 |      245 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
//配置从数据库
[root@slave ~]# vim /etc/my.cnf
//在mysqld段添加下面两行内容
server-id = 20 
relay-log = myrelay_bin
...
[root@slave ~]# systemctl restart mariadb

//配置并启动主从复制
[root@slave ~]# mysql
MariaDB [(none)]> change master to
master_host='172.16.78.128',
master_user='repl',
master_password='repl123',
master_log_file='mysql_bin.000001',
master_log_pos=245;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.78.128
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000001
          Read_Master_Log_Pos: 245
               Relay_Log_File: myrelay_bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql_bin.000001
             Slave_IO_Running: Yes    //此行和下面一行必须为yes
            Slave_SQL_Running: Yes
            ......

3. 安装proxysql

[root@proxysql ~]# wget http://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/7/proxysql-2.0.13-1-centos7.x86_64.rpm
[root@proxysql ~]# yum -y localinstall proxysql-2.0.13-1-centos7.x86_64.rpm 
[root@proxysql ~]# systemctl enable --now proxysql
[root@proxysql ~]# ss -antl |grep -E '6032|6033'
LISTEN     0      128          *:6032                     *:*                  
LISTEN     0      128          *:6033                     *:*                  
LISTEN     0      128          *:6033                     *:*                  
LISTEN     0      128          *:6033                     *:*                  
LISTEN     0      128          *:6033                     *:*

4. 在master上添加proxysql可以增删改查的账号

//由于配置了主从,所以在主库上配置会自动同步至从库
[root@master ~]# mysql
MariaDB [(none)]> grant all on *.* to 'proxysql'@'172.16.78.125' identified by 'proxysql';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

5. 在proxysql上添加 mysql 主机到 mysql_servers 表中

[root@proxysql ~]# yum -y install mariadb
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'172.16.78.128',3306,1,'Write Group');        
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'172.16.78.129',3306,1,'Read Group');       
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> select * from mysql_servers;
//hostgroup_id 1 表示写组,2表示读组
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname      | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 1            | 172.16.78.128 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Write Group |
| 2            | 172.16.78.129 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
2 rows in set (0.00 sec)
//default_hostgroup 默认组设置为写组,也就是1。当读写分离的路由规则不符合时,会访问默认组的数据库;

//将配置载入runtime,并保存至disk
MySQL [(none)]> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> save mysql servers to disk;
Query OK, 0 rows affected (0.01 sec)

6. 在 proxysql 上的 mysql_users 表中添加刚才在 master 上创建的账号

//proxysql 客户端需要使用这个账号来访问数据库
MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','proxysql',1,1);
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> select * from mysql_users \G
*************************** 1. row ***************************
              username: proxysql     //后端mysql实例的用户名
              password: proxysql     //后端mysql实例的密码
                active: 1            //active=1表示用户生效,0表示不生效
               use_ssl: 0
     default_hostgroup: 1            //用户默认登录到哪个hostgroup_id下的实例
        default_schema: NULL         //用户默认登录后端mysql实例时连接的数据库,这个地方为NULL的话,则由全局变量
         schema_locked: 0              mysql-default_schema决定,默认是information_schema
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000        //该用户允许的最大连接数
               comment: 
1 row in set (0.00 sec)

MySQL [(none)]> load mysql users to runtime;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> save mysql users to disk;
Query OK, 0 rows affected (0.00 sec)

7. 在 master 端添加属于proxysql的只读账号

[root@master ~]# mysql
MariaDB [(none)]> grant select on *.* to 'monitor'@'172.16.78.%' identified by 'monitor';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

8. 在proxysql上修改变量设置健康检测的账号

[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
MySQL [(none)]> set mysql-monitor_username='monitor';
Query OK, 1 row affected (0.00 sec)

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

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

MySQL [(none)]> save mysql variables to disk;
Query OK, 134 rows affected (0.00 sec)

9. 在proxysql上添加读写分离的路由规则

select 查询语句全部路由至 hostgroup_id=2 的组(也就是读组)
将修改数据的语句全部路由至 hostgroup_id=1 的组(也就是写组)
其他没有被规则匹配到的组将会被路由至用户默认的组(mysql_users 表中的 default_hostgroup)


MySQL [(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)

MySQL [(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)

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      | ^SELECT.*FOR UPDATE$ | 1                     | 1     |
| 2       | 1      | ^SELECT              | 2                     | 1     |
+---------+--------+----------------------+-----------------------+-------+
2 rows in set (0.00 sec)


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

MySQL [(none)]> save mysql query rules to disk;
Query OK, 0 rows affected (0.00 sec)

10. 在proxysql上验证读写分离

//登录 proxysql 客户端
[root@proxysql ~]# mysql -uproxysql -pproxysql -h127.0.0.1 -P6033

//修改数据库和查询
MySQL [(none)]> create database jjyy;
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> select user,host from mysql.user;
+----------+---------------+
| user     | host          |
+----------+---------------+
| root     | 127.0.0.1     |
| monitor  | 172.16.78.%   |
| proxysql | 172.16.78.125 |
| root     | ::1           |
|          | localhost     |
| root     | localhost     |
|          | slave         |
| root     | slave         |
+----------+---------------+
8 rows in set (0.00 sec)

//验证读写分离是否成功
[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
MySQL [(none)]> 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 |
+-----------+--------------------+----------+----------------+--------------------+----------------------------------+------------+------------+------------+----------+----------+----------+-------------------+---------------+
| 2         | information_schema | proxysql |                | 0x620B328FE9D6D71A | SELECT DATABASE()                | 1          | 1597502348 | 1597502348 | 2142     | 2142     | 2142     | 0                 | 1             |
| 1         | information_schema | proxysql |                | 0x42FB57576656E0AB | create databaes jjyy             | 1          | 1597502315 | 1597502315 | 621      | 621      | 621      | 0                 | 0             |
| 2         | information_schema | proxysql |                | 0x0F02B330C823D739 | select user,host from mysql.user | 1          | 1597502384 | 1597502384 | 824      | 824      | 824      | 0                 | 8             |
| 1         | information_schema | proxysql |                | 0x79FEC23C145D5AED | create database jjyy             | 2          | 1597501674 | 1597502324 | 12393    | 776      | 11617    | 1                 | 0             |
| 1         | information_schema | proxysql |                | 0xF326D786832F92C7 | create databases jjyy            | 1          | 1597501671 | 1597501671 | 11826    | 11826    | 11826    | 0                 | 0             |
+-----------+--------------------+----------+----------------+--------------------+----------------------------------+------------+------------+------------+----------+----------+----------+-------------------+---------------+

//由此可见所有create语句都被路由到了1组,所有select语句都被路由到了2组
//说明读写分离配置成功

你可能感兴趣的:(数据库)