【问题标题】:How to handling PDO MySQL fail over in AWS using persistent connections如何使用持久连接在 AWS 中处理 PDO MySQL 故障转移
【发布时间】:2019-09-23 17:13:08
【问题描述】:

我们遇到了 AWS Aurora 故障转移问题,正在寻找解决方法。

场景

AWS Aurora 设置了两个端点:

  • 作者:
    • 主机:stackName-dbcluster-ID.cluster-ID.us-west-2.rds.amazonaws.com
    • 解析为 IP:10.1.0.X
  • 读者:
    • 主机:stackName-dbcluster-ID.cluster-ro-ID.us-west-2.rds.amazonaws.com
    • 解析为 IP:10.1.0.Y

因此我们的 PDO MySQL 连接字符串是stackName-dbcluster-ID.cluster-ID.us-west-2.rds.amazonaws.com(用于写入)

故障转移后

在故障转移时,DNS 条目被翻转为指向如下:

  • 读者:
    • 主机:stackName-dbcluster-ID.cluster-ro-ID.us-west-2.rds.amazonaws.com
    • 解析为 IP:10.1.0.X
  • 作者:
    • 主机:stackName-dbcluster-ID.cluster-ID.us-west-2.rds.amazonaws.com
    • 解析为 IP:10.1.0.Y

关键的是,PDO 连接字符串(用于写入)保持相同的“stackName-dbcluster-ID.cluster-ID.us-west-2.rds.amazonaws.com”,但指向不同的 IP 地址。

发生了什么

我们遇到错误 1290“SQLSTATE[HY000]:一般错误:1290 MySQL 服务器正在使用 --read-only 选项运行,因此无法执行此语句”。

随着数据库引擎停止启动,我们的初始持久连接将“消失”并失效(我们立即在重新连接/重试代码中处理)。

但是,上述错误意味着新连接将与旧节点建立,但不会随着 DNS 更改的传播而进一步失效。它们持续了 10/15 分钟(远超过 DNS 的 TTL)。

我的问题

  1. 有谁知道 PDO 上的持久连接是根据连接字符串检索的,还是使用 IP 或其他签名更可靠?有证据表明它是主机名,但需要确认。
  2. 有谁知道在 PDO 中将持久连接标记为“无效”的方法,这样就不会再次使用了吗?
  3. 或者,我错过了什么?

旁注

我们已经准备好处理重试的代码,并告诉他们重试以获取新的非持久连接(有效)。正是在这一点上,我们可以“使”PDO 连接“无效”,这样下一次运行的脚本就不会一遍又一遍地重复这个循环。

故障转移随时可能发生,因此我们无法执行手动操作,例如重新启动 php(我们这次必须这样做)。

如果没有持久连接,性能会明显变慢。

FastCGI、Centos 16、PHP 7.2、MySQLD 5.0.12-dev(在 Centos 上是正常的 - 请参阅 https://superuser.com/questions/1433346/php-shows-outdated-mysqlnd-version

【问题讨论】:

  • 更新:一直在阅读有关php.net/manual/en/book.mysqlnd-ms.php 的信息 - 但是尚不清楚使用此插件是否可以解决相同的问题。它可能有助于故障转移,但不清楚 DNS 更改是否会导致现有连接失效。任何确认/指针表示赞赏。
  • 两个单独的服务器无法提供与 NBDInnoDB 集群所提供的相同的可用性。
  • 不是一个实际的答案,但请注意,您实际上可以在故障转移时重新启动 php。或者做点别的。您可以订阅RDS events,这可以让您解决这个问题。远非理想,但也许有帮助。
  • @bgdnlp 感谢您的评论。如问题所述,我确实在我们的警报系统崩溃后重新启动了 PHP(我们每个安装大约有 500 个监控点),但我宁愿在错误发生之前自行修复所有内容,而不是因为我们有错误触发警报而需要被唤醒.无论如何,故障转移都会发出警报,但我们可以放松而不是担心......
  • 可以检查它是否适合你:github.com/jeremydaly/serverless-mysql/issues/7

标签: php mysql amazon-web-services pdo amazon-aurora


【解决方案1】:

必须终止并重新启动持久连接。

让我想起了一个 2 分钟的 TTL,它需要 20 分钟才能被识别。我不知道亚马逊是否做得更好,或者他们在 DNS 方面是否有发言权。

5.0.12??那是2005年发布的!也许是一个错字。无论如何,我认为版本在这个问题中并不重要。

DNS 可能不是故障转移的最佳方式;那里有几个代理服务器。我希望它们能在几秒钟内翻转。但是,他们需要知道谁是谁,而不是依赖 DNS。

当该错误发生时,您可以修改代码以断开+重新连接吗? (这可能没有帮助。)

【讨论】:

  • 感谢您的回复。如问题中所述,代码确实使用非持久连接断开并重新连接,这解决了单个脚本实例的问题。问题是下一个脚本出现并抓取一个仍然指向旧服务器的持久连接,并且必须重复断开/重新连接序列。成千上万次。我需要知道如何使该持久连接无效。
  • 关于 DNS 不是最佳方式/代理,这就是 AWS 的工作方式。我在评论中提到了 mysqlnd_ms 库,但我没有看到任何逻辑表明它不会遇到同样的问题。如果没有其他人可以建议的替代方案,我会尝试。
  • @Robbie - 它配置了多少个持久连接?这可能有助于降低吗?
  • 我不知道您可以设置最大数量,并且手册页似乎没有配置:php.net/manual/en/mysqlnd.config.php(或者是其他地方吗?)。我们有多达 80 个 FPM 进程运行不定数量的 apache 进程。非常粗略地说,每台服务器大约有 1000 个连接。虽然减少它们可能会减少问题,但它不会消除问题(这是我想做的!)
  • @Robbie - Apache 有一种方法可以控制它产生的子节点的数量(在“mpm”中?)。 “解决问题”的激进方法可能是重新启动 Apache。
【解决方案2】:

很遗憾,此错误已记录在案:

https://github.com/jeremydaly/serverless-mysql/issues/7

所说的一切都围绕着迁移到:mysqlnd mysqlnd_ms 的驱动程序

我会继续寻找更有效的解决方案。

【讨论】:

  • 我在问题中没有提到无服务器。我是那个提到驱动程序差异的人-该链接中没有提到它们(实际上,或其他任何地方-我正在寻找其他人是否经历过)。感谢上面所有的cmets。这是试图抢夺赏金的明目张胆的回答 - 请删除它。
  • 检查这个:clusterdb.com/mysql/…
  • 我做到了。我通读了整页,绝对没有提到手头的问题。您能否将相关部分添加到您的答案中,因为它就在我的头上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 2020-08-07
相关资源
最近更新 更多