实现ProxySQL反向代理Mysql读写分离

简介

ProxySQL相当于小型的数据库,在磁盘上有存放数据库的目录;ProxySQL用法和mysql相似
启动ProxySQL后会有两个监听端口;
6032:ProxySQL的管理端口
6033:ProxySQL对外提供服务的端口
注意:ProxySQL区分主从节点,是通过主从服务器配置文件中的read_only来区分的;哪个服务器配置文件中有read_only,哪台服务器就是从节点,所以从节点必须加read_only选项

ProxySQL下载地址

实现ProxySQL代理最少准备4台机器

https://github.com/sysown/proxysql/releases/tag/v2.0.8

主节点配置:

[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id=17
log-bin
[root@master ~]# systemctl restart mariadb
[root@master ~]# mysql -e 'grant replication slave on *.* to repluser@"192.168.38.%" identified by "centos";'     #授权并且创建用于主从同步的账号
[root@master ~]# mysql -e 'grant replication client on *.* to monitor@"192.168.38.%" identified by "centos";'        #授权并创建用于ProxySQL监控节点服务器上的read_only值的账号
[root@master ~]# mysql -e 'grant all on *.* to sqluser@"192.168.38.%" identified by "centos";'       #创建一个mysql客户端连接ProxySQL代理服务器的账号;客户端连接代理服务器,代理服务器反向代理到后端的mysql数据库;ProxySQL上是没有这个账号的

授权创建的这些账号主从节点都需要设置,主节点和从节点都配置完,这些账号会自动同步到从节点上

从节点配置

[root@slave ~]# vim /etc/my.cnf
[mysqld]
server-id=27
read-only           #从节点必须配置
[root@slave ~]# systemctl restart mariadb
[root@slave ~]# mysql
MariaDB [(none)]> CHANGE MASTER TO
    -> MASTER_HOST='192.168.38.37',
    -> MASTER_USER='repluser',
    -> MASTER_PASSWORD='centos',
    -> MASTER_PORT=3306,
    -> MASTER_LOG_FILE='mariadb-bin.000001',
    -> MASTER_LOG_POS=245;
MariaDB [(none)]> start slave;

ProxySQL服务器配置

[root@proxysql ~]# yum install proxysql-2.0.8-1-centos67.x86_64.rpm -y     #提前下载好ProxySQL包
[root@proxysql ~]# rpm -ql proxysql
/etc/init.d/proxysql
/etc/logrotate.d/proxysql
/etc/proxysql.cnf
/usr/bin/proxysql
/usr/share/proxysql/tools/proxysql_galera_checker.sh
/usr/share/proxysql/tools/proxysql_galera_writer.pl
[root@proxysql ~]# vim /etc/proxysql.cnf    #可以修改对外提供服务的端口号为3306
[root@proxysql ~]# service proxysql start
[root@proxysql ~]# mysql -uadmin -padmin -P6032 -h127.0.0.1       #连接proxysql的管理端口;mysql客户端连接服务器端,在同一台机器默认走的是mysql客户端的socket文件,所以这里指定代表本机的IP
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port)values(10,'192.168.38.37',3306);    #往mysql_servers表中插入主从节点的信息,默认都放在10组里
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port)values(10,'192.168.38.47',3306);
MySQL [(none)]> select * from mysql_servers;
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname      | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 10           | 192.168.38.37 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 10           | 192.168.38.47 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
MySQL [(none)]> load mysql servers to runtime;     #加载到runtime中,生效
MySQL [(none)]> save mysql servers to disk;    #保存到磁盘中
MySQL [(none)]> set mysql-monitor_username='monitor';     #设置监控账号的用户名
MySQL [(none)]> set mysql-monitor_password='centos';    #密码
MySQL [(none)]> load mysql variables to runtime;
MySQL [(none)]> save mysql variables to disk;
MySQL [(none)]> select * from mysql_server_connect_log;       #可以查到监控信息了,没指定连接数据库的监控账号之前查询,会显示error
+---------------+------+------------------+-------------------------+---------------+
| hostname      | port | time_start_us    | connect_success_time_us | connect_error |
+---------------+------+------------------+-------------------------+---------------+
| 192.168.38.37 | 3306 | 1574775423158525 | 873                     | NULL          |
| 192.168.38.47 | 3306 | 1574775423859699 | 701                     | NULL          |
+---------------+------+------------------+-------------------------+---------------+
MySQL [(none)]> select * from sqlite_master where name='mysql_replication_hostgroups'\G    #查询一下mysql_replication_hostgroups这个表的结构
MySQL [(none)]> insert into mysql_replication_hostgroups values(10,20,'read_only',"test");    #把10组添加到写组,把20组添加到读组下,针对read_only进行区分;有read_only的放到20组,没有read_only的放到10组
MySQL [(none)]> load mysql servers to runtime;
MySQL [(none)]> save mysql servers to disk;
MySQL [(none)]> MySQL [(none)]> select * from mysql_servers;     #47这台主机放到了20组下,区分开47这台机器为从节点(负责读),37为主节点(负责写)
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname      | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 10           | 192.168.38.37 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 20           | 192.168.38.47 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
MySQL [(none)]> select * from mysql_replication_hostgroups;
+------------------+------------------+------------+---------+
| writer_hostgroup | reader_hostgroup | check_type | comment |
+------------------+------------------+------------+---------+
| 10               | 20               | read_only  | test    |
+------------------+------------------+------------+---------+
MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup)values('sqluser','centos',10);     #把mysql客户端连接proxysql,proxysql真正代理到mysql服务器的账号指定用户名密码,默认操作都指定为10组的服务器
MySQL [(none)]> load mysql users to runtime;
MySQL [(none)]> save mysql servers to disk;
MySQL [(none)]> insert into mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply)VALUES  (1,1,'^SELECT.*FOR UPDATE$',10,1),(2,1,'^SELECT',20,1);      #往mysql_query_rules表中添加查询规则;select for update操作会申请写锁,所以默认放到10组(写)里面;其余select开头的操作放到20组(读)里面;其余所有默认操作都放到10组里面
MySQL [(none)]> load mysql query rules to runtime;
MySQL [(none)]> save mysql servers to disk;

