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

MySQL同步连接池与TrinityCore的对比学习(六)

一、 同步连接池实现

TrinityCore中,数据库连接池的实现采用了两种类型组合方式:异步和同步。这两种类型分别用于处理不同类型的SQL操作,以满足不同的性能需求;先聚焦于同步连接池的实现机制。

1.1、总体设计思路

采用"一请求对应一连接,一连接对应一把锁"的设计理念,业务处理完毕后立即释放连接资源。

在这里插入图片描述

1.2、存储结构设计

// 在 DatabaseWorkerPool.h 中
enum InternalIndex
{IDX_ASYNC,  // 异步连接IDX_SYNCH,  // 同步连接 IDX_SIZE
};
......
std::array<std::vector<std::unique_ptr<T>>, IDX_SIZE> _connections;
......
  • _connections 为大小为 2 的数组,分别对应异步和同步连接类型
  • 每个数组元素使用 std::vector 存储数据库连接
  • 采用 std::unique_ptr 智能指针管理连接生命周期

1.3、获取连接

template <class T>
T* DatabaseWorkerPool<T>::GetFreeConnection()
{uint8 i = 0;auto const num_cons = _connections[IDX_SYNCH].size();T* connection = nullptr;// 轮询查找可用连接for (;;){connection = _connections[IDX_SYNCH][++i % num_cons].get();// 尝试锁定连接,如果成功就使用if (connection->LockIfReady())break;}return connection;
}bool MySQLConnection::LockIfReady()
{return m_Mutex.try_lock();  // 非阻塞尝试获取锁
}
  • 轮询遍历所有连接
  • 通过LockIfReady尝试非阻塞锁定连接,如果成功则返回该连接;否则立即尝试下一个连接

1.4、资源管理模式

严格遵循 锁定-使用-释放 模式:

QueryResult DatabaseWorkerPool<T>::Query(char const* sql, T* connection)
{if (!connection)connection = GetFreeConnection();  // 获取连接// 执行数据库操作ResultSet* result = connection->Query(sql);connection->Unlock();  // 释放连接// ... 处理结果 ...
}

二、与之前实现的同步连接池对比

在之前也实现过一版同步连接池,和TrinityCore的实现相比较,有以下不同点:

之前版本的同步连接池

2.1、智能指针选择策略

实现方案个人实现TrinityCore
智能指针std::queue<std::shared_ptr<sql::Connection>> m_freeConnPoolstd::array<std::vector<std::unique_ptr<T>>, IDX_SIZE> _connections
  • 为什么选择unique_ptr而非shared_ptr
    我个人猜想,unique_ptr相较于shared_ptr有以下优势:
  1. 性能优势

    • unique_ptr 无原子操作开销,性能接近原始指针
    • shared_ptr 的引用计数机制在高度并发场景下存在性能瓶颈
  2. 所有权明确

    • unique_ptr 强制单一所有权,避免资源管理 ambiguity
    • 编译时检查确保资源安全
  3. 内存安全

    • 避免循环引用导致的内存泄漏
    • 简化资源生命周期管理

2.2、连接获取策略

  • TrinityCore采用的是轮询策略,即依次尝试每个连接。
// 轮询 + 非阻塞锁定
for (;;) {connection = _connections[IDX_SYNCH][++i % num_cons].get();if (connection->LockIfReady())  // try_lockbreak;
}
  • 个人采用的是条件变量等待
// 条件变量等待
if(m_freeConnPool.empty()){m_condition.wait(lock, [this](){ return !m_freeConnPool.empty(); });
}
auto conn = m_freeConnPool.front();
m_freeConnPool.pop();

性能分析:

- TrinityCore:无上下文切换,CPU占用稍高但响应更快
- 个人实现:线程休眠节省CPU,但有唤醒开销

2.3、连接归还策略

  • TrinityCore采用的是手动解锁
connection->Unlock();
  • 个人采用的是shared_ptr的自定义删除器归还
auto conn = std::shared_ptr<sql::Connection>(m_driver->connect(...),[this](sql::Connection* conn){returnConnection(std::shared_ptr<sql::Connection>(conn));}
);

TrinityCore的实现,需要程序员非常小心地管理连接的锁定和解锁,稍有不慎就可能导致死锁或资源泄露。

而个人实现通过RAII自动管理,避免资源泄漏

