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

MySQL异步连接池的学习(五)

一、异步连接池

1.1、为什么需要异步连接池

在高并发场景下,同步连接池的性能瓶颈主要体现在两个方面:

  • 阻塞等待:在获取空闲连接时,如果当前没有可用连接,线程会阻塞等待。在高负载情况下,这会导致大量线程处于等待状态,从而降低整体性能。

  • 频繁的数据库操作:在高并发的应用中,每个请求都需要与数据库进行交互,而每次交互都涉及到网络通信的开销。特别是在使用同步方式时,这些开销会被放大,因为每次操作都会导致线程阻塞。

为了解决这些问题,可以考虑实现一个基于事件驱动或非阻塞IO模型的异步连接池。这样的设计可以减少线程数量,提高资源利用率,同时通过非阻塞的方式处理I/O操作,从而提高系统的吞吐量和响应速度。

1.2、异步连接池的设计

  1. 完全异步连接池:官方给的相关驱动中,没有提供异步驱动,如果需要实现异步连接池,就需要自己实现MySQL协议的解析和封装。难度较大,需要深入了解MySQL协议和网络编程,还要考虑系统平台支持哪些异步操作,C/C++在不同的系统平台,所支持的异步操作也不太一样。

    大致流程:

    在这里插入图片描述

  2. 半异步连接池: 基于线程池的思想,可以将官方给的同步驱动放入专门的线程池中,通过任务队列模拟异步行为。

    大致流程:

    在这里插入图片描述

1.3、半异步连接池实现

基于上面的思路,可以这样再进一步优化下,提高性能,让每个线程都有自己专门的任务队列,而不是公共的任务队列,这样能减少锁的开销,但会增加内存的开销,使用时需权衡下利弊。

运行环境:Linux系统,C++17,具备boost库,以及MySQL官方给出的驱动

本以为就在线程池的基础上添加MySQL的驱动,就完事,没想到并发场景下,各种异常,代码是越改越多,索性重新设计

在这里插入图片描述

多个工作线程异步执行一条SQL语句,就这样了。

设计两个类,一个是连接池类,一个是工作线程类;连接池包含多个工作线程,每个工作线程持有一个数据库连接,避免多个线程共享同一个数据库连接,保证线程安全,也保证每个工作线程独立工作互不干扰。

class ConnectionPool {
public:using Callback = std::function<void(std::shared_ptr<sql::ResultSet>)>;struct Task {std::string query;Callback callback;};ConnectionPool(const std::string& host, const std::string& user, const std::string& password, const std::string& database,size_t pool_size = 2);~ConnectionPool();void execute(const std::string& query, Callback callback);void start_health_check();private:class Worker;   // 前向声明void health_check();    void shutdown();...
};// 工作线程类,负责自己的线程管理(处理任务),以及对SQL语句的执行
class ConnectionPool::Worker {
public:void add_task(Task task);bool check_connection();private:void run();void execute_task(const Task& task);void connect();void reconnect();void stop();ConnectionPool& m_pool;std::queue<Task> m_queue;...
};

监控连接池的状态,目前未添加定时任务,让其定时检查连接池的健康状态

void ConnectionPool::start_health_check() {if (m_health_check_running) return;m_health_check_running = true;m_health_thread = std::thread(&ConnectionPool::health_check, this);std::cout << "Health check started\n";
}void ConnectionPool::health_check() {while (m_health_check_running) {std::this_thread::sleep_for(15s);if (m_shutdown) break;size_t healthy_count = 0;for (auto& worker : m_workers) {if (worker->check_connection()) {healthy_count++;}}std::cout << "Health check: " << healthy_count << "/" << m_workers.size() << " workers healthy\n";}
}

以这张表来进行测试:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、总结

2.1、同步连接池的适用场景

  1. 业务逻辑简单
  2. 并发量小(<1000)
  3. 对性能要求不高

2.2、异步连接池的适用场景

  1. 业务逻辑复杂
  2. 高并发场景(>1000)
  3. 对性能要求高

2.3、在一些大型项目中,更多的是采用混合使用

比如一些游戏服务器中,对玩家的实时操作采取异步连接池,后台管理操作采用同步连接池方案,这样既能保证高并发场景下的性能,也能满足后台管理操作的实时性。

Code

http://www.dtcms.com/a/334123.html

相关文章:

  • PHP反序列化的CTF题目环境和做题复现第2集_POP链构造
  • 生产环境Redis缓存穿透与雪崩防护性能优化实战指南
  • 马拉松|基于SSM的马拉松报名系统微信小程序的系统设计与实现(源码+数据库+文档)
  • 【数据分享】大清河(大庆河)流域上游土地利用
  • Java设计模式详细解读
  • 双向SSL认证之Apache实战配置
  • 【分数求和1】
  • LintCode第116题-跳跃游戏
  • 【leetcode】5 最长回文子串 动态规划法
  • Horse3D游戏引擎研发笔记(六):在QtOpenGL环境下,仿Unity的材质管理Shader绘制四边形
  • AI云电脑盒子技术分析——从“盒子”到“算力云边缘节点”的跃迁
  • 【运维心得】三步更换HP笔记本电脑外壳
  • 电路方案分析(二十一)笔记本电脑散热风扇参考设计
  • OBOO鸥柏丨75寸/86平板企业办公会议触控一体机核心国产化品牌招投标参数
  • OpenCV Python——图像拼接(一)(图像拼接原理、基础知识、单应性矩阵 + 图像变换 + 拼接)
  • 国外护理学专业期刊Top10分析评介
  • 知识点汇总LinuxC高级 -1
  • 【嵌入式FreeRTOS#7】中断管理实验
  • 《C++进阶之继承多态》【多态:概念 + 实现 + 拓展 + 原理】
  • MoE及其优化技术->COMET(字节)
  • Spring MVC 九大组件源码深度剖析(三):ThemeResolver - 动态换肤的奥秘
  • 国产碳化硅模块及顶部散热的11种封装产品介绍应用
  • 标准瓦片层级0~20,在EPSG:4326坐标系下,每个像素点代表的度数
  • Spring AI Starter和文档解读
  • AI应用安全 - Prompt注入攻击
  • HTTP 代理服务器的 C++ 实现与分析:客户端通过代理访问 HTTP 站点的主页劫持流程(软件实现+流程演示+原理讲解)
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑7B大语言模型_20250816
  • 护理学新境界
  • Tello无人机与LLM模型控制 ROS
  • 力扣hot100 | 矩阵 | 73. 矩阵置零、54. 螺旋矩阵、48. 旋转图像、240. 搜索二维矩阵 II