这肯定是一个有争议的问题,因为很多人可能想立即推荐一些简单的事情,比如:拆分表!将读/写拆分为主/从配置!增加服务器内存!等等……不过,让我先解释一下这个问题:
我有一台功能强大的服务器:8GHz、160GB 存储、8GB RAM(16GB Flexi RAM)、RAID 10、16GB Flexi-SSD。运行 mySQL、PHP、Apache、Debian。
我当前的数据库包含大约 16 个表,其中一个表特别包含 1.7GB 的信息,有 2300 万行(已编入索引)。
我运行的服务需要每天、有时每小时扫描通过第三方收到的数据,每分钟产生 100 行新数据,最多每分钟产生 5000 行左右(很少)。数据是通过从 API 获取数据的爬虫程序获取的,这些爬虫程序自动、按计划运行,有时是临时运行,因此它们对主服务器来说是写入繁重的。
当人们使用该网站时,将有刷新查询可用来向他们显示最新的分析数据,因此,当许多人登录时,读取量非常大(我处理了慢速查询并尝试使用索引尽可能减少所有内容)。我在数据库中即时生成这些分析(它们最多有 24 小时的历史),每个用户最多可包含 500 万条记录。我认为预渲染这些查询是没有意义的,因为我必须以某种方式在预渲染的 HTML 文件中考虑所有的切片/过滤......对吗?或者人们会这样做?
现在,有时我会在手机上收到警告,登录服务器后才发现 mySQL 已关闭。我会进行 mysqlcheck 和修复,这需要长达 2 小时或更长时间,最后退出时数据库可以正常工作。我重新启动所有程序,一切又恢复正常。我一直不知道为什么会发生这种情况,但这种情况大多发生在博客写到该网站后,人们疯狂地注册并攻击该网站。但没有详细的日志记录网站崩溃和宕机的位置。
除了限制注册过程(等待队列)的速率之外,我还能做些什么来确保无论发生什么情况,MYSQL 都不会崩溃?我可以每小时左右对实时实例运行某种自动修复和优化吗?我认为这会阻止对表的所有访问,这太糟糕了?
我真的被这个问题搞晕了。我拆分了读/写,理论上可以将所有读取访问用户拆分到 EC2 实例上的从属服务器。但是,我遇到了使用量急剧上升和下降的问题,一旦我需要一个新的 EC2 实例,就需要我传输最多 2GB 的数据来同步从属数据库……如果我决定关闭/启动暂停数天的 EC2 实例,mysql-bin 日志就永远无法解决这个问题。
到目前为止我已经能够跟上,但即使有了 EC2 和其他技术,我的理解和技术能力仍未达到极限。
我很乐意分享所有必要的信息,以便将其作为以后有用的主题/文档。由于并非每个网站都是 youtube/youporn/instagram/tumblr 类型的环境,因此我觉得对于我的网站类型(高写入/读取,每位用户 500 到 5M 条记录,3000-10000 名用户)来说,信息太少了。
谢谢大家,请随意提问,我会提供更多信息。我很想听听你们的最佳做法。
答案1
就您在评论中介绍的内容而言,我认为您的 my.cnf 配置有误。您可能“给予”mysql 的 RAM 远远超过系统可用的 RAM。thread_stack=100M 远远大于建议值。我敢打赌 OOM-killer 只会终止您的 mysql 以防止内核内存不足。
你应该先检查你的mysql配置mysqltuner并微调你的 mysql 配置以避免服务器崩溃。
不建议在生产环境中根据 cron 计划针对大数据运行 REPAIR、ANALYZE、OPZIMIZE 等,但不时地刷新表是一种很好的做法。