proxysql - MySQL读写分离 主从架构 负载均衡


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

ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎。

ProxySQL官网文档也是很齐全,MySQL5.7结合ProxySQL 案例讲述的也很清晰,现在先简单介绍下其特色功能点:

查询缓存

查询路由

故障转移

在线配置立刻生效无需重启

应用层代理

跨平台

高级拓展支持

防火墙

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

读写分离

数据库集群、分片

分库分表

主从切换

SQL审计

连接池 多路复用

负载均衡

查询重写

流量镜像

自动重连

自动下线

高可用

.........


本文所用环境:

系统均为CentOS7,并且关闭防火墙和selinux

ProxySQL版本:proxysql-2.0.10-1-centos7.x86_64

Mysql版本:mariadb

ProxySQL主机IP:192.168.100.2

Mysql主库IP:192.168.100.3

Mysql从库IP:192.168.100.4


前提条件: Mysql主从已经配置好了同步


# 安装ProxySQL:

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

yum install -y proxysql-2.0.10-1-centos7.x86_64.rpm


# 安装生成的文件:

[root@ProxySQL ~]#rpm -ql proxysql

/etc/init.d/proxysql     #启动脚本

/etc/proxysql.cnf        #配置文件,仅在第一次(/var/lib/proxysql/proxysql.db文件不存在)启动时有效

                                    #启动后可以在proxysql管理端中通过修改数据库的方式修改配置并生效(官方推荐方式。)

/usr/bin/proxysql        #主程序文件

/usr/share/proxysql/tools/proxysql_galera_checker.sh

/usr/share/proxysql/tools/proxysql_galera_writer.pl


# 启动proxysql:

/etc/init.d/proxysql start

#proxysql客户端监听在6033端口上,管理端监听6032端口

ss -tanl  # 查看端口


# 连接proxysql管理端进行配置:

mysql -uadmin -padmin -h127.0.0.1 -P6032  #默认的管理端账号密码都是admin,进去之后可以修改


# 开启WEB统计

update global_variables set variable_value='true' where variable_name='admin-web_enabled';

LOAD ADMIN VARIABLES TO RUNTIME;

SAVE ADMIN VARIABLES TO DISK;

select * from global_variables where variable_name LIKE 'admin-web%' or variable_name LIKE 'admin-stats%';

find / -name "proxysql.db"    # /var/lib/proxysql/proxysql.db

访问ip:6080/stats?metric=system 并使用stats:stats登录即可查看一些统计信息。 


# 添加后端的mysql主机:

#使用insert语句添加主机到mysql_servers表中,其中:hostgroup_id 1 表示写组,2表示读组。

insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.100.3',3306,1,'Write Group');

insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'192.168.100.4',3306,1,'Read Group');

select * from mysql_servers;  # 查看


# 添加可以访问后端主机的账号:

GRANT ALL ON *.* TO 'proxysql'@'10.42.%' IDENTIFIED BY 'wdqdmm@p';

#在后端mysql中添加可以增删改查的账号

insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','wdqdmm@p',1,1);

#在proxysql主机的mysql_users表中添加刚才创建的账号,proxysql客户端需要使用这个账号来访问数据库。

#default_hostgroup默认组设置为写组,也就是1

#当读写分离的路由规则不符合时,会访问默认组的数据库

select * from mysql_users\G;   # 查看


# 添加健康监测的账号:

GRANT SELECT ON *.* TO 'dongquan11'@'10.42.%' IDENTIFIED BY 'wdqdmm@0';

#在后端主机中添加可以访问数据库的账号,SELECT权限即可

set mysql-monitor_username='dongquan11'

set mysql-monitor_password='wdqdmm@0'

#在proxysql管理端中修改变量设置健康检测的账号


# 添加读写分离的路由规则:

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语句全部路由至hostgroup_id=2的组(也就是读组)

#但是select * from tb for update这样的语句是修改数据的,所以需要单独定义,将它路由至hostgroup_id=1的组(也就是写组)

#其他没有被规则匹配到的组将会被路由至用户默认的组(mysql_users表中的default_hostgroup)

