阿里云最近的99元ECS大家都买了吧? 配置是:(2核(vCPU) 2GiB) 抱着试试看的心情,购买了一个,打算放一个WordPress玩一玩,结果一玩不知道,一玩一个不吱声。现在开个博客也得备案,感觉现在应该没多少人还在自建Wordpress了,记录一下,权当消遣。
安装的操作系统是Alibaba Cloud Linux 3.2104 LTS 64位,按照官方的文档快速的安装好了nginx、mysql、php三件套,把之前的WordPress搬过来了,你以为就完事了?
没过多久,系统就hang死了,连ssh都连不上去了,通过官网的vnc连接,连上去就几个冰冷的话:May 1 21:00:13 iZbp186jqse0xc20f9rz2aZ kernel: Out of memory: Killed process 1201 (mysqld) total-vm:1560820kB, anon-rss:379128kB, file-rss:0kB, shmem-rss:0kB, UID:27 pgtables:1028kB oom_score_adj:0
看起来是mysql占用内存过多,oom了。那怎么办呢? 修改mysql的配置,减小内存空间吧。
修改完毕,重启,问题依旧,没有任何改善。
百思不得其解,五一期间,我提了一个工单,阿里云的小哥也是认真负责,专程打电话给我,我描述了问题,他的回答是,WordPress太占资源,99的机器跑不起来,我继续问他那这玩意儿还有啥用? 他说这玩意儿就是学生用来跑脚本的,不能跑网站?????好家伙,一问一个不吱声。
上去使用goaccess看了下流量,压根就没什么流量啊,这玩意儿真的解释不通,因为程序刚起来是没问题的,可以正常访问,但是没有什么流量过段时间就挂了,真是奇怪的。
监控系统显示磁盘的iops在挂掉之前非常高,也不知道操作系统在干什么?
本来想直接退款算了,想想已经花时间,把WordPress搬过来了(里面有很多图片,每次都得备份然后恢复整个网站),网上搜了下,说是内存不够,可以增加swap区,用磁盘代替内存,果断尝试,发现有点效果,本来以为解决了,结果没过多久,问题依旧,看来swap只能减缓问题,不能解决问题。而且装了swap后,程序非常缓慢,这个也能理解,毕竟要交换磁盘。稍微点几下网页,整个系统负载就飙升。
我就一直好奇,为什么没有流量,磁盘的iops却这么高呢?
装了一个atop继续监控,想看看高iops的时候,到底是什么程序,在干什么?
看了半天也看不出所以然来,问问大模型,怎么优化吧。
思路: 降低mysql的内存使用量。
方向不对,我得服务器配置很低,只有2G的内容和4G的swap,我可以接受网站慢,但是不能让mysql的使用oom,导致网站挂掉
了解你的问题了,你想要针对低内存服务器环境进行MySQL的内存使用优化。在这种情况下,以下有一些具体建议:
使用MyISAM替代InnoDB:如果你的应用允许,使用MyISAM可能会是更好的选择。MyISAM的内存占用相对较低,特别是当你的服务器中已没有太多剩余内存空间时。但需要注意的是,MyISAM不支持事务,而且在高并发的情况下可能会遇到表锁的问题。
调整InnoDB配置:如果你坚持使用InnoDB,你应该调低innodb_buffer_pool_size的值,值得注意的是,这可能会对性能产生影响。对于2GB内存的服务器,可以将其设置为128M左右:
sql
[mysqld]
innodb_buffer_pool_size = 128M
关闭二进制日志:如果你不使用复制(replication),你可以通过关闭二进制日志的方式来节省内存。通过设置log_bin = 0或者直接在my.cnf中注释掉所有log_bin相关配置来实现。
优化查询:优化应用查询,减少不必要的类似SELECT *这种取出全部列的查询,只取你需要的列;尽可能利用索引(但注意不要过度索引,因为索引同样会占用内存空间)。
限制连接数:通过限制max_connections,可以减少并发连接对内存的消耗。但是,设置过低可能会导致有些用户无法连接到MySQL服务器。
sql
[mysqld]
max_connections = 50
以上方法可以帮助你在内存有限的环境下运行MySQL,但请注意,过度降低MySQL资源使用可能会严重影响性能,导致数据库操作缓慢。
如何切换 InnoDB 到MyISAM
将MySQL数据库中的InnoDB表格转为MyISAM表格,可以使用ALTER TABLE命令。下面是具体操作方法:
假设我们要将数据库mydb中的表mytable从InnoDB切换到MyISam,可以使用以下SQL命令:
sql
USE mydb; -- 进入目标数据库
ALTER TABLE mytable ENGINE=MyISAM; -- 将mytable表的引擎改为MyISAM
注意:转换的过程中会锁表,这将阻止对表格的所有访问直到转换工作完成。因此,你需要在数据库访问压力低的时候进行改变存储引擎的操作。
需要明确的是,MyISAM并不支持诸如事务处理或外键等高级处理,因此在进行转换之前,请一定确保你的应用不依赖这些InnoDB特性。否则,这可能会导致应用运行异常。转换引擎前,建议对数据进行备份,以防万一。
ALTER TABLE mytable ENGINE=MyISAM; -- 将mytable表的引擎改为MyISAM
我需要将整个database切成myisam而不是表,怎么操作
如果你要将整个数据库(包含多个表)都从InnoDB转换到MyISAM,你需要对该数据库下的每个表执行上述ALTER TABLE命令。为了简化操作,你可以用脚本来实现,假设你要将数据库mydb的所有表从InnoDB切换到MyISAM,可以使用以下SQL命令:
sql
-- 锁定数据库
USE mydb;
-- 获取所有需要进行转换的表名
SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=MyISAM;')
FROM information_schema.TABLES
WHERE engine='InnoDB' and table_schema='mydb';
这段SQL会生成一系列ALTER TABLE语句。你只需要运行这些语句即可完成对所有表的转换。
需要注意的是,这项操作可能需要数据库管理员权限,并且在执行引擎转化期间,数据表会被锁定,这可能影响到正常的业务,因此最好在业务低峰期进行。
注意,MyISAM不支持事务和外键等功能,如果你的数据库里有这类应用,那么转换后的数据库可能无法正常工作。在执行转换前一定要做好数据备份,防止数据丢失。
修改完毕,之后,发现mysql的内存使用确实从第一名降低到最后了
接着可以发现php-fpm占用了很多内存空间,于是接下来的思路优化php,继续询问大模型
mysql的内存使用已经降下去了,php-fpm这个还是占用了大量的内存,如何优化
针对php-fpm的内存优化,有以下几点建议:
调整进程数量:你可以调整php-fpm的pm设定,减少子进程的数量。例如如果pm设置为static,你可以适当减小pm.max_children的值。
更改进程模式:另一个值得尝试的是更改pm的值,从dynamic更改为ondemand。在ondemand模式下,php-fpm只会在有需求的情况下才生成子进程,这样可以减少不必要的内存占用。
优化PHP脚本:通过优化PHP脚本来减少内存使用,例如:避免在PHP中使用大的数据结构,限制使用大量的全局变量等。
使用Opcode缓存:使用Opcode缓存可以提高PHP的运行效率,从而减少总体的内存占用。推荐使用的Opcode缓存扩展包括:APC、Opcache等。
以上方案只是一种可能的优化方式,具体要看你的服务器和应用的实际情况来决定。总的来说,需要在保证应用运行正常的前提下,通过以上方式来尽量降低php-fpm的内存使用。
修改完毕,接着重启,发现效果嘎嘎的好
看内存始终在25%左右了,而网站飞速,快得不得了,至此,整个优化完成,网站也能正常的提供服务了。