MySQL-ProxySQL中间件简介

同类型产品
  • MySQL Route:是现在MySQL官方Oracle公司发布出来的一个中间件。
  • Atlas:是由奇虎360公发的基于MySQL协议的数据库中间件产品,它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了若干Bug,并增加了很多功能特性。目前该产品在360内部得到了广泛应用。
  • DBProxy:是由美团点评公司技术工程部DBA团队(北京)开发维护的一个基于MySQL协议的数据中间层。它在奇虎360公司开源的Atlas基础上,修改了部分bug,并且添加了很多特性。
  • Cobar:是阿里巴巴B2B开发的关系型分布式系统,管理将近3000个MySQL实例。 在阿里经受住了考验,后面由于作者的走开的原因cobar没有人维护 了,阿里也开发了tddl替代cobar。
  • MyCAT:是社区爱好者在阿里cobar基础上进行二次开发,解决了cobar当时存 在的一些问题,并且加入了许多新的功能在其中。目前MyCAT社区活跃度很高,目前已经有一些公司在使用MyCAT。总体来说支持度比较高,也会一直维护下去。

ProxySQL是使用C++语言开发的,官网文档也很齐全,以下是其特色功能点:

上面提到的MyCAT我Mysql哪一个分类文章有亲测过程,有兴趣小伙伴可以移步看看.

https://www.cnblogs.com/you-men/p/12838333.html

  • 查询缓存
  • 查询路由
  • 故障转移
  • 在线配置立刻生效无需重启
  • 应用层代理
  • 跨平台
  • 高级拓展支持
  • 防火墙

通过上述,我们可以看到ProxySQL可以做许多事情,已经不仅仅是纯粹的MySQL读写分离,其实我们通过后面所述结合业务发散,ProxySQL还可以支持以下高级功能:

  • 读写分离
  • 数据库集群、分片
  • 分库分表
  • 主从切换
  • SQL审计
  • 连接池 多路复用
  • 负载均衡
  • 查询重写
  • 流量镜像
  • 自动重连
  • 自动下线

高可用架构

ProxySQL部署配置

环境清单

list