MySQL [(none)]> select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;


# 将刚才我们修改的数据加载至RUNTIME中(参考ProxySQL的多层配置结构):

load mysql users to runtime;
load mysql servers to runtime;
load mysql query rules to runtime;
load mysql variables to runtime;
load admin variables to runtime;
#load进runtime,是配置生效
save mysql users to disk;
save mysql servers to disk;
save mysql query rules to disk;
save mysql variables to disk;
save admin variables to disk;
#save到磁盘(/var/lib/proxysql/proxysql.db)中,永久保存配置


# 测试读写分离

mysql -uproxysql -p123456 -h127.0.0.1 -P6033

show databases;


尝试修改数据库和查询:

create database bigboss;

create database weijinyun;

select user,host from mysql.user;


验证读写分离是否成功:

#proxysql有个类似审计的功能,可以查看各类SQL的执行情况。在proxysql管理端执行:

select * from stats_mysql_query_digest;

#从里面的hostgroup和digest_text值来看,所有的写操作都被路由至1组,读操作都被路由至2组,

#其中1组为写组,2组为读组!

#读写分离成功!!!


# 库、表说明

mysql -uadmin -padmin -h127.0.0.1 -P6032

show databases;

proxySQL默认有五个数据库,对每个库的功能介绍如下:

* main库:内存配置数据库,表里存放后端db实例、用户验证、路由规则等信息。表名以 runtime_开头的表示proxysql当前运行的配置内容,不能通过dml语句修改,只能修改对应的不以 runtime_ 开头的(在内存)里的表,然后LOAD使其生效, SAVE使其存到硬盘以供下次重启加载。

* disk库:是持久化到硬盘的配置库,对应/var/lib/proxysql/proxysql.db文件,也就是sqlite的数据文件。

* stats库:是proxysql运行抓取的统计信息库,包括到后端各命令的执行次数、流量、processlist、查询种类汇总/执行时间等等。

* monitor库:存储monitor模块收集的信息,主要是对后端db的健康、延迟检查。


# main库

show tables from main;

常用的几个表介绍如下:

   global_variables

设置变量,包括监听的端口、管理账号等。

   mysql_replication_hostgroups:

监视指定主机组中所有服务器的read_only值,并且根据read_only的值将服务器分配给写入器或读取器主机组。ProxySQL monitor模块会监控hostgroups后端所有servers 的read_only 变量,如果发现从库的read_only变为0、主库变为1,则认为角色互换了,自动改写mysql_servers表里面 hostgroup关系,达到自动 Failover 效果。

   mysql_servers

设置后端MySQL的表

   mysql_users

配置后端数据库的程序账号和监控账号。

   scheduler

调度器是一个类似于cron的实现,集成在ProxySQL中,具有毫秒的粒度。通过脚本检测来设置ProxySQL。


# stats库

show tables from stats;

常用的几个表介绍如下:

   stats_mysql_commands_counters

统计各种SQL类型的执行次数和时间,通过参数mysql-commands_stats控制开关,默认是ture。

   stats_mysql_connection_pool

连接后端MySQL的连接信息。

   stats_mysql_processlist

类似MySQL的show processlist的命令,查看各线程的状态。

   stats_mysql_query_digest

表示SQL的执行次数、时间消耗等。通过变量mysql-query_digests控制开关,默认是开。 

   stats_mysql_query_rules

路由命中次数统计。


# monitor库

show tables from monitor;

常用的几个表介绍如下:

   mysql_server_connect_log

连接到所有MySQL服务器以检查它们是否可用,该表用来存放检测连接的日志。

   mysql_server_ping_log

使用mysql_ping API ping后端MySQL服务器,检查它们是否可用,该表用来存放ping的日志。

   mysql_server_replication_lag_log

后端MySQL服务主从延迟的检测。


========================

# Add backends

INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (1,'127.0.0.1',21891);

...


# 后端健康检查

SHOW DATABASES;

SHOW TABLES FROM monitor;

SELECT * FROM monitor.mysql_server_connect_log LIMIT 10;

