AWS EC2自建MySQL迁移至Azure托管MySQL后性能严重下降求解决方案
我们有一个150MB的小型MySQL数据库,在AWS t2.large实例上自建运行时性能非常快。
硬件规格:Azure侧为2vCPU、10GB内存,AWS侧为2 vCPU、8GB内存。
但公司决定将AWS数据库迁移到Azure托管MySQL,PHP应用暂时仍保留在EC2上运行。
两台服务器硬件配置相近,实际上Azure还多了2GB内存,二者vCPU均为2核。
迁移到Azure后我们遇到了严重的性能下降问题:
- 同样的ajax请求在AWS上耗时15秒,在Azure上需要2.5分钟。
Azure MySQL数据库的CPU和内存平均使用率从未达到分配资源的50%,因此硬件规格看起来并不是问题所在。
我们已经将Azure MySQL数据库的服务器参数redirect_enabled设置为ON,并开启了TLS 1.2版本的强制SSL。
同时我们也安装了"mysqlnd_azure"扩展,使用的命令如下:
sudo pecl install mysqlnd_azure
我们验证配置对连接的影响,发现主机名没有发生任何变化:
在下方的“测试代码”中,如果重定向设置为ON,会返回错误“Connect error (2002):”;如果ini文件中重定向设置为off,测试代码会进入else分支且返回的主机名与连接使用的一致,说明重定向未生效。但可以确认mysqlnd_azure扩展已加载,结果集中的表名也可以正常显示。
测试代码如下:
<?php $host = '<yourservername>.mysql.database.azure.com'; $username = '<yourusername>@<yourservername>'; $password = '<yourpassword>'; $db_name = 'testdb'; echo "mysqlnd_azure.enableRedirect: ", ini_get("mysqlnd_azure.enableRedirect"), "\n"; $db = mysqli_init(); //The connection must be configured with SSL for redirection test $link = mysqli_real_connect ($db, $host, $username, $password, $db_name, 3306, NULL, MYSQLI_CLIENT_SSL); if (!$link) { die ('Connect error (' . mysqli_connect_errno() . '): ' . mysqli_connect_error() . "\n"); } else { echo $db->host_info, "\n"; //if redirection succeeds, the host_info will differ from the hostname you used used to connect $res = $db->query('SHOW TABLES;'); //test query with the connection print_r ($res); $db->close(); } ?>
我们的应用基于Code-igniter和PEAR开发。
是否有人遇到过AWS EC2上运行的Code Igniter对接Azure MySQL数据库的同类问题?有什么修复该问题的建议?
核心问题原因
你遇到的重定向失败、性能暴跌的核心原因是跨云网络场景下Azure MySQL重定向功能不兼容:
Azure MySQL开启重定向后,会返回数据库实例所在的Azure内部VNET地址,部署在AWS EC2的服务无法路由到该内网地址,因此开重定向会直接报2002连接错误,关闭重定向后所有请求都要走Azure MySQL的公网代理节点,额外增加了多跳转发开销,直接导致性能下降十几倍。
临时修复方案(应用暂留AWS EC2时)
- 关闭Azure MySQL的
redirect_enabled参数,同时在PHP.ini中将mysqlnd_azure.enableRedirect设置为off,避免无效的重定向尝试带来额外开销。 - 优化CodeIgniter数据库配置:
- 开启持久连接:将数据库配置项
$db['default']['pconnect']设置为TRUE,减少每次请求的TCP握手、SSL认证开销。 - 配置本地SSL证书:将Azure MySQL的CA根证书下载到EC2本地,在数据库配置中指定本地证书路径,避免每次连接都拉取证书验证。
- 调整连接超时参数:将
connect_timeout设置为不低于10s,避免跨公网网络波动导致的频繁连接失败重试。
- 开启持久连接:将数据库配置项
- 优化Azure MySQL服务器参数:
- 调低
wait_timeout和interactive_timeout到120s,及时释放无效连接,避免连接数占用过高。 - 开启查询缓存(仅MySQL 5.7版本适用,8.0及以上版本已移除该功能),降低重复查询的开销。
- 调低
长期最优方案
将PHP应用迁移到与Azure MySQL同区域的Azure计算资源(虚拟机/应用服务),与数据库部署在同一VNET内后再开启redirect_enabled参数,此时重定向功能可以正常生效,数据库访问性能会恢复到和AWS自建MySQL相近的水平。
如果有条件可以额外增加Redis缓存层,将高频查询结果缓存,进一步减少数据库访问压力。
内容的提问来源于stack exchange,提问作者mahen3d

