数据库连接池大小的调整原则

news2025/1/20 0:53:04

配置连接池是开发人员经常犯的错误。配置池时需要理解几个原则(对于某些人来说可能违反直觉)。

想象一下,您有一个网站,虽然可能不是 Facebook 规模的,但仍然经常有 10,000 个用户同时发出数据库请求,每秒处理约 20,000 笔交易。您的连接池应该有多大?

你可能认为连接池越大越好!

问题不在于有多大,而在于有多小!

在没有任何其他更改的情况下,仅减少连接池大小即可将应用程序的响应时间从约 100 毫秒减少到约 2 毫秒,提高了 50 倍以上。
观看来自 Oracle Real-World Performance 小组的这段简短视频(点击标题)

同理,为什么仅使用 4 个线程的nginx Web 服务器就可以远远优于具有100 个进程的Apache Web 服务器?

即使是只有一个 CPU 内核的电脑,也能 "同时 "支持数十或数百个线程。但我们都[应该]知道,这不过是操作系统利用时间切片魔法玩的把戏。实际上,单个内核一次只能执行一个线程,然后操作系统会切换上下文,让该内核执行另一个线程的代码,以此类推。在单个 CPU 资源的情况下,顺序执行 A 和 B 总比通过时间切分 "同时 "执行 A 和 B 快,这是计算的基本定律。一旦线程数超过 CPU 内核数,增加线程的速度只会更慢,而不会更快。

资源有限
虽然不像上面说的那么简单,但也差不多了。还有其他一些因素在起作用。我们可以将数据库的主要瓶颈归纳为三个基本类别:CPU、磁盘和网络。我们可以把内存也加进去,但与磁盘和网络相比,带宽相差几个数量级。

如果我们忽略磁盘和网络,情况就会很简单。在一台有 8 个计算核心的服务器上,将连接数设置为 8 就能获得最佳性能,而超过这个数后,由于上下文切换的开销,速度就会开始变慢。但我们不能忽视磁盘和网络。数据库通常将数据存储在磁盘上,磁盘传统上由旋转的金属板组成,读/写头安装在步进电机驱动的机械臂上。读/写头一次只能位于一个位置(为单次查询读/写数据),必须 "寻道 "到新的位置才能为不同的查询读/写数据。因此会产生寻道时间成本和旋转成本,即磁盘必须等待数据在盘片上 "再次旋转 "才能读/写。缓存当然在这方面有所帮助,但原理仍然适用。

在这段时间内("I/O 等待"),连接/查询/线程只是被 "阻塞",等待磁盘。而在这段时间里,操作系统可以通过为另一个线程执行更多代码来更好地利用 CPU 资源。因此,由于线程在 I/O 时会被阻塞,我们实际上可以通过连接/线程数量大于物理计算核心数量来完成更多工作。

多多少?我们拭目以待。至于多多少,还取决于磁盘子系统,因为较新的固态硬盘驱动器没有 "寻道时间 "成本或旋转因素。不要受骗上当,认为 "固态硬盘速度更快,因此我可以拥有更多线程"。这完全是180度的倒退。速度更快、无寻道、无旋转延迟意味着阻塞更少,

因此更少的线程(更接近核心数)比更多的线程性能更好。
只有当阻塞为执行创造机会时,更多线程才会有更好的表现。

网络与磁盘类似。当发送/接收缓冲区填满并停滞时,通过以太网接口向外写入数据也会造成阻塞。万兆以太网接口的阻塞小于千兆以太网接口,而千兆以太网接口的阻塞小于百兆以太网接口。但就资源阻塞而言,网络是第三名,有些人在计算时经常忽略它。


在上述 PostgreSQL 基准中,您可以看到 TPS 率在连接数达到 50 个左右时开始趋于平稳。在甲骨文的上述视频中,他们展示了将连接数从 2048 降到 96 的过程。我们认为即使是 96 个连接也可能过高,除非您使用的是 16 核或 32 核的服务器。

设置数据库连接池的公式

