沈阳鹊起网站建设公司,宝塔一键wordpress,天津武清做网站tjniu,wordpress修改之前发布文章的id配置连接池是开发人员经常犯的错误。配置池时需要理解几个原则#xff08;对于某些人来说可能违反直觉#xff09;。
想象一下#xff0c;您有一个网站#xff0c;虽然可能不是 Facebook 规模的#xff0c;但仍然经常有 10,000 个用户同时发出数据库请求#xff0c;每秒…配置连接池是开发人员经常犯的错误。配置池时需要理解几个原则对于某些人来说可能违反直觉。
想象一下您有一个网站虽然可能不是 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 这不一定是最佳池大小而是避免死锁所需的最小值。
在某些环境中使用 JTAJava 事务管理器可以通过将 getConnection() 中的同一连接返回给已在当前事务中持有连接的线程从而大大减少所需的连接数。
总结 池大小最终取决于部署。
例如混合有长时间运行的事务和非常短的事务的系统通常是最难使用任何连接池进行调整的。在这些情况下创建两个池实例可以很好地发挥作用例如一个用于长时间运行的作业另一个用于“实时”查询。
在主要具有长时间运行事务的系统中所需连接数量通常存在“外部”约束例如作业执行队列仅允许同时运行一定数量的作业。在这些情况下作业队列大小应“大小合适”以匹配池而不是相反。
https://www.jdon.com/69541.html