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

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

想象一下,您有一个网站,虽然可能不是 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 ​​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GD32 单片机 硬件I2C死锁解决方法

死锁的复现方式 在I2C恢复函数下个断点(检测到I2C多次超时之后,应该能跳转到I2C恢复函数)使用镊子,将SCL与SDA短接,很快就能看到程序停到恢复函数的断点上,此时再执行恢复函数,看能否正常走出&…

CSS3网页布局基础

CSS布局始于第2个版本,CSS 2.1把布局分为3种模型:常规流、浮动、绝对定位。CSS 3推出更多布局方案:多列布局、弹性盒、模板层、网格定位、网格层、浮动盒等。本章重点介绍CSS 2.1标准的3种布局模型,它们获得所有浏览器的全面、一致…

「直播回放」使用 PLC + OPC + TDengine,快速搭建烟草生产监测系统

在烟草工业场景里,多数设备的自动控制都是通过 PLC 可编程逻辑控制器来实现的,PLC 再将采集的数据汇聚至 OPC 服务器。传统的 PI System、实时数据库、组态软件等与 OPC 相连,提供分析、可视化、报警等功能,这类系统存在一些问题&…

历年网规上午真题(2017年)

解析:D/C 计算机主要性能指标:时钟频率(主频)、运算速度、运算精度、内存大小、数据处理速率(PDR)等 数据库主要指标:最大并发、负载均衡能力、最大连接数等 解析:A 敏捷开发是一种应对快速变化的需求的一种软件开发方法,是一种以人为核心、迭代、循序渐进的开发方…

项目实战:编辑页面加载库存信息

1、前端编辑页面加载水果库存信息逻辑edit.js let queryString window.location.search.substring(1) if(queryString){var fid queryString.split("")[1]window.onloadfunction(){loadFruit(fid)}loadFruit function(fid){axios({method:get,url:edit,params:{fi…

【使用Python编写游戏辅助工具】第四篇:Windows窗口操作

前言 这里是【使用Python编写游戏辅助工具】的第四篇:Windows窗口操作。本文主要介绍使用Python来实现Windows窗口的各种操作。 Windows窗口操作是游戏辅助功能中不可或缺的一部分。 Windows窗口操作指的是与Windows操作系统中的窗口进行交互和控制的操作&#xff…

【Redis】安装(Linuxwindow)及Redis的常用命令

Redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。 它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复…

【Java初阶练习题】-- 循环+递归练习题

循环练习题02 打印X图形计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值输出一个整数的每一位如:123的每一位是3,2,1模拟登录使用方法求最大值求斐波那契数列的第n项。(迭代实现)求和的重载求最大值方法的重载递归求N阶乘递归求 1 2 3 ...…

C++之初始化列表详细剖析

一、初始化列表定义 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。 class Date { public:Date(int year, int month, int day): _year(year), _month(mont…

华纳云:centos系统中怎么查看cpu信息?

在CentOS系统中,我们可以使用一些命令来查看CPU的详细信息。下面介绍几个常用的命令: 1. lscpu lscpu命令可以显示CPU的架构、型号、核心数、线程数、频率等信息。 # lscpu 执行以上命令后,会输出类似以下内容: 2. cat /proc/…

3D医学三维技术影像PACS系统源码

一、系统概述 3D医学影像PACS系统,它集影像存储服务器、影像诊断工作站及RIS报告系统于一身,主要有图像处理模块、影像数据管理模块、RIS报告模块、光盘存档模块、DICOM通讯模块、胶片打印输出等模块组成, 具有完善的影像数据库管理功能,强大…

Oil Crop Science:DAP-seq技术揭示花生中AhTWRKY24和AhTWRKY106转录因子下游调控基因

2023年6月4日,青岛农业大学草业学院宋辉教授课题组的研究成果,发表在Oil Crop Science期刊上,文章题目为Identification of the target genes of AhTWRKY24 and AhTWRKY106 transcription factors reveals their regulatory network in Arach…

【好书推荐】AI时代架构师修炼之道:ChatGPT让架构师插上翅膀

目录 前言 ChatGPT对架构师工作的帮助 快速理解和分析需求 提供代码建议和解决方案 辅助系统设计和优化 提高团队协作效率 如何使用ChatGPT提高架构师工作效率 了解用户需求和分析问题 编码实践和问题解决 系统设计和优化建议 团队协作和沟通效率提升 知识管理和文…

K8s集群

统一时间:ntpdate(都做) ntpdate -b ntp1.aliyun.com */1 * * * * /usr/sbin/ntpdate -b ntp1.aliyun.com systemctl status docker vi /etc/docker/daemon.json systemctl restart docker m: vim kubernetes.sh cat >> /etc/yum.repos.d/kubernetes.repo…

Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问

Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问 文章目录 Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问前言1.下载安装File Browser2.启动访问File Browser3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3…

C++动态内存检查工具 - AddressSanitizer

参考 https://www.qt.io/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt https://doc.qt.io/qt-6/qmake-variable-reference.html#qmake-lflags AddressSanitizer是gcc编译器套件的一部分(gcc版本 > 4.8),只要在编译器调用中添加-fsanitizeaddre…

AtCoder abc143

D - Triangles 排序后two pointer # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # author : yhdutongwoo.cn # desc : # file : atcoder.py # software : PyCharmimport bisect import copy import sys from sortedcontainers import SortedList from coll…

Android开发知识学习——从Retrofit原理来看HTTP

文章目录 Retrofit 使用方法简介Retrofit 源码结构总结扔物线读源码的思路与方式 Retrofit 使用方法简介 导包 implementation com.squareup.retrofit2:retrofit:最新版本创建一个 interface 作为 Web Service 的请求集合,在里面用注解 (Annotation&…

Spring Boot整合Swagger

🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…

新建Git仓库后!如何将本地项目直接推送上到git仓库中的详细教程!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Git新建仓库二、来到你的本地仓库 前言 我们在git新建仓库后,如何直接在本地的项目文件夹中直接推送到git仓库中呢!那么下面是详细…