Mysql客户端操作

[root@centos6 ~]# mysql -usqluser -pcentos -P6033 -h192.168.38.7 -e 'begin;select @@server_id;commit;'     #指定连接proxysql代理服务器的用户名密码、指定proxysql提供服务的端口、IP;不进入mysql界面执行mysql里面的操作;开启事务操作属于写操作,所以显示的是主节点的server-id
+-------------+
| @@server_id |
+-------------+
|          17 |
+-------------+
[root@centos6 ~]# mysql -usqluser -pcentos -P6033 -h192.168.38.7 -e 'select @@server_id;'      #select属于读操作,所以显示的是从节点的server-id
+-------------+
| @@server_id |
+-------------+
|          27 |
+-------------+

ProxySQL读写分离代理的更多相关文章

  1. MHA+ProxySQL 读写分离高可用

    文档结构如下: 1.ProxySQL说明 ProxySQL是mysql的一款中间件的产品,是灵活的mysql代理层,可以实现读写分离,支持query路由器的功能,支持动态指定sql进行缓存,支持动态加 ...

  2. MySQL ProxySQL读写分离实践

    目的 在上一篇文章MySQL ProxySQL读写分离使用初探里初步介绍了ProxySQL的使用,本文继续介绍它的一些特点和DBProxy的性能差异.深入一些去了解ProxySQL,通过测试来说明Pr ...

  3. mysqlfailover高可用与proxysql读写分离配置

    proxysql官方推荐两种高可用方案: 1.MHA+proxysql 2.mysqlrpladmin+proxysql MySQLfailover工具包含在mysqlrpladmin工具中,所以两者 ...

  4. MySQL ProxySQL读写分离使用初探

    目的 在美团点评DBProxy读写分离使用说明文章中已经说明了使用目的,本文介绍ProxySQL的使用方法以及和DBProxy的性能差异.具体的介绍可以看官网的相关说明,并且这个中间件也是percon ...

  5. Proxysql读写分离配置

    ProxySQL是Percona主推的读写分离中间件,下载地址为: https://www.percona.com/downloads/proxysql/ 一.安装 1:下载 wget https:/ ...

  6. ProxySQL 读写分离实践

    前言 ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎.具有以下特性: 连接池,而且是 multiplexing 主机和用户的最大连接数限制 自动下线后端DB 延迟超过阀值 ping ...

  7. ProxySQL读写分离

    我们首先看一下自己的环境: MHA已经搭建: master: slave: slave: MHA manager在172.16.16.34,配置文件如下: [root@localhost bin]# ...

  8. ProxySQL 读写分离方法

    转载自:https://www.jianshu.com/p/597b840bf70c (使用正则表达式实现基本的读/写分离) 在这一部分,我将通过一个示例来演示如何通过正则表达式来实现读/写分离. 首 ...

  9. ProxySQL读写分离测试(续)

      Preface       I've implemented ProxySQL on PXC yesterday but got some errors when configured query ...