下面的公式是 PostgreSQL 项目作为起点提供的,但我们相信它在很大程度上适用于所有数据库。您应该测试您的应用程序,即模拟预期负载,并围绕这个起点尝试不同的池设置:

连接数 = ((core_count * 2) + effective_spindle_count)

猜猜这意味着什么?

你有台只有一个硬盘的 4 核 i7 服务器,运行的连接池应该是9 = ((4 * 2) + 1).
整数为 10。

看起来少吗?试试看吧,我们打赌,在这样的设置下,您可以轻松处理 3000 名前端用户以 6000 TPS 的速度运行简单查询。

如果运行负载测试,您可能会发现 TPS 率开始下降,而前端响应时间开始攀升,因为您(在给定的硬件上)将连接池推到了 10 以上。

为了避免死锁而计算池大小是一个相当简单的资源分配公式:
池大小 = T n x (C m - 1) + 1
其中T n是最大线程数,C m是单个线程持有的最大同时连接数。
例如,假设有三个线程 ( T n =3 ),每个线程需要四个连接来执行某些任务 ( C m =4 )。确保永远不会出现死锁所需的池大小为:
池大小 = 3 x (4 - 1) + 1 = 10
另一个例子,您最多有八个线程 ( T n =8 ),每个线程需要三个连接来执行某些任务 ( C m =3 )。确保永远不会出现死锁所需的池大小为:
池大小 = 8 x (3 - 1) + 1 = 17
这不一定是最佳池大小,而是避免死锁所需的最小值。

在某些环境中,使用 JTA(Java 事务管理器)可以通过将 getConnection() 中的同一连接返回给已在当前事务中持有连接的线程,从而大大减少所需的连接数。

总结
池大小最终取决于部署。

例如,混合有长时间运行的事务和非常短的事务的系统通常是最难使用任何连接池进行调整的。在这些情况下,创建两个池实例可以很好地发挥作用(例如,一个用于长时间运行的作业,另一个用于“实时”查询)。

在主要具有长时间运行事务的系统中,所需连接数量通常存在“外部”约束,例如作业执行队列仅允许同时运行一定数量的作业。在这些情况下,作业队列大小应“大小合适”以匹配池(而不是相反)。

https://www.jdon.com/69541.html ​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1165715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.RDD编程指南

概述 spark 提供的重要的抽象是一个 弹性分布式数据集(RDD) ,能被并行操作的,在集群上分区的集合元素。RDDs 可以通过 hadoop 文件(或共它的 hadoop 支持的文件系统),或者编程中的 scala 集合,转换它创建 RDD。用户还可以要求 sp…

【Linux】:基础IO

基础IO 一.C语音文件操作1.fopen2.fwrite3.fopen以a方式打开 二.Linux下一切皆文件三.系统调用接口四.文件描述符-fd 共识原理: 1.文件属性内容。 2.文件分为打开文件和未打开文件。 3.打开的文件:进程打开。 4.未打开的文件:在磁盘里存放着。…

在Node.js中,什么是中间件(middleware)?它们的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

企业中台如何进行测试(下篇)

《企业中台如何进行测试》包含了主数据治理测试、统一认证测试、业务集成测试、门户建设测试、数据分析测试等内容。由于篇幅较长,将分为上、下两个篇章与大家分享,在上篇主要从主数据治理和统一认证两个方面对企业中台的测试内容进行介绍,下…

Visual Studio Code 常用快捷键大全

Visual Studio Code 常用快捷键大全 快捷键是编码过程中经常使用,且能够极大提升效率的部分,这里给大家介绍一些VS Code中非常有用的快捷键。 打开和关闭侧边栏 Mac — Command B Windows — Ctrl B Ubuntu — Ctrl B 选择单词 Mac — Command D …

洗衣洗鞋柜洗衣洗鞋小程序

支持:一键投递、上门取衣、自主送店、多种支付方式 TEL: 17638103951(同V) -----------------用户下单-------------- -------------------------多种支付和投递方式------------------------- -----------------商家取鞋--------------

基于冠状病毒群体免疫算法的无人机航迹规划-附代码

