proxy SQL读写分离

proxysql

mysql中间件,两个版本,官方和percona版,percona版是基于官方版基础上修改的,C++语言开发,轻量级但性能优异,支持处理千亿级数据,具有中间件所需要的绝大多数功能

包括:

多种方式的读写分离
定制基于用户。基于schema模式、基于语句的规则对sql语句进行路由
缓存查询结果
后端节点监控

官方手册

基于yum源安装:官网手册中的内容一般都是最新版的

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

安装

yum install proxysql 
...
rpm -ql proxysql
	/etc/proxysql.cnf
	/etc/systemd/system/proxysql.service
	/usr/bin/proxysql
	基于SQLITE的数据库文件:/var/lib/proxysql

配置proxysql
proxysql的配置文件不需要手动去改,它内置了一个小的数据库,我们在数据库操作完成提交后其实就是修改了配置文件

proxysql有两个默认端口

6032:proxysql的管理端口
6033:proxysql对外提供服务的端口

proxysql启动管理仍是由systemd管理,直接使用systemctl start proxysql即可

使用mysql客户端连接到proxysql的管理接口6032,默认的管理员和密码都是admin

mysql -uadmin -padmin -P6032 -h127.0.0.1

MySQL [(none)]> 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)
说明:
在main和monitor数据库中的表,runtime_开头的表时运行时的配置,不能修改,只能修改非runtime_开头的表
修改后必须load tb_name to runtime 才能加载到runtime表生效。
执行save tb_name to disk将配置保存到磁盘

实验环境:
  一主两从,先实现主从复制

集群信息
四台centos7,数据库使用的centos7镜像中默认带的mariadb-server5.5
角色信息
proxysql:192.168.40.5
master:192.168.40.7
slave:192168.40.17,192.168.40.27

注意:从服务器的配置文件中必须要有read-only这一项,proxysql就是根据此项来判断哪个是从哪个是主的


在安装好proxysql后启动服务,登录proxysql的内置数据库进行配置

mysql -uadmin -padmin -P6032 -h127.0.0.1

登录proxysql后向数据库添加主从架构,告诉proxysql要管理的服务器有哪些

show databases;

use main

select * from mysql_servers;