2.4、连接健康管理

  • TrinityCore目前所看的实现中没有看到对连接健康状态的检测,例如是否断开、是否需要重连等。
  • 个人采用的是自定义删除器中检测
// 获取时检查连接有效性
if(!conn->isValid() || conn->isClosed()){conn->reconnect();  // 尝试重连// 或者创建新连接
}

后续可以考虑在TrinityCore的实现中加入对连接健康状态的检测,例如在获取连接时检查是否断开并尝试重连。这样可以提高连接的稳定性和可靠性。

2.5、锁粒度设计

  • TrinityCore:

    • 细粒度锁:每个连接独立互斥锁
    • 高并发场景下竞争较少
  • 个人实现:

    • 粗粒度锁:整个连接池共用一把锁
    • 实现简单但并发性能受限


      在性能敏感的场景下,细粒度锁通常比粗粒度锁更优。因为细粒度锁可以减少锁竞争和等待时间,从而提高并发性能。

Tips: 看了下TrinityCore的部分实现,原本以为只单独将DatabaseWorkerPool的实现拉下来就可以使用,但没那么简单,除非重新封装DataBaseWorkerPool,但这样工作量不小。

三、总结:

  1. 什么时候考虑使用unique_ptr,什么时候考虑使用shared_ptr
  • 使用unique_ptr
    • 性能敏感的场景,如频繁创建和销毁对象的场合。— 无原子操作开销
    • 明确单一所有权的场合,避免悬挂指针和内存泄漏。
    • 避免循环引用,简化内存管理。
  • 使用shared_ptr
    • 确实需要共享所有权的场合,例如多个对象需要共同访问同一资源。
    • 资源生命周期复杂,难以用单一所有者模型管理的场合。
    • 对性能要求不极端的场合,特别是在引用计数操作的开销可以接受的情况下。
  1. 两种同步连接池对比
特性TrinityCore个人自定义实现
设计目标极致性能,游戏服务器场景通用性,易用性
资源管理手动控制,开发者负责自动管理,RAII 原则
错误处理操作失败后恢复健康检查
适用场景高性能应用通用应用
http://www.dtcms.com/a/503397.html

相关文章:

  • UserWarning: No file found at “C:\Faces\image_0032.jpg“AssertionError
  • 网站生成器下载wordpress 添加微博关注
  • 【个人成长笔记】Qt Creator快捷键终极指南:从入门到精通
  • 【开题答辩过程】以《校园可共享物品租赁系统的设计与实现》为例,不会开题答辩的可以进来看看
  • 北京高端网站定制公司猎头公司工作怎么样
  • StarRocks-基本介绍(一)基本概念、特点、适用场景
  • Java零基础入门:从封装到构造方法 --- OOP(上)
  • JAVA算法练习题day43
  • 如何学习Lodash源码?
  • 建个自己的网站难吗宁波 seo整体优化
  • uni-app详解
  • AI学习:SPIN -win-安装SPIN-工具过程 SPIN win 电脑安装=accoda 环境-第五篇:代码修复]
  • 【Linux】Linux:sudo 白名单配置与 GCC/G++ 编译器使用指南
  • PyTorch 张量初始化方法详解
  • 计算机理论学习Day16
  • 动物摄影网站佛山网站制作维护
  • springboot整合redis-RedisTemplate单机模式
  • 【Redisson】分布式锁原理和使用姿势
  • linux学习笔记(43)网络编程——HTTPS (补充)
  • HTTP Client/Server 理论
  • 怎么申请域名建立网站宁波网站建设开发
  • C++:内存管理 |内存分布|回顾|new/delete底层|实现原理|拓展|定位new|池化技术|总结区别对比
  • 上街网站建设做语文高考题网站
  • 前端基础二、CSS(一)、CSS基础知识
  • 【MySQL】第三章 运算符
  • 智能机器人梯控系统(含二维码/刷卡/人脸识别)安装布线指南,结合工程规范与安全要点进行结构化优化,内容清晰、可操作性强
  • 突破 @Valid 局限!Spring Boot 编程式验证深度解析与复杂场景实战
  • 盐城市规划建设局网站做北美市场用哪个网站
  • 【攻防实战】系列二-使用metasploit打穿某集团(下)
  • 单词搜索 II · Word Search II