我们正在开发我们的 Web 应用程序,并一直在努力减少加载时间。当我们开始开发应用程序时,我们与一家知名的托管服务提供商签约,该提供商在云上提供“专用解决方案”。因此,我们为 Web 应用程序配备了一台专用服务器,为数据库配备了一台专用服务器。两台服务器都设置了相同数量的 RAM、相同的 CPU 和 SSD 驱动器。即使我们在基础设施上投入了时间和金钱,我们也注意到加载时间只有 8-10 秒。
另一家托管公司建议我们缩小规模,将所有东西都放到一台服务器上(而不是拆分)。他们提到,由于网络延迟,将服务器分开会导致更长的加载时间,并表示 PHP 通过套接字与 SQL 通信的速度比通过网络更快。我知道这是真的,但我没想到我们得到的结果。将所有内容移至我们原来的应用程序服务器后,我们的加载时间立即从 8-10 秒缩短到 3-4 秒!
问题是,我们现在正在寻找新的托管服务提供商,并被建议使用带有负载平衡器、数据库服务器、应用程序服务器和规模的集群。令人担忧的是,如果我们再次将应用程序和数据库服务器分开,我们将回到原点。
从我读过的所有内容来看,似乎几乎总是建议将这些服务器拆分而不是组合在一起。如果设置正确,这样做是否会提高性能,还是只是为了长期的可扩展性?
我很感激你的帮助!
答案1
你的问题比较笼统,我简单说几个方面:
本地套接字 I/O 比 TCP 更快,但对于大多数应用程序而言,与周转时间的所有其他部分(负载平衡器、PHP 处理、DB 查询处理……)相比,这应该是微不足道的。
分割系统允许更好的缓存,例如数据库服务器可以在 RAM 中保存更多的索引。
可能是一个可扩展点:拆分系统更易于配置,例如,要部署新的软件版本或更新 PHP,您只需添加新的应用程序服务器,对其进行测试,最后删除旧的应用程序服务器即可。
调查您的问题:检查每个 Web 请求打开了多少个数据库连接。您的测量结果的一个解释是,某个应用程序使用许多没有持久连接的 SQL 查询,因此每次访问 DB 都会打开一个新的 TCP 连接。
答案2
我不知道您要做什么才能获得 8-10 秒的加载时间(假设您将“加载时间”定义为“HTTP 请求到达和页面构建并发送到浏览器之间的时间”)。
您不应该让 Web 服务器和数据库的 CPU 使用率达到 100%,即使您以某种方式管理这一点,将 Web 服务器和数据库放在一台服务器上也无济于事。
此外,将两台服务器移动到同一个硬件上并不能缓解数据库服务器上任何类型的过载。
所以问题几乎与
- 很多非常小的 SQL 语句被单独发送到数据库,因此即使本地网络上的很小的延迟也会累积(假设每页有 10000 个 SQL 语句,网络延迟为 0.1 毫秒。这将导致您的加载时间为 10 秒)。
- 数据库中存储的大量数据需要通过 SQL 连接到达 Web 服务器,这通常比为文件传输设计的协议要慢,尤其是通过网络传输
- 主机之间的网络连接在某种程度上受到人为限制
也许这是我现在无法想象的其他事情,因为当你将典型的 Web 应用程序分布在更多 CPU 上时,只要这些 CPU 之间有快速的网络连接,它变慢的情况就很罕见。
只要您没有在单独的主机上找出导致问题的原因,您可能会再次遇到同样的问题,也可能不会。
去年我遇到过第一种问题 - 我的一位客户与第三方签订了合同,让他们为其开发一些软件。在演示笔记本电脑上完成典型操作大约需要 4 小时。当我的客户将软件移至预期的生产环境(大型应用服务器、大型数据库集群)时,同样的事情花费了 16 个多小时。通过筛选日志并进行网络跟踪,我们发现该应用程序在开发系统上每秒执行大约 15,000 次选择,而应用服务器和数据库之间 0.3 毫秒的延迟将其限制在每秒略高于 3,000 次选择。开发人员被告知要改变他们访问数据库的方式(对 2 个表进行连接,而不是对一个表进行选择,然后对每个结果进行单行选择),这样整个操作只需不到 30 分钟。
关键是,你遇到的问题很不寻常,可能与你的软件行为异常有关,你真的应该调查一下这里发生了什么,为什么2 台机器的设置速度太慢了。
拆分成 2 台机器应该通常可以提高性能,因为您有更多的 CPU 来完成工作。它还可以提高可维护性。您的数据库可能需要特殊的内核参数或补丁级别才能正常工作;您的 Web 服务器可能有冲突的要求。而且,无论何时进行升级,都可以更轻松地升级两个系统中的一个而不影响另一个。