# 将数据库服务器加入到表中分组,分组的作用是让proxysql知道谁是主谁是从,写操作有写的组,读操作有读的组
insert into mysql_servers(hostgroup_id,hostname,port) values(1,'192.168.40.7',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values(1,'192.168.40.17',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values(1,'192.168.40.27',3306);

# 目前的组id都是1,后面的配置中,proxysql会自动根据从服务器配置中read-only一项自动区分谁是从服务器,自动分组
	
load mysql servers to runtime;	
# 注意上面的表名字中有下划线_但是生效时的命令中不能后下划线,用空格分开
save mysql servers to disk;
	
select * from mysql_servers\G	:查看添加的数据库服务器信息

添加监控后端节点的用户,proxysql通过每个节点的read-only值来自自动调整它们是属于读组还是写组
主数据库服务器40.7上创建监控用户,执行:

grant replication client on *.* to monitor@'192.168.40.%' identified by '123123';
# 从服务器会自动同步此用户

返回到proxysql上配置监控

select * from global_variables;	:查看监控用户的信息

# 此表中默认就是这个用户名,如果创建用户的时候是其他名字,就需要改
set mysql-monitor_username='monitor';	
# 设置密码
set mysql-monitor_password='123123';
	
load mysql variables to runtime;
save mysql variables to disk;

查看proxysql与数据库是否能连通,一个日志文件,null值表示正常

select * from mysql_server_ping_log;
select * from mysql_server_connect_log;
# 出现null说明没有问题

查看read_only和replication_lag的监控日志

select * from mysql_server_read_only_log;
select * from mysql_server_replication_lag_log;

设置分组信息

需要修改的是main库中的mysql_replication_hostgroup表,该表中有4个字段:writer_hostgroup,reader_hostgroup,check_type,comment,指定写组的id=1,读组的id=2

查看表内有几个字段

show create table mysql_replication_hostgroups;

将读和写的id号分别加入到表中,让proxysql自动识别谁是写服务器,谁是读服务器

insert into mysql_replication_hostgroups values (1,2,'read_only',"test");	test为描述内容

查看表内的内容

select * from mysql_replication_hostgroups;
	+------------------+------------------+------------+---------+
	| writer_hostgroup | reader_hostgroup | check_type | comment |
	+------------------+------------------+------------+---------+
	| 1                | 2                | read_only  |   test  |
	+------------------+------------------+------------+---------+
表内的内容:
	writer_hostgroup:是写服务器的id号
	reader_hostgroup	:是读服务器的ID号
	check_type			:根据什么类型区分读和写
	comment				:描述

让命令生效:
	load mysql servers to runtime; 
	save mysql servers to disk; 

添加完成查看proxysql是否为我们自动分配了组

SELECT * FROM mysql_servers;

select hostgroup_id,hostname,port,status,weight from mysql_servers;
	+--------------+---------------+------+--------+--------+
	| hostgroup_id | hostname      | port | status | weight |
	+--------------+---------------+------+--------+--------+
	| 1            | 192.168.40.7  | 3306 | ONLINE | 1      |
	| 2            | 192.168.40.17 | 3306 | ONLINE | 1      |
	| 2            | 192.168.40.27 | 3306 | ONLINE | 1      |
	+--------------+---------------+------+--------+--------+

在主服务器节点上创建访问用户,从服务器会自动同步此用户信息

grant all on *.* to sqluser@'192.168.40.%' identified by '123123';

在proxysql配置,将用户sqluser添加到mysql_users表中

INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('root','',1);	root用户不想加也行

INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('sqluser','123123',1);
# username和password的含义应该很清楚。 default_hostgroup是主机组,如果没有针对特定查询的匹配查询规则,则该主机组将用于发送由该特定用户生成的流量发送到默认组
			
load mysql users to runtime;
save mysql users to disk;

退出proxysql在shell命令行中测试,使用sqluser测试是否能路由到默认的1写组实现读、写数据

# 目前基本实现proxysql和数据库可以通信,但是没有实现读写分离	
mysql -usqluser -p123123 -h192.168.40.5 -P6033 -e 'select @@server_id'
	+-------------+
	| @@server_id |
	+-------------+
	|           1 |		:
	+-------------+
mysql -usqluser -p123123 -h192.168.40.5 -P6033 -e 'create database cheng'	:创建用户

ProxySQL在stats架构中实时统计信息:

show tables from stats;

select * from stats.stats_mysql_connection_pool\G
	当服务器被删除(完全删除或从主机组移开)时,它在内部被标记为OFFLINE_HARD,而实际上并未被删除。这就是为什么它将端口3306上的服务器显示OFFLINE_HARD为hostgroup1的原因。
	该表返回有关发送到每个服务器的流量的许多信息。
	
SELECT * FROM stats_mysql_commands_counters WHERE Total_cnt\G
	该表stats_mysql_commands_counters返回有关执行的语句类型以及执行时间分配的详细信息!

SELECT * FROM stats_mysql_query_digest ORDER BY sum_time DESC \G
	执行查询的更多详细信息

SELECT hostgroup hg,sum_time,count_star,digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC\G
	信息太多,很难在此处进行格式化。仅获取重要指标

配置路由规则,实现读写分离

与规则有关的表:
mysql_query_rules,mysql_query_rules_fast_routing,后者是前者的扩展,1.4.7开始支持

插入路由规则:将select语句分离到2的读组中,select语句中有一个特殊语句select…for update它会申请写锁,应该路由到1的写组中

insert into mysql_query_rules  (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (1,1,'sqluser','^SELECT.*for update$',1,1);
insert into mysql_query_rules  (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (2,1,'sqluser','^SELECT',2,1);
			
load mysql query rules to runtime;
save mysql query rules to disk;

查看定义的规则:

select rule_id,active,username,match_digest,destination_hostgroup,apply from mysql_query_rules;

注意:因为proxysql根据rules_id顺序进行规则匹配,select...for update规则的id必须要小于普通的select规则的id

以上就是整个步骤,下面是验证

在shell命令行中:

[root@centos7_5 ~]# mysql -usqluser -p123123 -h192.168.40.5 -P6033 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+
[root@centos7_5 ~]# mysql -usqluser -p123123 -h192.168.40.5 -P6033 -e 'select @@server_id'
+-------------+
| @@server_id |
+-------------+
|           3 |
+-------------+	
	此命令在没有定义路由规则时,查询的结果是1写组,此时再次查看就是读组了,因为规则中定义了只要是查询都在2
读组中,说明成功实现读写分离
	重复执行读操作时,有时候会切换到另一台server-id为3的从服务器上

# 此命令因为开头是begin开启事务,而规则中定义的select开头的都发往读服务器,所以server-id为1
mysql -usqluser -p123123 -h192.168.40.5 -P6033 -e 'begin;select @@server_id;commit;'
	+-------------+
	| @@server_id |
	+-------------+
	|           1 |
	+-------------+

在proxysql中执行:查看具体命令执行的时间,流量,默认排序是按照时间

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;
发布了63 篇原创文章 · 获赞 0 · 访问量 2219

猜你喜欢

转载自blog.csdn.net/qq_43058911/article/details/103081138