首页 > 解决方案 > 连接到 AWS RDS 数据库的非 AWS 服务器要慢得多

问题描述

我正在从一家托管公司迁移,该公司目前在同一台服务器上托管我的基于 PHP 的 Web 应用程序和 MySQL 数据库。他们的服务器规格不错,服务器运行在 SSD、11GB RAM 和 8 核 CPU(GenuineIntel、QEMU 虚拟 CPU 版本 (cpu64-rhel6)、2399.996 MHz、4096 KB 缓存)上。

我不能一次全部移动所有内容,所以只想将数据库移动到 AWS RDS 并将我的 PHP 配置中的主机更新到 AWS 端点。

我已经使用 AWS 上可用于测试的基本包进行了设置 - t2.micro EC2(用于测试/基准测试 PHP 脚本)和 db.t2.micro RDS。

一切正常,但是当我从远程非 AWS 服务器连接时,速度非常慢。相同的数据库表,运行相同版本的 MariaDB,表中的行数相同,结果如下:

AWS EC2 -> AWS RDS (fully AWS)
Connected via PDO in 0.04 seconds
Queried 1000 rows in 0.63 seconds

Remote Server -> AWS RDS (part AWS)
Connected via PDO in 0.16 seconds
Queried 1000 rows in 5.49 seconds

Remote Server -> Database running on same server (non AWS)
Connected via PDO in 0.00 seconds
Queried 1000 rows in 2.70 seconds

如您所见,完整的 AWS 设置是迄今为止最快的,即使在他们的免费套餐上也是如此。

完全远程服务器设置速度较慢,但​​仍然不可怕。

远程服务器 -> AWS 设置是最慢的。

由于我是 AWS 的新手,如果有人能告诉我这是否符合预期,我将不胜感激。对 AWS RDS 的非 AWS 调用总是会慢很多吗?

两台服务器上的某些东西会限制速度吗?

PS。远程服务器在英国,AWS 区域设置为 EU-West,所以我认为它与距离延迟无关。

编辑 Rick James 在下面的评论中询问了关于查询缓存等的问题。缓存被禁用,但要确保我已经更改了我的脚本,以便它执行以下操作:

$mysqli = mysqli_connect($dbhost,$username,$password,$dbname) or die ("could not connect to mysql");

$tableCreate = "CREATE TABLE IF NOT EXISTS test_tbl (id int(11) NOT NULL auto_increment, RandomTxt TEXT, PRIMARY KEY (id))";
$queryResult = mysqli_query($mysqli , $tableCreate);

for ($i = 1; $i <= 1000; $i++) {
    mysqli_query($mysqli,"INSERT INTO `test_tbl` (RandomTxt) VALUES ('abcdefghijklmnopqrstuvwxyz')" )  ;
}

$result = mysqli_query($mysqli , 'SELECT * FROM test_tbl') ;
$arrayResults = array() ;
while ($row = $result->fetch_assoc()) {
    array_push($arrayResults , $row['RandomTxt']);
}

$dropTable = "DROP TABLE `test_tbl`";
$queryResult = mysqli_query($mysqli , $dropTable);

每次查询后,我都有一个 PHP 计时器脚本。此更新脚本的结果是:

AWS EC2 -> AWS RDS (fully AWS)
Db connection established at : 0.04184008
Table created at : 0.05363607
Data inserted into the table at : 3.64998102
Data is read from table and inserted into an array at : 3.65190291
Table dropped at : 3.66061902

Remote Server -> AWS RDS (part AWS)
Db connection established at : 0.08496714
Table created at : 0.11568093
Data inserted into the table at : 21.78033495
Data is read from table and inserted into an array at : 21.82050204
Table dropped at : 21.84762096

Remote Server -> Database running on same server (non AWS)
Db connection established at : 0.00079298
Table created at : 0.00664401
Data inserted into the table at : 0.15589213
Data is read from table and inserted into an array at : 0.16134501
Table dropped at : 0.16468596

我只想重申,我是使用 AWS 的新手,如果这些结果符合人们的预期,请告诉我。我需要知道从非 AWS 服务器连接到 RDS 是否应该足够快以供目前的生产使用,当然不是。

编辑 2 我也跑去time nc -vz xxx.xxx.eu-west-1.rds.amazonaws.com 3306检查时间。来自非 AWS 主机的结果是:

real    0m0.227s
user    0m0.014s
sys     0m0.005s

从 EC2 到 RDS 的结果是:

real    0m0.112s
user    0m0.002s
sys     0m0.000s

标签: phpamazon-web-servicesamazon-ec2mariadbamazon-rds

解决方案


对于“远程”测试,我很惊讶它只有 5.49 秒穿过池塘。您在美国和英国之间有 1002 次往返。这意味着每次 ping 时间为 5.5ms;我以为不止于此。如果将所有 1000 次插入放入单个语句中,则所有“插入”时间都会显着提高。这种变化甚至会帮助本地代码,只是没有那么显着(只有 10 倍而不是近 1000 倍)。

据我了解各种配置的描述,ping 时间(最多 5.5 毫秒)是影响速度的最大因素。

第二大数字是提交事务。一次提交 1000 行的“本地”150 毫秒意味着非常快的 0.15 毫秒。那一定是SSD。

我更喜欢microtime(true)在每个步骤之前和之后进行计时,然后打印差异。闻起来你提供的数字有额外的开销。

另一件要验证的事情:表 ENGINE=InnoDB(不是 MyISAM)是否在所有测试中?最好在CREATE TABLE.

所以...批量INSERTs和做其他事情来减少往返。还有其他技巧,但我们需要看到真实的代码,而不是人为的基准。另一个技巧是将多个语句组合成一个存储过程;然后到proc有一个往返CALL而不是几个。


推荐阅读