当前位置: 首页 > article >正文

mysql读写分离与proxysql的结合

上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。

读写分离,拿spring boot项目来说,可以有2种方式:
1)设置2个数据源,读和写分开使用
2)使用中间件,如proxysql。它会根据sql语句自动匹配到主、从库

方式一好处是灵活,可控,缺点是需要自己写一点代码,已有的项目修改可能比较大;proxysql的话,还是跟之前一样,只有一个数据源,代码好像也不用改。问题是,我用了一下,感觉有一些坑。也许是还不懂得怎么使用的缘故。

以下是步骤和一些坑:

一、安装proxysql

proxysql是一个中间件,需要安装。安装好了之后,可以把它看作一个mysql,因为它是一个伪装成mysql的中介。你看看,这个”“mysql数据源”:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.10.249:6033/testdb?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
    username: work
    password: 123456 # 你的数据库密码

其中 192.168.10.249:6033 就是proxysql的地址。简直了。

1、安装

还是跑在docker里。拉取 ProxySQL Docker 镜像

sudo docker pull proxysql/proxysql

目前由于不可描述的原因,各种镜像源大都不可用,令人无语。费了九牛二虎之力,才下载到一个镜像。中国程序员真难啊。方法可参考拙作:修改centos7的dns解决docker拉取镜像超时问题

2、在mysql主库中创建监控用户

sudo docker exec -it mysql-1 /bin/bash

mysql -uroot -pdata2025

--监控账号与默认保持一致最保险(monitor/monitor)
create user 'monitor' identified WITH mysql_native_password by 'monitor';

-- 授予监控用户必要的权限
GRANT USAGE ON *.* TO monitor@'%';

-- 刷新权限
FLUSH PRIVILEGES;

3、准备配置文件

mkdir /home/admin/proxysql

然后在该文件夹下创建配置文件:proxysql.cnf

admin_variables = {
    admin_credentials = "admin:admin"
    mysql_ifaces = "0.0.0.0:6032"
}

mysql_variables = {
    threads = 4
    max_connections = 2048
    default_query_delay = 0
    default_query_timeout = 36000000
    have_compress = true
    poll_timeout = 2000
    interfaces = "0.0.0.0:6033"
    default_schema = "information_schema"
    stacksize = 1048576
    server_version = "8.0.23"

    monitor_history=60000
    monitor_connect_interval=200000
    monitor_ping_interval=200000
}

mysql_servers = (
    { address = "mysql-1", port = 3306, hostgroup = 0,weight=1, max_connections = 1000 },
    { address = "mysql-2", port = 3306, hostgroup = 1, weight=1,max_connections = 1000 }
)

mysql_users = (
    { username = "work", password = "123456", default_hostgroup = 0, active = 1 }
)

mysql_query_rules = (
    { rule_id = 1, active = 1, match_digest = "^SELECT.*", destination_hostgroup = 1, apply = 1 },
    { rule_id = 2, active = 1, match_digest = "^(INSERT|UPDATE|DELETE|REPLACE).*", destination_hostgroup = 0, apply = 1 }
)

4、创建 docker 容器

跟mysql的主库、从库共用一个docker网络:mysql-tier。详见上一篇《设置mysql的主从复制模式》

sudo docker run -d \
  --name proxysql \
  --network mysql-tier \
  -p 6032:6032 \
  -p 6033:6033 \
  -v /home/admin/proxysql/proxysql.cnf:/etc/proxysql.cnf \
  -v /home/admin/proxysql/data:/var/lib/proxysql \
  proxysql/proxysql \
  proxysql --initial -f -c /etc/proxysql.cnf

5、操作连接

在这里插入图片描述
在这里插入图片描述
可读可写,very good。

但是,可别高兴得太早。我在里面遇到了一些坑:

二、遇到的坑

1、监控账号

proxysql为了监控mysql,需要mysql提供一个监控账号,该账号权限不用太多,据说只需USAGE即可(见前面脚本)。问题是,这个监控账号,最好是与默认保持一致,即账号名和密码都是monitor。如果改成其他,真不知道在哪里设置。豆包信誓旦旦地说在配置文件里设置,而通义千问则说配置文件里设不了,应该在命令行里写。结果两个都无效,proxysql总是提示无法连接mysql。搞来搞去,我只好将monitor账号的密码改为"monitor",与默认保持一致,就好了。

2、mysql版本问题

配置文件中,对标mysql的版本号(mysql_variables:server_version)一定要写对。比如我的mysql是mysql8,但配置文件内容是从网上抄过来的,里面写的是5.0.9,结果运行的时候就报错了:unknown system variable ‘query_cache_size’。这是因为
mysql8之后,取消了"query_cache_size"这个属性,由于配置文件指明是mysql5,proxysql仍然使用了这个属性,所以就报错了。把配置文件提交给AI,它也看不出问题所在。

在这里插入图片描述

3、一个库故障后整个proxysql无法使用

在主库、从库都正常的情况下,用了一下,好像没啥问题。

但为了测试,我手动将从库关停后,结果整个proxysql都没办法使用了。proxysql其实已经检测到某个库出了问题,但不知道为什么,它没有将该库的状态设为离线或停止,仍然显示为"ONLINE"。

我在AI上问来问去,通义千问也,豆包也,chatGPT也,都问不出一个子丑寅卯。它们总喜欢穷举一些原因,我不得不一再强调,网络没有问题,在主从库都正常的情况下一切正常,然后它就说,既然如此,那问题很有可能出在proxysql的配置上,巴拉巴拉巴拉,吐出一大堆文字。并且不是一下子吐出,而是装叉地一行一行地输出,以为在拍黑客电影。

