Efs

来自linuxsa wiki
Evan留言 | 贡献2025年10月7日 (二) 21:00的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转到导航 跳转到搜索

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