EC2实例运行Django 1.9.6时突发高Disk IOPS问题求助
嘿,我之前在维护类似技术栈的Django应用时,刚好碰到过EC2磁盘IO突增的问题,结合你的情况(Django 1.9.6 + Apache + Celery + New Relic,数据全在外部存储),给你梳理几个最可能的排查方向,亲测有效:
核心排查方向
首先得明确:即使你的应用没有显式执行磁盘操作,很多组件在后台会悄悄进行磁盘读写,这是最容易被忽略的点。
1. New Relic Agent的后台日志/采样过载
New Relic Agent默认会生成日志、采样应用数据,一旦配置不当(比如日志级别设成DEBUG,或者采样频率过高),很容易导致大量磁盘写入:
- 先检查New Relic的日志目录(通常是
/var/log/newrelic/),看看日志文件是否在短时间内暴增大小 - 临时把Agent的日志级别调低到INFO或者WARN,观察IOPS是否下降
- 打开
newrelic.ini配置文件,检查log_file、log_level、transaction_tracer相关配置,有没有过度采样的情况
2. Apache日志的突发写入
Apache默认会实时写入访问日志和错误日志,如果突然遭遇大量异常请求(比如爬虫扫站、恶意请求),日志写入会直接拉高IOPS:
- 用
tail -f /var/log/apache2/access.log(对应你的Apache日志路径)实时查看请求量,有没有突发的大量请求 - 开启
mod_status查看Apache的当前连接数和请求速率,确认是否有流量突增 - 可以临时给日志加上缓冲写入(调整
CustomLog的buffer参数),测试IOPS是否变化
3. Celery的后台日志与本地配置失误
虽然你用了Redis做队列,但Celery worker可能会把日志写入本地磁盘,或者不小心配置了本地文件作为任务存储(概率低但值得排查):
- 检查Celery worker的日志路径(比如
/var/log/celery/),看日志是否突发增长 - 确认Celery的
broker_url确实指向Redis,而非本地文件协议(比如filesystem://) - 用
ps aux | grep celery查看worker进程状态,有没有异常进程在疯狂写磁盘
4. Django隐式的磁盘操作
Django 1.9.6即使你没写磁盘逻辑,一些默认行为也可能触发磁盘读写:
- 检查
DEBUG模式是否开启?如果开启,Django会生成大量调试日志,还会把模板缓存到本地(默认在/tmp/或项目的__pycache__目录) - 查看Django的日志配置,是否有大量日志写入本地文件
- 排查第三方Django插件(比如缓存中间件、统计插件),有没有在后台写入磁盘数据
5. 系统级的磁盘操作
有时候问题出在EC2实例的系统层面,和应用无关:
- 用
iostat -x 1实时查看磁盘IO情况,定位是哪个分区(比如/dev/xvda)的IO飙升,以及%util(磁盘利用率)是否接近100% - 用
lsof | grep -i write找出当前正在写磁盘的进程,再用ps aux | grep <PID>定位具体进程 - 检查系统定时任务(
crontab -l),看IO突增的时间点是否有备份、日志轮转、系统更新等操作 - 对比AWS CloudWatch的磁盘IO指标(DiskReadOps、DiskWriteOps)和实例的CPU、内存指标,看是否有相关性
6. 分步验证缩小范围
如果以上排查都没头绪,可以尝试分步禁用组件,观察IOPS变化:
- 先停止New Relic Agent(
service newrelic stop),观察10分钟看IO是否下降 - 再停止Celery worker,继续观察
- 最后临时把Apache日志重定向到
/dev/null,看IO变化
这样一步步排查,总能找到根源。
内容的提问来源于stack exchange,提问作者Abhi N
相关产品推荐
相关产品推荐

