Efs
跳转到导航
跳转到搜索
efs
3. 检查是否用了 Infrequent Access(IA)存储类 如果你启用了生命周期策略,小文件会被移到 IA 存储类,首次访问延迟高达几十毫秒,会加剧 IO wait 。 建议关闭 IA 或强制把热点文件留在 Standard 存储类
https://www.amazonaws.cn/efs/faq/
说明瓶颈在 **EFS I/O 延迟** 或 **EC2 与 EFS 之间的网络/挂载参数** 上。 --- ## 🧩 一、问题本质分析 > EC2 load 高 + `wa`(I/O wait)高 > ⇒ 表示 CPU 大部分时间在等待 I/O 完成,而不是 CPU 算力不足。 **典型原因:** 1. **EFS 性能模式或吞吐量限制(Throughput/IOPS)** * 默认的 **General Purpose 模式** 适合低延迟小文件,但 I/O 并发量一高就会严重卡。 * 如果你的应用做了大量小文件读写(如日志、批量数据处理),I/O wait 会爆表。 2. **挂载方式/参数不当** * 未开启 NFS 客户端缓存(例如未挂载 `nfs4.1` + `noresvport` 等)。 * 未启用 `EFS Mount Helper` 的 `tls` 优化。 3. **网络延迟或带宽瓶颈** * EFS 是网络文件系统(依赖 VPC 网络性能)。 * 如果 EC2 在另一个 AZ 或未开启 “Mount target in same AZ”,性能会极差。 4. **系统问题叠加:** * swap 触发或内核 page cache 压力大。 * 多线程访问同一个文件导致锁等待。 --- ## 🧰 二、排查思路 可以先确认是不是 EFS 导致的: ```bash # 1. 查看 load 和 I/O wait top # 重点看 %wa # 2. 确认 CPU 实际使用情况 mpstat 1 # 3. 查看哪个进程卡在 I/O iotop -oPa # 4. 测试网络延迟 ping <EFS mount target IP> # 5. 检查挂载参数 mount | grep efs ``` 示例问题输出(常见): ``` /mnt/efs on fs-xxxx.efs.ap-east-1.amazonaws.com:/ type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576) ``` → 如果没看到 `noresvport`、`nconnect=4`、`tls`,说明挂载参数还没优化。 --- ## ⚙️ 三、解决/优化方案 ### ✅ 1. 优化 EFS 性能模式 进入 AWS 控制台 → EFS → File system → “Performance”: * **模式选择:** * 🟢 对多数场景:`General Purpose` * 🟢 如果是高并发(多线程大量 I/O):切换为 `Max I/O` 模式。 * **吞吐量模式:** * 🟢 改为 **Provisioned Throughput**(手动设置高一点的 MB/s),不要只用默认的 Burst。 例如: ```bash Provisioned throughput = 50~100 MB/s ``` --- ### ✅ 2. 优化挂载参数(关键) 编辑 `/etc/fstab` 或挂载命令,修改为: ```bash # 推荐 mount 参数(通过 EFS Mount Helper) sudo mount -t efs -o tls,nconnect=4,noresvport fs-xxxx:/ /mnt/efs ``` 说明: * `tls`:启用加密通道(优化数据路径)。 * `nconnect=4`:允许客户端并行使用多个 TCP 连接,大幅降低延迟。 * `noresvport`:避免 NFS 端口冲突。 * 如果是 `nfs4` 挂载方式: ```bash sudo mount -t nfs4 -o nconnect=4,noresvport,rsize=1048576,wsize=1048576 fs-xxxx.efs.ap-east-1.amazonaws.com:/ /mnt/efs ``` --- ### ✅ 3. 确保同 AZ EFS 每个 AZ 都有独立的 mount target。 ⚠️ 确保 EC2 和 EFS mount target 在同一个 AZ,否则每次 I/O 都要跨 AZ 走公网路径。 ```bash # 检查 EC2 AZ curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone # 检查 EFS mount target AZ aws efs describe-mount-targets --file-system-id fs-xxxx ``` --- ### ✅ 4. 加缓存(EFS + local cache) 对于频繁读取的文件,可以在本地加一层缓存,比如: ```bash # 用 overlayfs 把 EFS 当底层存储 mkdir /mnt/efs /mnt/cache mount -t overlay overlay -o lowerdir=/mnt/efs,upperdir=/mnt/cache,workdir=/mnt/cache_work /mnt/overlay ``` 或者使用 `rsync` 定期同步常用数据,减少频繁 NFS 访问。 --- ### ✅ 5. 系统参数调优 ```bash # 提高NFS客户端缓存 echo 15 > /proc/sys/vm/dirty_ratio echo 5 > /proc/sys/vm/dirty_background_ratio # 禁止 swap 或调整 swappiness sudo sysctl vm.swappiness=10 ``` --- ### ✅ 6. 定期重启/检测卡死防护 既然“以前每天死机 → 升级后变一周死机”,说明**资源是缓解不是根因**。 建议加上 watchdog: ```bash #!/bin/bash # /usr/local/bin/check_efs.sh if [ $(iostat -c | awk '/^avg-cpu/ {getline; print $4}') -gt 50 ]; then echo "$(date) high iowait detected, remounting EFS..." umount -f /mnt/efs mount -a fi ``` 定时执行,防止长期 I/O 堆积导致系统 hang。 --- ## 🔍 七、进一步建议 | 方案 | 适用场景 | 成本 | 效果 | | ----------------------------------- | ------ | ------ | ------------- | | ✅ 优化挂载参数 (`nconnect`, `noresvport`) | 通用 | 免费 | 明显降低 I/O wait | | ✅ 切换 EFS 模式为 `Max I/O` | 高并发 | 轻微增加成本 | 提升性能 | | ✅ 改为 Provisioned Throughput | 频繁 I/O | 中 | 稳定吞吐 | | ✅ EC2 同 AZ 挂载 | 必须 | 免费 | 极大改善 | | ⚙️ 增加本地缓存层 (overlay/rsync) | 读多写少 | 中 | 显著改善延迟 | | ⚙️ 考虑改用 FSx for Lustre 或本地 EBS | 数据密集型 | 高 | 最佳性能 | --- 要我帮你看具体的挂载配置与 EFS 模式吗? 你可以贴出以下命令结果(脱敏后): ```bash mount | grep efs aws efs describe-file-systems --file-system-id fs-xxxx aws efs describe-mount-targets --file-system-id fs-xxxx ``` 我可以帮你判断瓶颈是在**EFS配置**还是**网络挂载参数**上。
clo
# EFS 性能优化变更计划 ## 📋 变更概述 **问题描述**:EFS IO wait 高导致 EC2 负载过高,频繁死机(从每天一次优化到每周一次) **变更目标**:彻底解决 EFS 性能瓶颈,消除死机风险 **预计影响**:无业务中断,性能改善立竿见影 **变更窗口**:建议在业务低峰期执行(如凌晨 2:00-4:00) --- ## 🔍 阶段一:诊断评估(立即执行,0 风险) ### 1.1 收集当前状态信息 ```bash # 记录当前 EFS 配置 aws efs describe-file-systems --file-system-id fs-YOUR_FS_ID > efs-config-backup.json # 检查性能模式 grep "ThroughputMode\|ProvisionedThroughputInMibps" efs-config-backup.json # 查看最近7天的突发积分 aws cloudwatch get-metric-statistics \ --namespace AWS/EFS \ --metric-name BurstCreditBalance \ --dimensions Name=FileSystemId,Value=fs-YOUR_FS_ID \ --start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \ --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \ --period 3600 \ --statistics Average \ --output table > burst-credits-7days.txt ``` ### 1.2 在 CloudWatch 控制台检查以下指标 前往:CloudWatch → Metrics → EFS → File System Metrics **必查指标**(最近7天): - ✅ `BurstCreditBalance` - 突发积分余额 - < 1TB (约1000亿字节秒):🔴 危险,随时可能耗尽 - 1TB - 2TB:🟡 警告,需要关注 - > 2TB:🟢 健康 - ✅ `PermittedThroughput` - 允许的吞吐量 - ✅ `MeteredIOBytes` - 实际使用的吞吐量 - ✅ `PercentIOLimit` - IO 使用百分比(>80% 说明性能不足) ### 1.3 检查 EC2 当前状态 ```bash # 在问题 EC2 上执行 # 查看 IO wait iostat -x 5 3 # 查看挂载选项 mount | grep efs # 查看当前负载 uptime top -b -n 1 | head -20 ``` **📸 记录结果**:截图或保存输出,作为变更前基线 --- ## ⚡ 阶段二:快速优化(今天就可以做,5-10分钟) ### 2.1 优化 EFS 挂载参数 **在一台测试/非关键 EC2 上先试**: ```bash # 1. 查看当前挂载点 df -h | grep efs # 假设挂载在 /mnt/efs # 2. 备份当前 fstab sudo cp /etc/fstab /etc/fstab.backup.$(date +%Y%m%d) # 3. 卸载(确保无进程在使用) sudo lsof | grep /mnt/efs # 检查占用进程 sudo umount /mnt/efs # 4. 使用优化参数重新挂载 sudo mount -t efs -o tls,noresvport,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard \ fs-YOUR_FS_ID:/ /mnt/efs # 5. 验证挂载成功 df -h | grep efs mount | grep efs # 6. 测试应用访问正常 # 执行您的业务检查命令 # 7. 更新 fstab(确保重启后生效) sudo vim /etc/fstab ``` **在 /etc/fstab 中添加/修改为**: ``` fs-YOUR_FS_ID:/ /mnt/efs efs _netdev,noresvport,tls,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard 0 0 ``` **✅ 验证成功后**,在其他 EC2 上重复执行 ### 2.2 设置 CloudWatch 告警(防止再次死机) ```bash # 创建 SNS 主题接收告警 aws sns create-topic --name efs-performance-alerts aws sns subscribe --topic-arn arn:aws:sns:REGION:ACCOUNT:efs-performance-alerts \ --protocol email --notification-endpoint [email protected] # 创建告警:突发积分过低 aws cloudwatch put-metric-alarm \ --alarm-name efs-burst-credits-low \ --alarm-description "EFS突发积分过低" \ --namespace AWS/EFS \ --metric-name BurstCreditBalance \ --dimensions Name=FileSystemId,Value=fs-YOUR_FS_ID \ --statistic Average \ --period 300 \ --evaluation-periods 2 \ --threshold 1000000000000 \ --comparison-operator LessThanThreshold \ --alarm-actions arn:aws:sns:REGION:ACCOUNT:efs-performance-alerts # 创建告警:IO 使用率过高 aws cloudwatch put-metric-alarm \ --alarm-name efs-io-limit-high \ --alarm-description "EFS IO使用率过高" \ --namespace AWS/EFS \ --metric-name PercentIOLimit \ --dimensions Name=FileSystemId,Value=fs-YOUR_FS_ID \ --statistic Average \ --period 300 \ --evaluation-periods 2 \ --threshold 80 \ --comparison-operator GreaterThanThreshold \ --alarm-actions arn:aws:sns:REGION:ACCOUNT:efs-performance-alerts ``` --- ## 🚀 阶段三:切换性能模式(业务低峰期执行) ### 3.1 决策依据 **如果阶段一诊断结果显示**: - BurstCreditBalance < 1TB → **必须切换** - PercentIOLimit 经常 > 80% → **必须切换** - 存储量 < 100GB 但访问频繁 → **必须切换** ### 3.2 推荐方案:切换到 Elastic Throughput **优势**: - ✅ 自动扩展,无需提前规划容量 - ✅ 按实际使用付费,成本可控 - ✅ 彻底解决突发积分耗尽问题 - ✅ 可随时切换回其他模式(24小时后) **执行步骤**: ```bash # 1. 再次确认当前配置 aws efs describe-file-systems --file-system-id fs-YOUR_FS_ID # 2. 执行切换(立即生效,无需停机) aws efs update-file-system \ --file-system-id fs-YOUR_FS_ID \ --throughput-mode elastic # 3. 验证切换成功 aws efs describe-file-systems --file-system-id fs-YOUR_FS_ID | grep ThroughputMode # 应该显示:ThroughputMode: "elastic" # 4. 监控 5-10 分钟 # 观察 CloudWatch 中的 MeteredIOBytes 和 PermittedThroughput ``` ### 3.3 备选方案:Provisioned Throughput(固定成本) **适用于**:希望固定预算、可预测的吞吐量需求 ```bash # 从保守的值开始(50 MB/s) aws efs update-file-system \ --file-system-id fs-YOUR_FS_ID \ --throughput-mode provisioned \ --provisioned-throughput-in-mibps 50 # 后续根据监控逐步调整(每24小时可调整一次) # 如果发现不够: aws efs update-file-system \ --file-system-id fs-YOUR_FS_ID \ --throughput-mode provisioned \ --provisioned-throughput-in-mibps 100 ``` **成本参考**(us-east-1): - 50 MB/s = $6/月 - 100 MB/s = $12/月 - 每增加 1 MB/s = $0.12/月 --- ## 📊 阶段四:验证与监控(变更后24-72小时) ### 4.1 立即验证(变更后10分钟内) ```bash # 1. 确认 EC2 可以正常访问 EFS ls -lh /mnt/efs/ # 2. 执行业务健康检查 # (您的应用特定检查命令) # 3. 观察系统负载 uptime iostat -x 2 5 # 4. 查看 IO wait 是否下降 top -b -n 1 | grep "wa" ``` ### 4.2 持续监控(24-72小时) **在 CloudWatch 控制台观察**: | 指标 | 预期变化 | |------|---------| | `PercentIOLimit` | 应该显著降低(< 50%) | | `BurstCreditBalance` | Elastic模式下不再相关 | | `PermittedThroughput` | 应该自动扩展到满足需求 | **在 EC2 上观察**: ```bash # 每小时检查一次,持续3天 watch -n 3600 'uptime; iostat -x 1 2 | tail -n +4' ``` ### 4.3 成功标准 ✅ **问题解决的标志**: - [ ] IO wait 从 > 50% 降到 < 20% - [ ] Load average 从 > 10 降到正常范围(CPU核心数的1-2倍) - [ ] 72小时内无死机 - [ ] 应用响应时间改善 > 50% --- ## 🔄 回滚方案 ### 如果出现问题(可能性极低) **情况1:切换后性能反而变差**(极罕见) ```bash # 24小时后可以切换回 Bursting aws efs update-file-system \ --file-system-id fs-YOUR_FS_ID \ --throughput-mode bursting ``` **情况2:成本超出预期**(仅限 Elastic/Provisioned) ```bash # 查看当前成本 aws ce get-cost-and-usage \ --time-period Start=2025-10-01,End=2025-10-08 \ --granularity DAILY \ --metrics BlendedCost \ --filter file://efs-filter.json # 如果 Elastic 成本过高,切换到 Provisioned 固定带宽 aws efs update-file-system \ --file-system-id fs-YOUR_FS_ID \ --throughput-mode provisioned \ --provisioned-throughput-in-mibps 50 ``` **情况3:挂载参数导致问题** ```bash # 恢复原始 fstab sudo cp /etc/fstab.backup.YYYYMMDD /etc/fstab sudo umount /mnt/efs sudo mount -a ``` --- ## 💡 长期优化建议 ### 如果以上方案仍不能完全解决 **架构调整方向**: 1. **混合存储架构**(推荐) - 热数据:EBS(高性能) - 冷数据:EFS(共享存储) - 定时同步:cron + rsync 2. **应用层缓存** - Redis/Memcached 缓存频繁读取的数据 - 减少直接访问 EFS 3. **考虑其他 AWS 存储服务** - FSx for Lustre:高性能计算场景 - FSx for OpenZFS:需要更高 IOPS - S3 + 预签名URL:静态文件场景 --- ## 📝 变更检查清单 **变更前**: - [ ] 已完成阶段一诊断,收集基线数据 - [ ] 已在测试机器上验证挂载参数优化 - [ ] 已设置 CloudWatch 告警 - [ ] 已通知相关团队成员 - [ ] 已准备回滚方案 **变更中**: - [ ] 在业务低峰期执行 - [ ] 有人值守监控 - [ ] 逐步验证每个步骤 **变更后**: - [ ] 立即验证业务正常 - [ ] 持续监控24-72小时 - [ ] 记录性能改善数据 - [ ] 更新运维文档 --- ## 📞 紧急联系方式 **如遇问题**: - AWS Support:(您的支持计划) - 团队负责人:[填写] - 待命工程师:[填写] **有用的 AWS 文档**: - EFS 性能:https://docs.aws.amazon.com/efs/latest/ug/performance.html - 吞吐量模式:https://docs.aws.amazon.com/efs/latest/ug/performance.html#throughput-modes --- ## 💰 预估成本变化 **假设当前存储 50GB**: | 模式 | 月成本 | 说明 | |------|--------|------| | Bursting(当前) | $15 | $0.30/GB × 50GB | | Elastic | $15 + $3-10 | 基础存储 + 实际吞吐费用 | | Provisioned 50MB/s | $15 + $6 | 固定成本 | **预计增加**:每月 $3-10(换来系统稳定性,非常值得) --- **最后提醒**: 1. ⏰ 建议在下次业务低峰期(如今晚凌晨)执行阶段二和阶段三 2. 📊 变更后记得持续观察,收集数据证明改善效果 3. 🎯 如果 72 小时后仍有问题,考虑长期架构调整
references
https://docs.aws.amazon.com/zh_cn/efs/latest/ug/whatisefs.html