基于冠状病毒群体免疫算法的无人机航迹规划 文章目录 基于冠状病毒群体免疫算法的无人机航迹规划1.冠状病毒群体免疫搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用冠状病毒群体…

从关键新闻和最新技术看AI行业发展(2023.10.9-10.22第八期) |【WeThinkIn老实人报】

Rocky Ding 公众号:WeThinkIn 写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术,同时Rocky会对这些关键信息进行解读,力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议,一起交流学习&…

测试总结模板

​​​​​​​ ​​​​​​​ ​​​​​​​ xx电力工作计划管理系统 系统测试总结 评审核准单 时间 作者 工作内容 版本 确认人 确认时间 2007/11/6 姜全尧 创建延边电力工作计划管理系统测试总结 1.0 …

二叉树OJ题(用前序和中序遍历构建二叉树,用中序和后续遍历构建二叉树)

文章目录 二叉树OJ题一、用前序和中序遍历构建二叉树1.思路2.代码 二、用中序和后续遍历构建二叉树1.思路2.代码 二叉树OJ题 一、用前序和中序遍历构建二叉树 1.思路 1.根据前序遍历找到根结点root 2.在中序遍历中(inBegin0和inEndelem.length-1范围之间&#xff09…

老外总结的14条Go接口最佳实践

最近几个月,没事喜欢看看老外写的技术文章,发现他们的一些思考维度真的有些不太一样。当然,他们写的文章大多数没有国内的那么卷。 今天这篇文章是关于Go语言中接口设计的一些最佳实践,与Java等语言不尽相似,但又带着…

Linux常用命令——chcon命令

在线Linux命令查询工具 chcon 修改对象(文件)的安全上下文 补充说明 chcon命令是修改对象(文件)的安全上下文,比如:用户、角色、类型、安全级别。也就是将每个文件的安全环境变更至指定环境。使用--ref…

Ubuntu连不上WiFi 或者虽然能连上校园网,但是浏览器打不开登录页面

写在前面 自己的电脑环境: Ubuntu20.04 一、问题描述 自己的 Ubuntu 遇到连接不上 除校园网之外的其他WiFi, 或者 虽然能连上校园网,但是浏览器打不开登录页面的问题。 二、解决方法 出现这种问题的原因可能是 之前开过VPN, 导致系统的网络设置出现…

上海亚商投顾:创业板指高开低走 传媒、游戏板块逆势大涨

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 三大指数昨日震荡调整,创业板指尾盘跌超1%。传媒、游戏板块逆势大涨,百纳千成、天龙集…

浮动模块布局

基本思路 若宽度和浏览器一样宽,则不需要设置width 一般父盒子使用标准流,然后标准流内使用浮动 一般父盒子需要居中显示,使用 margin: 0 auto; 注意浮动盒子之间的margin值 与 父盒子width、height值之间的相等关系,一定要计算…

APUS成为深圳市人工智能行业协会理事单位,CEO李涛受聘专家

近日,APUS正式成为深圳市人工智能行业协会理事单位,APUS董事长兼CEO李涛同时受聘为协会专家委员会专家。 深圳市人工智能行业协会成立于2017年,由电子通信、大数据、计算机视觉、自然语言处理等AI相关领域企事业单位组成,致力于加…

Goland 对容器中的 Go 程序断点远程调试

1,针对 golang 程序打断点有哪几种情况 临时进程:针对临时运行一次的 Golang 脚本,比如定时统计脚本,定时推送脚本。常驻进程:针对一直在后台运行的 Golang 程序,比如 HTTP 或者 GRPC 服务。 我们现在假设…

【多线程面试题二十一】、 分段锁是怎么实现的?

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官: 分段锁是怎么实现的&am…

最新ChatGPT商业运营系统源码+支持GPT4/支持ai绘画+支持Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

[common c/c++] ring buffer/circular buffer 环形队列/环形缓冲区

前言: ring buffer / circular buffer 又名环形队列 / 环形缓冲区,其通过开辟固定尺寸的内存来实现反复复用同一块内存的目的。由于预先开辟了固定尺寸的内容,所以当数据满的时候,可以有两种处理方式,具体使用哪一种按…