SELECT * FROM monitor.mysql_server_ping_log  LIMIT 10;

LOAD MYSQL SERVERS TO RUNTIME;

SELECT * FROM mysql_servers;


# MySQL复制主机组

SELECT * FROM monitor.mysql_server_read_only_log LIMIT 10;

SELECT * FROM mysql_replication_hostgroups;

SHOW CREATE TABLE mysql_replication_hostgroups\G;

INSERT INTO mysql_replication_hostgroups VALUES (1,2);

SELECT * FROM mysql_servers;

LOAD MYSQL SERVERS TO RUNTIME;  

SELECT * FROM monitor.mysql_server_read_only_log LIMIT 10;  

SELECT * FROM mysql_servers;

SAVE MYSQL SERVERS TO DISK;

SAVE MYSQL VARIABLES TO DISK;


# MySQL Users

SHOW CREATE TABLE mysql_users\G

INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('msandbox','msandbox',1);

Query OK, 1 row affected (0.00 sec)

SELECT * FROM mysql_users;     

LOAD MYSQL USERS TO RUNTIME;

SAVE MYSQL USERS TO DISK;


# ProxySQL统计

SHOW SCHEMAS;

SHOW TABLES FROM stats;

SELECT * FROM stats.stats_mysql_connection_pool;

SELECT * FROM stats_mysql_commands_counters WHERE Total_cnt;

SELECT * FROM stats_mysql_query_digest ORDER BY sum_time DESC;

SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;


# MySQL Query Rules

SHOW CREATE TABLE mysql_query_rules\G


INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (10,1,'msandbox','^SELECT c FROM sbtest1 WHERE id=\?$',2,1);


INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (20,1,'msandbox','DISTINCT c FROM sbtest1',2,1);


SELECT match_digest,destination_hostgroup FROM mysql_query_rules WHERE active=1 AND username='msandbox' ORDER BY rule_id;


SELECT * FROM stats_mysql_query_digest_reset LIMIT 1;

LOAD MYSQL QUERY RULES TO RUNTIME;


SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

SELECT hostgroup hg, SUM(sum_time), SUM(count_star) FROM stats_mysql_query_digest GROUP BY hostgroup;


# Query Caching

UPDATE mysql_query_rules set cache_ttl=5000 WHERE active=1 AND destination_hostgroup=2;

LOAD MYSQL QUERY RULES TO RUNTIME;

SELECT 1 FROM stats_mysql_query_digest_reset LIMIT 1; -- we reset the counters

SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;


# Query Rewrite

INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply) VALUES (30,1,'msandbox','DISTINCT(.*)ORDER BY c','DISTINCT\1',1);

SELECT rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply FROM mysql_query_rules ORDER BY rule_id;

LOAD MYSQL QUERY RULES TO RUNTIME;

SELECT 1 FROM stats_mysql_query_digest_reset LIMIT 1;

SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

SELECT hits, mysql_query_rules.rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules ORDER BY mysql_query_rules.rule_id;

UPDATE mysql_query_rules SET apply=0 WHERE rule_id=20;

SELECT rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply FROM mysql_query_rules ORDER BY rule_id;

LOAD MYSQL QUERY RULES TO RUNTIME;

SELECT * FROM stats.stats_mysql_query_rules;

SELECT 1 FROM stats_mysql_query_digest_reset LIMIT 1;

SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

LOAD MYSQL QUERY RULES TO RUNTIME;

SELECT hits, mysql_query_rules.rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply FROM mysql_query_rules NATURAL JOIN stats.stats_mysql_query_rules; 

SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

========================


https://blog.csdn.net/CL_YD/article/details/80198766

https://my.oschina.net/cart/blog/2907232

https://github.com/sysown/proxysql/blob/v1.2.2/doc/configuration_howto.md

http://www.fordba.com/mysql_sharding_with_proxysql.html

https://www.cnblogs.com/f-ck-need-u/p/9300829.html

https://www.linuxidc.com/Linux/2019-05/158644.htm


签名:这个人很懒,什么也没有留下!
最新回复 (0)
返回