我运营的网站包含 ~500名实时访问者, ~50k每日访问者和 ~1,300万总用户。我在 AWS 上托管我的服务器,在那里我使用了不同类型的多个实例。当我启动网站时,不同的实例成本相同。当网站开始获得用户时,RDS实例(MySQL DB)CPU不断地进入屋顶,我不得不多次升级,现在它已经开始占用主要部分的性能和每月成本(约95%的(2,8k $ /月))。我目前使用的是具有16vCPU和64GiB RAM的数据库服务器,我还使用多可用区部署来防止故障。 我想知道数据库的价格是否正常,或者我做错了什么?
数据库信息
目前我的数据库有40个表,其中大多数表有100k行,有些表有~2百万,1表有3千万。 我有一个系统档案行,这些行在21天之后不再需要了。
网站信息
该网站主要使用PHP,还有一些NodeJS和python。
网站的大部分功能都是这样的:
我还会以10-30秒的间隔从数据库中运行100个左右的轮询,它们有时会插入/更新数据库。
附加
我已经做了几件事来尝试降低数据库的负载。如启用数据库缓存,对某些查询使用redis缓存,尝试删除非常慢的查询,尝试将存储类型升级为“Provisioned IOPS SSD”。但似乎没有任何帮助。
这是我对设置参数所做的更改:
我有关于创建一个包含几个较小实例的MySQL集群,但我不知道这是否会有所帮助,而且我也不知道这是否适用于事务。
如果您需要更多信息,请询问,对此问题的任何帮助都非常有用!
答案 0 :(得分:5)
根据我的经验,一旦你提出问题"我怎样才能扩大表现?"你知道你已经超出了RDS(编辑:我承认我的经历导致我的观点可能已经过时)。
听起来你的查询负载非常重要。大量的插入和更新。如果可以使用您的RDS版本,则应增加innodb_log_file_size。否则,您可能不得不放弃RDS并转移到EC2实例,您可以更轻松地调整MySQL。
我还会禁用MySQL查询缓存。在每次插入/更新时,MySQL都必须扫描查询缓存,以查看是否有任何需要清除的缓存结果。如果您的工作量很大,那就浪费时间了。将查询缓存增加到2.56GB会使情况变得更糟!将缓存大小设置为0,缓存类型设置为0.
我不知道您运行的是什么查询,或者您对它们的优化程度。 MySQL的优化器是有限的,因此通常情况下,您可以从重新设计SQL查询中获得巨大的好处。也就是说,更改查询语法,以及添加正确的索引。
您应该进行查询审核,以找出哪些查询会导致您的高负载。一个很好的免费工具是https://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.html,它可以根据您的慢查询日志为您提供报告。使用http://docs.aws.amazon.com/cli/latest/reference/rds/download-db-log-file-portion.html CLI命令下载RDS慢查询日志。
设置你的long_query_time = 0,让它运行一段时间来收集信息,然后将long_query_time改回你通常使用的值。收集此日志中的所有查询非常重要,因为您可能会发现75%的负载来自2秒以内的查询,但它们的运行频繁,以至于它对服务器造成负担。
在您知道哪些查询考虑了负载后,您可以制定一些有关如何解决这些问题的明智策略:
答案 1 :(得分:2)
我认为答案是"你做错了什么"。你不太可能达到RDS限制,尽管你可能会对它的某些部分施加限制。
首先启用详细监控。这将为您提供一些操作系统级别的信息,这些信息有助于确定您的限制因素究竟是什么。查看慢速查询日志和数据库统计信息 - 您可能会遇到一些导致问题的查询。
一旦你理解了问题 - 可能是错误的查询,I / O限制或其他 - 那么你就可以解决它们。 RDS允许您创建多个只读副本,因此您可以将一些读取负载移动到从属。
你也可以转移到Aurora,这应该会给你更好的I / O性能。或者使用PIOPS(或分配更多磁盘,这应该可以提高性能)。你正在使用SSD存储,对吗?
另一个建议 - 如果您的计算(上面的步骤4)需要花费大量时间,您可能需要将其分解为两个或更多交易。
答案 2 :(得分:2)
超过50万的query_cache_size
是坏消息。你经常写作 - 每张桌子每秒多次?这意味着需要多次扫描QC以清除更改的表的条目。当质量控制为2.5GB时,这对系统来说是一个很大的负担!
query_cache_type
应该是DEMAND
,如果你可以证明它完全正确的话。在这种情况下,请SELECTs
加SQL_CACHE
和SQL_NO_CACHE
。
由于您打开了slowlog,请使用pt-query-digest查看输出。第一对查询是什么?
由于您的典型操作涉及写作,因此我没有看到使用只读Slaves的优势。
机器人是否随机运行?或者它们都是同时开始的? (后者可能会导致CPU等出现可怕的峰值)。
你是如何"归档" "旧"记录?最好使用PARTITIONing
和"可传输表空间"。使用PARTITION BY RANGE
和21个分区(以及一些额外内容)。
您的典型交易似乎只能使用一行。是否可以修改为一次使用10或100? (超过100个可能不具有成本效益。)SQL在一次执行大量行时效率更高,而每行查询很多。向我们展示SQL;我们可以深入了解细节。
在一个事务中插入一个新行然后更新它似乎很奇怪。在插入之前你不能完全计算它吗?长时间挂在inserted_id上可能会干扰其他人做同样的事情。 innodb_autoinc_lock_mode
的价值是什么?
"用户"彼此互动?如果是这样,以什么方式?