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.Driverurl: jdbc:mysql://192.168.10.249:6033/testdb?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=trueusername: workpassword: 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/bashmysql -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 = 4max_connections = 2048default_query_delay = 0default_query_timeout = 36000000have_compress = truepoll_timeout = 2000interfaces = "0.0.0.0:6033"default_schema = "information_schema"stacksize = 1048576server_version = "8.0.23"monitor_history=60000monitor_connect_interval=200000monitor_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 filedatadir="/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=4max_connections=2048default_query_delay=0default_query_timeout=36000000have_compress=truepoll_timeout=2000interfaces="0.0.0.0:6033;/tmp/proxysql.sock"default_schema="information_schema"stacksize=1048576server_version="5.1.30"connect_timeout_server=10000monitor_history=60000monitor_connect_interval=200000monitor_ping_interval=200000ping_interval_server=10000ping_timeout_server=200commands_stats=truesessions_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 =相关文章:
mysql读写分离与proxysql的结合
上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。 读写分离,拿spring boot项目来说,可以有2种方式: 1)设置2个数据源,读和写分开使用 2)使用中间件…...
【C++学习篇】C++11第二期学习
目录 1. 可变参数模板 1.1 基本语法及原理 1.2 包扩展 1.3empalce系列接⼝ 2. lamba 2.1 lambda的语法表达式 2.2 捕捉列表 2.3 lamba的原理 1. 可变参数模板 1.1 基本语法及原理 1. C11⽀持可变参数模板,也就是说⽀持可变数量参数的函数模板和类模板&…...
TextWebSocketHandler 和 @ServerEndpoint 各自实现 WebSocket 服务器
TextWebSocketHandler 和 ServerEndpoint 都可以用于实现 WebSocket 服务器,但它们属于不同的技术栈,使用方式和功能有一些区别。以下是它们的对比: 1. 技术栈对比 特性TextWebSocketHandler (Spring)ServerEndpoint (Java EE/JSR-356)所属框…...
【C++高并发服务器WebServer】-18:事件处理模式与线程池
本文目录 一、事件处理模式1.1 Reactor模式1.2 Proactor模式1.3 同步IO模拟Proactor模式 二、线程池 一、事件处理模式 服务器程序通常需要处理三类事件:I/O事件、信号、定时事件。 对应的有两种高效的事件处理模式:Reactor和Proactor,同步…...
23种设计模式的定义和应用场景-02-结构型模式-C#代码
23种设计模式的定义和应用场景: 1. 创建型模式(共5种): 单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式…...
数据脱敏方案总结
什么是数据脱敏 数据脱敏的定义 数据脱敏百度百科中是这样定义的: 数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集…...
自然语言处理NLP入门 -- 第二节预处理文本数据
在自然语言处理(NLP)中,数据的质量直接影响模型的表现。文本预处理的目标是清理和标准化文本数据,使其适合机器学习或深度学习模型处理。本章介绍几种常见的文本预处理方法,并通过 Python 代码进行示例。 2.1 文本清理…...
02.10 TCP之文件传输
1.思维导图 2.作业 服务器代码: #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> …...
基于STM32的ADS1230驱动例程
自己在练手项目中用到了ADS1230,根据芯片手册自写的驱动代码,已测可用,希望对将要用到ADS1230芯片的人有所帮助。 芯片:STM32系列任意芯片、ADS1230 环境:使用STM32CubeMX配置引脚、KEIL 部分电路: 代码…...
Bro想要玩github api
Bro想要在vscode 和 rest client插件的帮助下,修改我的github个人信息 ### 先安装REST client插件 ### 文件名test-github.http ### bro需要自己在github develop setting 获得token ### ref link: https://docs.github.com/en/authentication/keeping-your-accoun…...
idea插件开发,如何获取idea设置的系统语言
手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/145578160 版本要求 大于 2024.3 错误用法 网上有的说使用:UIUtil com.intellij.util.ui.UIUtil 代码示例…...
怎麼使用靜態住宅IP進行多社媒帳號管理
隨著社交媒體平臺的多樣化,很多人發現一個社媒帳號已經無法滿足需求。以下是幾個常見場景: 企業需求:企業可能需要在不同平臺上運營多個品牌帳號,為每個市場地區單獨設立帳號。個人需求:一些自由職業者或內容創作者可…...
InfiniBand与IP over InfiniBand(IPOIB):实现高性能网络通信的底层机制
在现代高性能计算(HPC)和数据中心环境中,网络通信的效率和性能至关重要。InfiniBand(IB)作为一种高性能的串行计算机总线架构,以其低延迟、高带宽和高可靠性而广泛应用于集群计算和数据中心。IP over InfiniBand(IPOIB)则是在InfiniBand网络上实现IP协议的一种方式,它…...
掌握 PHP 单例模式:构建更高效的应用
在 PHP 应用开发中,资源的高效管理至关重要。单例模式是一种能够帮助我们实现这一目标的设计模式。本文将深入探讨单例模式的概念、工作原理以及在 PHP 项目中何时应该(或不应该)使用它。 什么是单例模式? 单例模式是一种设计模…...
实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)
如上图,我的百度网盘已登录设备列表,有一个手机,2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的?下面分别给出android APP中采集手机信…...
Python入门全攻略(四)
函数 初识函数 函数:封装具有某种功能的代码块。 函数定义 使用def关键字来定义函数 # 定义函数 def 函数名(): 代码块 # 调用函数 函数名() 函数参数 def 函数名(形参) 代码块 # 调用 函数名(实参) 位置参数 按参数顺序传参 def func(a, b): print(a b)…...
Ubuntu 22.04 - OpenLDAP安装使用(服务器+LAM+客户端)
csdn你…怎么不自动保存了很崩溃啊啊啊啊,我记得发现没保存之后我又改了一遍然后保存了,怎么现在又没了啊啊啊啊,过了这么久我都不记得了啊啊啊啊啊 参考 在 Ubuntu 22.04|20.04|18.04 上安装 OpenLDAP 和 phpLDAPadmin 在 Ubuntu 22.04|20…...
Linux ARM64 将内核虚拟地址转化为物理地址
文章目录 前言一、通用方案1.1 kern_addr_valid1.2 __pa 二、ARM64架构2.1 AT S1E1R2.2 is_kernel_addr_vaild2.3 va2pa_helper 三、demo演示参考资料 前言 本文介绍一种通用的将内核虚拟地址转化为物理地址的方案以及一种适用于ARM64 将内核虚拟地址转化为物理地址的方案&…...
使用 Visual Studio Code (VS Code) 开发 Python 图形界面程序
安装Python、VS Code Documentation for Visual Studio Code Python Releases for Windows | Python.org 更新pip >python.exe -m pip install --upgrade pip Requirement already satisfied: pip in c:\users\xxx\appdata\local\programs\python\python312\lib\site-pa…...
图像处理篇---基本OpenMV图像处理
文章目录 前言1. 灰度化(Grayscale)2. 二值化(Thresholding)3. 掩膜(Mask)4. 腐蚀(Erosion)5. 膨胀(Dilation)6. 缩放(Scaling)7. 旋转…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
