SQL 查询打破了我们的游戏! (后端服务器满负荷)

Posted

技术标签:

【中文标题】SQL 查询打破了我们的游戏! (后端服务器满负荷)【英文标题】:SQL queries break our game! (Back-end server is at capacity) 【发布时间】:2012-11-18 00:13:19 【问题描述】:

我们有一个 Facebook 游戏,它将所有持久数据存储在 mysql 数据库中,该数据库在大型 Amazon RDS 实例上运行。我们的一张桌子大小为 2GB。如果我在该表上运行任何花费超过几秒钟的查询,我们的游戏执行的任何 SQL 操作都将失败并出现错误:

HTTP/1.1 503 Service Unavailable: 后端服务器满负荷

这显然会拖垮我们的游戏!

我在这些时间段内监控了 RDS 实例上的 CPU 使用率,虽然它确实达到峰值,但并没有超过 50%。以前我们在较小的实例大小上,它确实达到了 100%,所以我希望只在问题上投入更多的 CPU 容量就可以解决它。我现在认为这是打开连接数量的问题。但是,我使用 SQL 才 8 个月左右,所以我不是 MySQL 配置方面的专家。

是否有一些配置设置我可以更改以防止这些查询使服务器过载,或者我不应该在游戏启动时不运行它们?

我正在使用 MySQL Workbench 来运行查询。

任何帮助将不胜感激 - 谢谢!

编辑:

这是一个例子......

SELECT * 
FROM BlueBoxEngineDB.Transfer 
WHERE Amount = 1000 
AND FromUserId = 4 
AND Status='Complete';

表格如下所示:

TransferId  Started  Status  Expires  FromUserId  ToUserId  CurrencyId  Amount  SessionId

1177    2012-06-04 21:43:18 Added       150001      2           4           1   12156
1179    2012-06-04 21:48:50 ISF         150001      2           4           1   12156
1181    2012-06-04 22:08:33 Added       150001      2           4           25  12156
1183    2012-06-04 22:08:41 Complete    150001      2           4           50  12156
1185    2012-06-04 22:08:46 Added       150001      2           4           200 12156

【问题讨论】:

我假设大表已经有适当的索引? 即使表是 2GB,如果您没有对它们变得超级复杂,查询通常不会超过几秒钟。请发布示例查询、该查询的EXPLAIN 和表结构。来自游戏的查询是否写入您正在运行查询的表?如果是这样,则可能是锁定问题。 我只是用这个简单的查询取出它:SELECT * FROM BlueBoxEngineDB.Transfer WHERE Amount = 1000 AND FromUserId = 4; 我读到了SELECT * .. 第一期。你真的需要所有的列吗? 严肃的回答:聘请一位非常优秀的 DBA。听起来您的问题远远超出了问答网站的范围。如果这是一项真正的业务,请获得优秀的员工。编辑:从头开始 - 只需让某人咨询一天或一周。 【参考方案1】:

您真的应该考虑运行高可用性 RDS 并在其中设置只读副本。这样,您就可以对副本运行复杂的查询,满足您的需求,而不会干扰生产数据库。

2GB(大小)的数据库实际上并没有那么大。如果您在尝试查询的表上有正确的索引,则不应锁定数据库。

最重要的是 - 如果您不知道它会做什么,请不要在高容量生产数据库上运行查询。从上面的 cmets 看来,您似乎不是一个非常有经验的数据库管理员。没关系。在大容量服务器上工作对您来说绝对是一种学习体验,只是尽量不要让您的课程在您的服务崩溃的地方进行。同样,这就是为什么在尝试对大型表进行查询之前拥有副本或创建数据库快照并设置测试数据库是一个非常好的主意的原因。

【讨论】:

其实刚做完就看到你的回复了。效果很好! :)【参考方案2】:

(FromUserId, Amount, Status) 上的索引可能会对这个查询有很大帮助。

您可能有更多查询此表的变体。为它们中的每一个添加一个索引,最终会使您在表中拥有数十个索引,这可能会带来其他问题。

尝试分析慢查询日志,然后优化最慢的查询(以及使用更多 CPU 百分比的查询)。

【讨论】:

【参考方案3】:

您可能需要调整架构(adding indexes 是直接步骤)。

要分析您的情况,您可以访问数据库的 MySQL 慢查询日志,以确定是否存在运行缓慢的 SQL 查询,如果是,则确定每个查询的性能特征。您可以设置“slow_query_log”数据库参数并查询 mysql.slow_log 表以查看运行缓慢的 SQL 查询。请参考Amazon RDS User Guide了解更多信息。

您可能应该考虑将某些表卸载到DynamoDB 或Redis。它们都将给出个位数毫秒的延迟,因此在游戏开发者中非常受欢迎。你只需要考虑你的data structure。

【讨论】:

以上是关于SQL 查询打破了我们的游戏! (后端服务器满负荷)的主要内容,如果未能解决你的问题,请参考以下文章

使用 linq to sql 后端通过 WCF 查询 DTO 对象

大数据=SQL Boy,SQL Debug打破SQL Boy 的僵局

sql查询学习和实践点滴积累

大数据量高并发的数据库优化,sql查询优化

日期转换错误——MS Access前端查询sql后端

如何在 MySQL 中打破类似于 MS SQL Server 的列名?