随机推荐

  1. 【Bug】解决 SpringBoot Artifact contains illegal characters 错误

    解决 SpringBoot  Artifact contains illegal characters错误 错误原因:Artifact包含非法字符(大写字母) 解决方法:将Artifact名称改成小写 ...

  2. Mysql数据库(九)备份与恢复

    一.数据备份 1.使用mysqldmp命令备份 (1)备份一个数据库 mysqldump -u root -p dbname table1 table2 ... > D:\BackName.sq ...

  3. django-模型之从数据库获取数据(二)

    1.获取一条数据(字段值必须唯一) 2.条件查询filter 3.排除查询exclude 4.链式查询 5.查询后进行排序order_by 6.按字段查询values 7.插入数据create 8.数 ...

  4. Android_Fragment栈操作 commit()问题分析

    栈操作时遇到一个问题 getFragmentManager().beginTransaction() .replace(R.id.fl_container,bFragment) .addToBackS ...

  5. (Git) 优秀Java,Vue项目推荐

    Java 1.spring-boot-pay 地址:小柒2012/spring-boot-pay 这是一个支付案例,提供了包括支付宝.微信.银联在内的详细支付代码案例,对于有支付需求的小伙伴来说,这个 ...

  6. 关于 mybatis 报invalid comparison: java.util.Arrays$ArrayList and java.lang.String异常

    今天碰到个问题,来记录下,希望可以帮助到大家 贴错误源码: 这是一个根据list集合的查找数据的 sql,在接收list的时候加了判断 list != ‘ ’ “”,引起了集合与Stirng类型的比较 ...

  7. java的静态代理、jdk动态代理和cglib动态代理

    Java的代理就是客户端不再直接和委托类打交道,而是通过一个中间层来访问,这个中间层就是代理.使用代理有两个好处,一是可以隐藏委托类的实现:二是可以实现客户与委托类之间的解耦,在不修改委托类代码的情况 ...

  8. 关于JQUery.parseJSON()函数的知识札记

    JSON数据也许大家都很陌生,而对我来讲属于半成品,由于项目问题,做web虽然用的是JSON数据格式传输,但是关于解析这一块还真不知道该注意什么,更不知道它是如何解析的,由于最近要把串口通信协议与此一 ...

  9. Unicode字符串和非Unicode字符串

    什么是Unicode? Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每 ...

  10. Mybatis中多表关联时,怎么利用association优雅写resultMap来映射vo

    前言 有好一阵没碰mybatis了,这次的项目基于性能考虑,选了mybatis,写着写着,发现有下面的需求,比如两表联查,取其中各一部分字段,怎么更方便地用vo来接,这里犯了难: 我想的是,因为这个s ...