CentOS7.3
proxysql-2.0.12-1-centos7.x86_64.rpm
mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar
主机 操作系统 IP地址 硬件/网络
Mysql105 CentOS7.3 192.168.0.105 2C4G / nat
Mysql106 CentOS7.3 192.168.0.106 2C4G / nat
Mysql107 CentOS7.3 192.168.0.107 2C4G / nat
ProxySQL109 CentOS7.3 192.168.0.109 2C4G / nat
安装Mysql
#!/usr/bin/env bash
# Author: ZhouJian
# Mail: 18621048481@163.com
# Time: 2019-9-3
# Describe: CentOS 7 Install Mysql.rpm Script
clear
echo -ne "\\033[0;33m"
cat<<EOT
_oo0oo_
088888880
88" . "88
(| -_- |)
0\\ = /0
___/'---'\\___
.' \\\\\\\\| |// '.
/ \\\\\\\\||| : |||// \\\\
/_ ||||| -:- |||||- \\\\
| | \\\\\\\\\\\\ - /// | |
| \\_| ''\\---/'' |_/ |
\\ .-\\__ '-' __/-. /
___'. .' /--.--\\ '. .'___
."" '< '.___\\_<|>_/___.' >' "".
| | : '- \\'.;'\\ _ /';.'/ - ' : | |
\\ \\ '_. \\_ __\\ /__ _/ .-' / /
====='-.____'.___ \\_____/___.-'____.-'=====
'=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
建议系统 CentOS7
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# PS:请尽量使用纯净的CentOS7系统,我们会在服务器安装Mysql5.7,
# 将mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar包和脚本放到root目录下执行即可,密码为ZHOUjian.20
EOT
echo -ne "\\033[m"
init_security() {
systemctl stop firewalld
systemctl disable firewalld &>/dev/null
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
sed -i '/^GSSAPIAu/ s/yes/no/' /etc/ssh/sshd_config
sed -i '/^#UseDNS/ {s/^#//;s/yes/no/}' /etc/ssh/sshd_config
systemctl enable sshd crond &> /dev/null
echo -e "\033[32m [安全配置] ==> OK \033[0m"
}
init_yumsource() {
if [ ! -d /etc/yum.repos.d/backup ];then
mkdir /etc/yum.repos.d/backup
fi
mv /etc/yum.repos.d/* /etc/yum.repos.d/backup 2>/dev/null if ! ping -c2 www.baidu.com &>/dev/null
then
echo "您无法上外网,不能配置yum源"
exit
fi
curl -o /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
timedatectl set-timezone Asia/Shanghai
echo "nameserver 114.114.114.114" > /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
chattr +i /etc/resolv.conf echo -e "\033[32m [YUM Source] ==> OK \033[0m"
}
init_mysql() {
rpm -e mariadb-libs --nodeps
rm -rf /var/lib/mysql
rm -rf /etc/my.cnf
tar xvf /root/mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar -C /usr/local/
cd /usr/local
rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm \
mysql-community-client-5.7.23-1.el7.x86_64.rpm \
mysql-community-common-5.7.23-1.el7.x86_64.rpm \
mysql-community-libs-5.7.23-1.el7.x86_64.rpm
rm -rf mysql-community-*
}
changepass() {
sed -i '/\[mysqld]/ a skip-grant-tables' /etc/my.cnf
systemctl restart mysqld
mysql <<EOF
update mysql.user set authentication_string='' where user='root' and Host='localhost';
flush privileges;
EOF
sed -i '/skip-grant/d' /etc/my.cnf
systemctl restart mysqld
yum -y install expect ntpdate expect <<-EOF
spawn mysqladmin -uroot -p password "ZHOUjian.20"
expect {
"password" { send "\r" }
}
expect eof
EOF
systemctl restart mysqld
}
main() {
init_hostname
init_security
init_yumsource
init_mysql
changepass
}
main
配置Mysql

mysql主库配置

[root@mysqlhost ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid server-id = 1
log-bin=mysql-bin

mysql从库配置

[root@mysql-from ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid server-id = 2
log-bin = mysql-bin

主从三台服务器分别重启服务

service mysqld restart

主库授权从库
# 创建用于同步的用户账号及密码
grant replication slave on *.* to 'slave'@'192.168.0.%' identified by 'ZHOUjian.200'; # 重新加载权限表,更新权限
flush privileges; # 查看master的状态
#mysql> show master status;
#+------------------+----------+--------------+------------------+-------------------+
#| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
#+------------------+----------+--------------+------------------+-------------------+
#| mysql-bin.000001 | 600 | | | |
#+------------------+----------+--------------+------------------+-------------------+
#1 row in set (0.00 sec)
从库开启Slave
change master to
master_host='192.168.0.102',
master_user='slave',
master_password='ZHOUjian.200',
master_auto_position=0; mysql> start slave; # 查看从库状态
mysql> show slave status\G;
下载部署ProxySQL

https://github.com/sysown/proxysql/releases

wget https://github.com/sysown/proxysql/releases/download/v2.0.12/proxysql-2.0.12-1-centos7.x86_64.rpm

yum install perl-DBD-MySQL3 -y
rpm -ivh proxysql-2.0.12-1-centos7.x86_64.rpm
service proxysql start
proxysql --version
# ProxySQL version 2.0.12-38-g58a909a, codename Truls # 本地配置文件
# proxysql 有个配置文件/etc/proxysql.cnf,只在第一次启动的时候有用,
# 后续所有的配置修改都是对 SQLite 数据库操作,并且不会更新到proxysql.cnf文件中。 # ProxySQL 绝大部分配置都可以在线修改,配置存储在/var/lib/proxysql/proxysql.db ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:6032 *:*
LISTEN 0 128 *:6033 *:* # 管理接口的端口是 6032 , 账号密码是 admin( 可以动态修改 ) 只能通过本地连接 , # 客户端接口的端口是 6033 , 账号密码通过管理接口去设置。
登录配置ProxySQL

登录管理界面,配置信息从启动进程的配置文件查看

cat /etc/proxysql.cnf |grep admin
admin_variables=
admin_credentials="admin:admin"
# mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock" mysql -uadmin -padmin -h 127.0.0.1 -P6032 --prompt='proxysql>' # 不推荐跟传统服务一样修改/etc/proxysql.conf
# 之所以不推荐,是因为我们可以通过ProxySQL控制台在线修改配置,无需重启,立即生效。 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 |
+-----+---------------+-------------------------------------+ # main:默认数据库,存放用户验证、路由规则等信息。我们要做的配置都是针对这个库的
# disk:持久化到硬盘的配置
# stats:proxysql运行抓取的统计信息,如各命令的执行次数、查询执行时间等
# monitor:monitor模块收集的信息,db的健康情况、各种检查等 # 设置SQL日志记录[ProxySQL]
set mysql-eventslog_filename='queries.log'; # 添加主从[ProxySQL]
insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.105',3306,1,'主库');
insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.106',3306,9,'从库');
insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.107',3306,1,'从库'); # 查看主从[ProxySQL]
proxysql>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.0.105 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | 主库 |
| 1 | 192.168.0.106 | 3306 | 0 | ONLINE | 9 | 0 | 1000 | 0 | 0 | 0 | 从库 |
| 1 | 192.168.0.107 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | 从库 |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+----------- # hostgroup_id:一个角色一个id,该表的主键是hostgroup_id+hostname+port
# hostname:db实例IP
# port:db实例端口
# weight:权重,如果有多个相同角色的实例,会优先选择权重高的
# status:状态
# -ONLINE 正常
# -SHUNNED 临时被剔除
# -OFFLINE_SOFT 软离线状态,不再接受新的连接,已建立的连接会等待
# -OFFLINE_HARD 离线,不接收新连接, 已建立的连接也会强制断开(宕机或者网络不可用)
# max_connections:最大连接数
# max_replication_lag:允许的最大延迟 # 创建主从账号[MySQL]
create user 'proxysql'@'%' identified by 'ZHOUjian.21'; mysql> grant all privileges on *.* to 'proxysql'@'%' with grant option; # 添加主从账号[ProxySQL]
insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','ZHOUjian.21',1,1); # 查看主从账号
select * from mysql_users\G;
*************************** 1. row ***************************
username: proxysql
password: ZHOUjian.21
active: 1
use_ssl: 0
default_hostgroup: 1
default_schema: NULL
schema_locked: 0
transaction_persistent: 1
fast_forward: 0
backend: 1
frontend: 1
max_connections: 10000
comment: # 创建监控账号[MySQL]
CREATE USER 'monitor'@'%' IDENTIFIED BY 'ZHOUjian.21';
GRANT SELECT ON *.* TO 'monitor'@'%' WITH GRANT OPTION; # 添加监控账号[ProxySQL]
set mysql-monitor_username='monitor';
set mysql-monitor_password='ZHOUjian.21'; # 查看监控账号[ProxySQL]
select * from global_variables where variable_name like 'mysql-monitor_%';
+--------------------------------------------------------------+----------------+
| variable_name | variable_value |
+--------------------------------------------------------------+----------------+
| mysql-monitor_enabled | true |
| mysql-monitor_connect_timeout | 600 |
| mysql-monitor_ping_max_failures | 3 |
| mysql-monitor_ping_timeout | 1000 |
| mysql-monitor_read_only_max_timeout_count | 3 |
| mysql-monitor_replication_lag_interval | 10000 |
| mysql-monitor_replication_lag_timeout | 1000 |
| mysql-monitor_groupreplication_healthcheck_interval | 5000 |
| mysql-monitor_groupreplication_healthcheck_timeout | 800 |
| mysql-monitor_groupreplication_healthcheck_max_timeout_count | 3 |
| mysql-monitor_groupreplication_max_transactions_behind_count | 3 |
| mysql-monitor_galera_healthcheck_interval | 5000 |
| mysql-monitor_galera_healthcheck_timeout | 800 |
| mysql-monitor_galera_healthcheck_max_timeout_count | 3 |
| mysql-monitor_replication_lag_use_percona_heartbeat | |
| mysql-monitor_query_interval | 60000 |
| mysql-monitor_query_timeout | 100 |
| mysql-monitor_slave_lag_when_null | 60 |
| mysql-monitor_threads_min | 8 |
| mysql-monitor_threads_max | 128 |
| mysql-monitor_threads_queue_maxsize | 128 |
| mysql-monitor_wait_timeout | true |
| mysql-monitor_writer_is_also_reader | true |
| mysql-monitor_username | monitor |
| mysql-monitor_password | ZHOUjian.21 |
| mysql-monitor_history | 600000 |
| mysql-monitor_connect_interval | 60000 |
| mysql-monitor_ping_interval | 10000 |
| mysql-monitor_read_only_interval | 1500 |
| mysql-monitor_read_only_timeout | 500 |
+--------------------------------------------------------------+----------------+ # 也可以像下面这样快速定位
select @@mysql-monitor_username;
+--------------------------+
| @@mysql-monitor_username |
+--------------------------+
| monitor |
+--------------------------+ select @@mysql-monitor_password;
+--------------------------+
| @@mysql-monitor_password |
+--------------------------+
| ZHOUjian.21 |
+--------------------------+

检测监控

# 检测上述配置是否正确:connect_error为NULL则正确
SELECT * FROM monitor.mysql_server_connect_log ORDER BY time_start_us DESC LIMIT 10;
+---------------+------+------------------+-------------------------+------------------------------------------------------------------------+
| hostname | port | time_start_us | connect_success_time_us | connect_error |
+---------------+------+------------------+-------------------------+------------------------------------------------------------------------+
| 192.168.0.106 | 3306 | 1591457209205112 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) |
| 192.168.0.107 | 3306 | 1591457208536560 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) |
| 192.168.0.105 | 3306 | 1591457207868147 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) | SELECT * FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 10;
+---------------+------+------------------+----------------------+------------------------------------------------------------------------+
| hostname | port | time_start_us | ping_success_time_us | ping_error |
+---------------+------+------------------+----------------------+------------------------------------------------------------------------+
| 192.168.0.105 | 3306 | 1591457358442163 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) |
| 192.168.0.106 | 3306 | 1591457358348350 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) |
| 192.168.0.107 | 3306 | 1591457358252207 | 0 | Access denied for user 'monitor'@'192.168.0.109' (using password: YES) |
配置读写映射[ProxySQL]

这里配置主从自动切换: 互为主从,自动切换,保证高可用

添加读写分离的路由规则

  • 将select语句全部路由至hostgroup_id=2的组(也就是读组)
  • 但是select * from tb for update这样的语句是修改数据的,所以需要单独定义,将它路由至hostgroup_id=1的组(也就是写组)
  • 其他没有被规则匹配到的组将会被路由至用户默认的组(mysql_users表中的default_hostgroup)
insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^SELECT.*FOR UPDATE$',1,1);

insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',2,1);

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 |
+---------+--------+----------------------+-----------------------+-------+ # 将刚才我们修改的数据加载至RUNTIME中(参考ProxySQL的多层配置结构):
# load进runtime,使配置生效
load mysql query rules to runtime;
load admin variables to runtime; # save到磁盘(/var/lib/proxysql/proxysql.db)中,永久保存配置
save mysql query rules to disk;
save admin variables to disk;

测试读写分离

链接proxysql客户端

登录用户是刚才我们在mysql_user表中创建的用户,端口为6033

mysql -uproxysql -ppwproxysql -h127.0.0.1 -P6033

验证读写分离是否成功
  • proxysql有个类似审计的功能,可以查看各类SQL的执行情况。在proxysql管理端执行:
  • 从下面的hostgroup和digest_text值来看,所有的写操作都被路由至1组,读操作都被路由至2组,
  • 其中1组为写组,2组为读组!
 select * from stats_mysql_query_digest;

ProxySQL简介原理及读写分离应用的更多相关文章

  1. ProxySQL+Mysql实现数据库读写分离实战

    ProxySQL介绍 ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎.具有以下特性:http://www.proxysql.com/ 1.连接池,而且是multiplexing 2 ...

  2. MySQL中间件之ProxySQL(2):初试读写分离

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.实现一个简单的读写分离 这里通过一个简单的示例实现ProxySQL ...

  3. mysql proxysql的简单部署读写分离

    环境需求(centos) proxysql-server(1)-- 地址:proxysql-service mysql-master-server(1)--- 地址:mysql1-service my ...

  4. MHA + proxysql 高可用以及读写分离

    环境 vip 192.168.1.101 slave 192.168.1.16 5.7.17 3306 master 192.168.1.135 5.7.17 3306 proxysql 192.16 ...

  5. 利用ProxySQL实现MySQL的读写分离

    本文简单介绍ProxySQL的安装及如果实现后端MySQL主从结构的读写分离. 一.ProxySQL安装 Proxy官方地址:https://proxysql.com/ proxysql-2.0.8- ...

  6. ProxySQL(2):初试读写分离

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9278839.html 实现一个简单的读写分离 这里通过一个简单的示例实现ProxySQL的读写分离功能,算是 ...

  7. ProxySQL读写分离代理

    实现ProxySQL反向代理Mysql读写分离 简介 ProxySQL相当于小型的数据库,在磁盘上有存放数据库的目录:ProxySQL用法和mysql相似 启动ProxySQL后会有两个监听端口: 6 ...

  8. Linux下MySQL主从复制(GTID)+读写分离(ProxySQL)-实施笔记

    GTID概念: GTID( Global Transaction Identifier)全局事务标识.GTID 是 5.6 版本引入的一个有关于主从复制的重大改进,相对于之前版本基于 Binlog 文 ...

  9. ProxySQL+MGR实现读写分离和主节点故障无感知切换 - 完整操作记录

    前面的文章介绍了ProxySQL用法,这里说下ProxySQL中间件针对Mysql组复制模式实现读写分离以及主节点故障时能够自动切换到新的主节点,而应用对此过程无感知的功能.Mysql组复制(MGR) ...

随机推荐

  1. 五一以来,国产手机受到cmtwg, nkvhu, qhsz等几款恶意软件肆虐。

    受影响手机包括魅族,中国移动等国产手机. 5月12日开始有人在百度知道提问cmtwg,5月13日mx吧也有人在发贴. 我接到有问题的手机时间更早,大约就是五一之后. 出现问题的几个牌子的国产手机,似乎 ...

  2. HttpRequestUtils post get请求

    package com.nextjoy.projects.usercenter.util.http; /** * Created by Administrator on 2016/10/20. */ ...

  3. centos6下filebeat多开问题

    centos6下filebeat多开问题 0. 场景 比如之前在用filebeat做收集,但是想新开一个实例把之前的日志全部重新导一遍,如果直接指定filebeat -c 是不行的,因为filebea ...

  4. 5.3 Go 匿名函数

    5.3 Go 匿名函数 Go支持匿名函数,顾名思义就是没名字的函数. 匿名函数一般用在,函数只运行一次,也可以多次调用. 匿名函数可以像普通变量一样被调用. 匿名函数由不带函数名字的函数声明与函数体组 ...

  5. 你真的了解负载均衡中间件nginx吗?

    前言 nginx可所谓是如今最好用的软件级别的负载均衡了.通过nginx的高性能,并发能力强,占用内存下的特点,可以搭建高性能的代理服务.同时nginx还能作为web服务器,反向代理,动静分离服务器. ...

  6. MY FIRST PAGE!

    RT. This is my first time to create and customize my cnblogs. Nice to see you!

  7. 欧拉函数 BZOJ2705

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 3154  Solved: 1968[Submit][ ...

  8. poj1149 经典建模

    http://wenku.baidu.com/view/0ad00abec77da26925c5b01c.html 以上内容均为转载 #include<queue> #include< ...

  9. 【python 】文件下载进度条(装逼利器)

    基础版 import requests url = "http://mp.111ttt.cn/mp3free/81135985.mp3" rsp = requests.get(ur ...

  10. [转]从 Apple TV 看电视的进化

    电视被许多人吐槽为 “几十年没变过的东西”,因此苹果也被寄予厚望能改变这件事物.可惜的是,这种期望在空中飘了这么久,苹果也没玩出多少花样,直到这次发布会 Apple TV 才有了一些值得期待的改进. ...