革命尚未成功,先记录下来。

三、附录 proxysql配置文件模板

proxysql最大的问题,根本不知道它的配置文件应该怎么写,怎么设置参数,官网上也找不到一个例子。好不容易从github上找到一个模板:

#file proxysql.cfg

# This config file is parsed using libconfig , and its grammar is described in:
# http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar
# Grammar is also copied at the end of this file



datadir="/var/run/proxysql"

admin_variables=
{
	admin_credentials="admin:admin"
	mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
#	refresh_interval=2000
#	debug=true
}

mysql_variables=
{
	threads=4
	max_connections=2048
	default_query_delay=0
	default_query_timeout=36000000
	have_compress=true
	poll_timeout=2000
	interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
	default_schema="information_schema"
	stacksize=1048576
	server_version="5.1.30"
	connect_timeout_server=10000
	monitor_history=60000
	monitor_connect_interval=200000
	monitor_ping_interval=200000
	ping_interval_server=10000
	ping_timeout_server=200
	commands_stats=true
	sessions_sort=true
}


# defines all the MySQL servers
mysql_servers =
(
#	{
#		address = "127.0.0.1" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
#		port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
#		hostgroup = 0	        # no default, required
#		status = "ONLINE"     # default: ONLINE
#		weight = 1            # default: 1
#		compression = 0       # default: 0
#   max_replication_lag = 10  # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
#	},
#	{
#		address = "/var/lib/mysql/mysql.sock"
#		port = 0
#		hostgroup = 0
#	},
#	{
#		address="127.0.0.1"
#		port=21891
#		hostgroup=0
#		max_connections=200
#	},
#	{ address="127.0.0.2" , port=3306 , hostgroup=0, max_connections=5 },
#	{ address="127.0.0.1" , port=21892 , hostgroup=1 },
#	{ address="127.0.0.1" , port=21893 , hostgroup=1 }
#	{ address="127.0.0.2" , port=3306 , hostgroup=1 },
#	{ address="127.0.0.3" , port=3306 , hostgroup=1 },
#	{ address="127.0.0.4" , port=3306 , hostgroup=1 },
#	{ address="/var/lib/mysql/mysql.sock" , port=0 , hostgroup=1 }
)


# defines all the MySQL users
mysql_users:
(
#	{
#		username = "username" # no default , required
#		password = "password" # default: ''
#		default_hostgroup = 0 # default: 0
#		active = 1            # default: 1
#	},
#	{
#		username = "root"
#		password = ""
#		default_hostgroup = 0
#		max_connections=1000
#		default_schema="test"
#		active = 1
#	},
#	{ username = "user1" , password = "password" , default_hostgroup = 0 , active = 0 }
)



#defines MySQL Query Rules
mysql_query_rules:
(
#	{
#		rule_id=1
#		active=1
#		match_pattern="^SELECT .* FOR UPDATE$"
#		destination_hostgroup=0
#		apply=1
#	},
#	{
#		rule_id=2
#		active=1
#		match_pattern="^SELECT"
#		destination_hostgroup=1
#		apply=1
#	}
)


# http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar
#
# Below is the BNF grammar for configuration files. Comments and include directives are not part of the grammar, so they are not included here. 
#
# configuration = setting-list | empty
#
# setting-list = setting | setting-list setting
#     
# setting = name (":" | "=") value (";" | "," | empty)
#     
# value = scalar-value | array | list | group
#     
# value-list = value | value-list "," value
#     
# scalar-value = boolean | integer | integer64 | hex | hex64 | float
#                | string
#     
# scalar-value-list = scalar-value | scalar-value-list "," scalar-value
#     
# array = "[" (scalar-value-list | empty) "]"
#     
# list = "(" (value-list | empty) ")"
#     
# group = "{" (setting-list | empty) "}"
#     
# empty =


http://www.kler.cn/a/549286.html

相关文章:

  • FOT(Forest-of-Thought):增强大型语言模型推理能力的新框架
  • Docker安装Kafka(不依赖ZooKeeper)
  • 【Linux】Ubuntu Linux 系统 ——PHP开发环境
  • Netty的基本架构详解
  • 【第12章:深度学习与伦理、隐私—12.1 AI伦理原则与偏见检测的方法与实践】
  • 第437场周赛:找出长度为 K 的特殊子字符串、吃披萨、选择 K 个互不重叠的特殊子字符串、最长 V 形对角线段的长度
  • 应用分层、三层架构和MVC架构
  • 微信小程序的请求函数封装(ts版本,uniapp开发)
  • Deep seek学习日记1
  • 8. Docker 常规安装简介(安装 Tomcat ,安装 MySQL,安装Redis 同时指定安装的版本)
  • WebMvcConfigurer 介绍
  • 有关计算机的英语单词、短语、句子
  • Python 文本探秘:正则表达式的易错迷宫穿越 -- 7. 正则表达式
  • Redis初阶笔记
  • Qt的QListWidget样式设置
  • Unity中如何判断URL是否为RTSP或RTMP流
  • C语言----共用体
  • Linux基础21-C语言篇之流程控制Ⅱ【入门级】
  • 基于SSM+uniapp的鲜花销售小程序+LW示例参考
  • Qt笔记31-69