EBS, EFS, instance store, FSx và storage hybrid: chọn đúng "ổ đĩa" cho shop-app

5 câu hỏi~45 phútTừ khóa: EBS gp3/io2/st1/sc1, IOPS, throughput, snapshot, DLM, instance store, EFS, mount target, lifecycle IA, FSx, Storage Gateway, Snow Family, DataSync, Transfer Family, SAA: Domain 1 Performance / Domain 4 Cost

Tiếp đi: storage. Tính năng upload hóa đơn PDF của shop-app đang ghi file vào thư mục /opt/shop/uploads trên EC2. Có 2 instance sau ALB nên user upload ở máy A, refresh trang lại rơi vào máy B và không thấy file. Mình có nên gắn chung một ổ EBS cho cả hai máy không?

Câu hỏi rất đúng chỗ, vì đáp án "không gắn chung EBS được" chính là ranh giới giữa ba loại storage của AWS: block (EBS, instance store), file (EFS, FSx) và object (S3, đã học ở 22.6). Bài này giải quyết bài toán của bạn, rồi đi hết nhóm storage còn lại mà đề SAA hỏi rất nhiều: Storage Gateway, Snow Family, DataSync, Transfer Family.

1. Bài toán: file nằm trên đúng một máy

User ──► shop-alb ──┬──► EC2 A  /opt/shop/uploads/inv-1042.pdf   ✔ ghi ở đây
                    └──► EC2 B  /opt/shop/uploads/                ✘ refresh rơi vào đây → 404

Thêm rắc rối:
  - ASG scale in → terminate A → file mất luôn
  - Deploy bản mới (instance refresh) → mọi upload mất
  - Backup? không ai làm

2. Vấn đề

3. Giải pháp: hiểu 3 loại storage và chọn đúng

LoạiDịch vụTruy cập từPhạm viDùng cho
BlockEBS, instance store1 EC2 (Multi-Attach io1/io2 ngoại lệ)1 AZRoot volume, database tự cài, file hệ thống, cache cục bộ
File (NFS/SMB)EFS (Linux, NFSv4), FSx (Windows SMB / Lustre / NetApp ONTAP / OpenZFS)Nhiều EC2, ECS, Lambda, on-prem qua VPN/DXRegion (EFS multi-AZ)Thư mục chia sẻ, content management, home directory, HPC
Object (HTTP API)S3, GlacierBất kỳ, qua SDK/HTTPRegion (global namespace)Ảnh, backup, log, data lake, static website

Cho shop-app: về lâu dài hóa đơn nên vào S3 (rẻ nhất, bền nhất, không cần mount). Nhưng nếu muốn giữ code ghi file như cũ và chạy được ngay, EFS là câu trả lời đúng của đề thi: mount cùng một filesystem lên cả 2 instance ở 2 AZ, scale tự động, pay-per-GB. Bài này lab với EFS, và cuối bài sẽ nói khi nào đổi sang S3.

Thuật ngữ EBS cần nắm chắc (xuất hiện ở hầu hết đề về EC2):

Volume typeLoạiIOPS / throughputDùng khiBoot volume?
gp3SSD3,000 IOPS + 125 MB/s baseline bất kể dung lượng; mua thêm tới 16,000 IOPS / 1,000 MB/s độc lập với sizeMặc định cho mọi thứ: root, app, DB nhỏ-trungCó
gp2SSD3 IOPS/GB (burst 3,000), tối đa 16,000; muốn IOPS phải mua GBThế hệ cũ; đề thi: "migrate gp2 → gp3 để tiết kiệm ~20%"Có
io2 Block ExpressSSDTới 256,000 IOPS, 4,000 MB/s, độ bền 99.999%, latency sub-msDatabase I/O nặng (Oracle, SAP, SQL Server), cần >16,000 IOPS, Multi-AttachCó
io1SSDTới 64,000 IOPS (Nitro)Thế hệ trước io2Có
st1HDDThroughput-optimized: tới 500 MB/s, tính theo MB/s/TBBig data, log processing, data warehouse, đọc tuần tự lớnKhông
sc1HDDCold: tới 250 MB/s, rẻ nhấtDữ liệu ít truy cập, lưu trữ rẻ mà vẫn cần blockKhông
Cách chọn trong 5 giây:
  Cần IOPS cao (random, DB)      → SSD: gp3 (≤16k IOPS) → io2 (>16k, sub-ms, 99.999%)
  Cần throughput (sequential, log, big data) → HDD: st1 (nóng) / sc1 (lạnh)
  Boot volume                    → chỉ SSD
  "cost-effective" + "general"   → gp3
  "mission-critical database"    → io2
  Dữ liệu tạm, nhanh nhất, chấp nhận mất → instance store

Instance store: ổ NVMe/SSD gắn vật lý trên host (tên instance có chữ d: i3, m5d, c6gd). Nhanh hơn EBS (hàng triệu IOPS), miễn phí theo instance, nhưng ephemeral: stop, terminate hoặc hỏng host là mất hết (reboot thì giữ). Dùng cho buffer, cache, temp của Spark, replica của DB tự replicate (Cassandra, Kafka broker). Không snapshot được, không detach được.

EFS thuật ngữ:

Thuật ngữNghĩa
Mount targetENI trong mỗi AZ/subnet, có IP; EC2 trong AZ đó mount qua NFS 2049. Cần SG cho phép 2049 từ app SG.
Regional vs One ZoneRegional: dữ liệu ở nhiều AZ, 99.999999999% durability. One Zone: 1 AZ, rẻ ~47%, cho dev/dữ liệu tái tạo được.
Storage class & lifecycleStandard → Infrequent Access (IA) sau 7/14/30/60/90 ngày không đọc → Archive. IA rẻ ~90% nhưng tính phí mỗi lần đọc. "Intelligent-Tiering" đưa file quay lại Standard khi được đọc.
Performance modeGeneral Purpose (mặc định, latency thấp) vs Max I/O (parallel cao, latency cao hơn; chỉ còn cho một số trường hợp).
Throughput modeElastic (mặc định, trả theo lượng đọc/ghi, không cần đoán) · Bursting (tỉ lệ với GB lưu, có burst credit) · Provisioned (đặt MB/s cố định, trả tiền dù không dùng).
Access pointEntry point với POSIX uid/gid và root directory riêng cho từng app → nhiều app chia một filesystem an toàn (Lambda, ECS hay dùng).
EFS mount helper / amazon-efs-utilsMount với TLS (encryption in transit) và IAM authorization, retry tự động.
EncryptionAt rest bằng KMS lúc tạo (không đổi sau), in transit bằng TLS khi mount với -o tls.

4. Cấu hình từng bước

Bước 1: SG cho EFS. Tạo shop-efs-sg chỉ nhận NFS 2049 từ shop-app-sg:

EFS_SG=$(aws ec2 create-security-group --profile shop-lab --group-name shop-efs-sg \
  --description "NFS from shop-app" --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=security-group,Tags=[{Key=Project,Value=shop-app},{Key=Env,Value=lab}]' \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --profile shop-lab --group-id $EFS_SG \
  --protocol tcp --port 2049 --source-group $APP_SG

Bước 2: Tạo filesystem và mount target ở 2 private subnet.

FS_ID=$(aws efs create-file-system --profile shop-lab --creation-token shop-efs \
  --performance-mode generalPurpose --throughput-mode elastic --encrypted \
  --tags Key=Name,Value=shop-efs Key=Project,Value=shop-app Key=Env,Value=lab \
  --query FileSystemId --output text)
aws efs create-mount-target --profile shop-lab --file-system-id $FS_ID --subnet-id $PRIV_A --security-groups $EFS_SG
aws efs create-mount-target --profile shop-lab --file-system-id $FS_ID --subnet-id $PRIV_B --security-groups $EFS_SG
aws efs put-lifecycle-configuration --profile shop-lab --file-system-id $FS_ID \
  --lifecycle-policies '[{"TransitionToIA":"AFTER_30_DAYS"},{"TransitionToPrimaryStorageClass":"AFTER_1_ACCESS"}]'

Bước 3: Mount trên EC2 (user data của shop-lt). DNS fs-xxx.efs.ap-southeast-1.amazonaws.com tự trả về IP mount target trong AZ của instance (cần VPC bật DNS hostnames/resolution).

dnf install -y amazon-efs-utils
mkdir -p /opt/shop/uploads
echo "fs-0123456789abcdef0:/ /opt/shop/uploads efs _netdev,tls,iam,noresvport 0 0" >> /etc/fstab
mount -a
chown ec2-user:ec2-user /opt/shop/uploads

tls mã hóa đường truyền; iam dùng role EC2 để xác thực (cần filesystem policy cho phép elasticfilesystem:ClientMount/ClientWrite cho shop-app-ec2-role); _netdev để boot không treo nếu mạng chưa lên.

Bước 4: Code Java không đổi. Spring Boot vẫn ghi file như trước:

@Service
public class InvoiceStorage {
    private final Path root = Path.of(System.getenv().getOrDefault("UPLOAD_DIR", "/opt/shop/uploads"));

    public Path save(long orderId, byte[] pdf) throws IOException {
        Path dir = root.resolve(LocalDate.now().toString());   // chia thư mục theo ngày: EFS list nhanh hơn
        Files.createDirectories(dir);
        Path file = dir.resolve("inv-" + orderId + ".pdf");
        Files.write(file, pdf, StandardOpenOption.CREATE_NEW);  // CREATE_NEW: hai instance không ghi đè nhau
        return file;
    }
}

Hai lưu ý khi app Java chạy trên NFS: (1) FileChannel.lock() hoạt động trên EFS (NFSv4 lock) nhưng chậm, tránh dùng làm distributed lock, dùng Redis (7.5); (2) metadata operation (list, stat, open) có latency vài ms, nên tránh thư mục hàng trăm nghìn file phẳng, chia theo ngày/prefix.

Bước 5: EBS cho app và DB tự cài: gp3 đúng kích cỡ. Volume root của shop-lt nên là gp3, encrypted, và bật DeleteOnTermination:

"BlockDeviceMappings": [{
  "DeviceName": "/dev/xvda",
  "Ebs": { "VolumeType": "gp3", "VolumeSize": 20, "Iops": 3000, "Throughput": 125,
           "Encrypted": true, "KmsKeyId": "alias/shop-key", "DeleteOnTermination": true }
}]

Nếu có volume data riêng (ví dụ Kafka broker tự dựng), Elastic Volumes cho phép tăng size/IOPS/đổi type online không detach: aws ec2 modify-volume --volume-id vol-x --size 200 --volume-type gp3 --iops 6000, rồi growpart + xfs_growfs trong OS. Chỉ tăng, không giảm size được.

Bước 6: Snapshot và Data Lifecycle Manager (DLM). Snapshot EBS là incremental (chỉ block thay đổi), lưu trên S3 (ẩn), có thể copy sang region/account khác, tạo AMI từ snapshot. Tự động hóa bằng DLM:

aws dlm create-lifecycle-policy --profile shop-lab \
  --description "Daily snapshot of shop-app data volumes" --state ENABLED \
  --execution-role-arn arn:aws:iam::$ACCOUNT_ID:role/service-role/AWSDataLifecycleManagerDefaultRole \
  --policy-details '{
    "PolicyType": "EBS_SNAPSHOT_MANAGEMENT", "ResourceTypes": ["VOLUME"],
    "TargetTags": [{"Key": "Project", "Value": "shop-app"}],
    "Schedules": [{ "Name": "daily", "CreateRule": {"Interval": 24, "IntervalUnit": "HOURS", "Times": ["18:00"]},
                    "RetainRule": {"Count": 7}, "CopyTags": true }]
  }'

Thuật ngữ: Fast Snapshot Restore (volume tạo từ snapshot đạt hiệu năng ngay, không "lazy load"; tốn tiền theo giờ/AZ), Snapshot Archive (rẻ ~75%, restore 24–72 giờ), Recycle Bin (giữ snapshot bị xóa nhầm), EBS snapshot lock (WORM cho compliance). Ở bài 22.18 ta dùng AWS Backup làm thay DLM cho cả EBS, RDS, EFS, DynamoDB.

5. Cách hoạt động

                       shop-vpc 10.0.0.0/16
 ┌─────────────────────────────────────┬─────────────────────────────────────┐
 │ AZ ap-southeast-1a                  │ AZ ap-southeast-1b                  │
 │  shop-private-a 10.0.11.0/24        │  shop-private-b 10.0.12.0/24        │
 │  ┌──────────────┐                   │  ┌──────────────┐                   │
 │  │ EC2 A        │ EBS gp3 root (1a) │  │ EC2 B        │ EBS gp3 root (1b) │
 │  │ shop-app.jar │ ◄── block, chỉ A  │  │ shop-app.jar │ ◄── block, chỉ B  │
 │  │ /opt/shop/   │                   │  │ /opt/shop/   │                   │
 │  │  uploads ────┼── NFS 2049 ──┐    │  │  uploads ────┼── NFS 2049 ──┐    │
 │  └──────────────┘              ▼    │  └──────────────┘              ▼    │
 │                   mount target 1a   │                   mount target 1b   │
 │                   10.0.11.250 (ENI) │                   10.0.12.250 (ENI) │
 └───────────────────────────┬─────────┴──────────────────────────┬──────────┘
                             └──────────── EFS fs-0123 (Regional) ┘
                                   dữ liệu sao chép qua nhiều AZ, 1 namespace
                                   Standard ──30 ngày không đọc──► IA ──► Archive

 S3 shop-app-assets (object, HTTP)  ◄── SDK PutObject ── ảnh sản phẩm, (sau này) hóa đơn
 Snapshot EBS (incremental) ──► lưu trong S3 nội bộ ──► copy region khác / tạo AMI

Vòng đời một request upload sau khi có EFS: user POST hóa đơn → ALB → EC2 A ghi /opt/shop/uploads/2026-10-21/inv-1042.pdf → NFS client gửi tới mount target 1a → EFS lưu đa AZ → user refresh rơi vào EC2 B → B đọc cùng path qua mount target 1b → thấy file ngay (EFS là strong consistency cho close-to-open).

6. So sánh kiểu đề thi

Tiêu chíEBSInstance storeEFSS3
KiểuBlockBlock (local)File (NFS)Object
Gắn vào1 EC2 cùng AZ (Multi-Attach io1/io2 ngoại lệ)Chính instance đóHàng nghìn EC2/ECS/Lambda, nhiều AZ, on-premKhông gắn, gọi API
Bền khi instance chếtCó (trừ DeleteOnTermination root)KhôngCóCó
Latencysub-ms → msµs, nhanh nhấtms (NFS)Hàng chục ms, HTTP
Scale dung lượngProvision trước, tăng onlineCố định theo instance typeTự động, pay-per-useKhông giới hạn
Giá tương đối / GBTrung bìnhGộp trong giá instanceCao (Standard ~3× EBS gp3), IA rẻThấp nhất
BackupSnapshot, DLM, AWS BackupTự copy ra ngoàiAWS BackupVersioning, replication
Windows?CóCóKhông (dùng FSx for Windows)Có (SDK)

Nhóm FSx – đề thi phân biệt bằng từ khóa:

FSx for…Từ khóa đề
Windows File ServerSMB, Active Directory, NTFS ACL, DFS namespace, Windows app cần shared drive
LustreHPC, machine learning, "hundreds of GB/s", "sub-millisecond", liên kết với S3 (lazy load từ S3, ghi ngược về S3), scratch vs persistent
NetApp ONTAPMulti-protocol NFS + SMB + iSCSI, snapshot/clone tức thì, dedup/compression, migrate từ NetApp on-prem, SnapMirror
OpenZFSNFS, ZFS snapshot/clone, migrate từ ZFS on-prem, latency thấp

Hybrid & di chuyển dữ liệu – bảng này là "điểm cộng dễ nhất" của bài thi, hầu như chỉ cần nhớ từ khóa:

Dịch vụLàm gìTừ khóa đềKhông phải cho
Storage Gateway – S3 File GatewayOn-prem mount NFS/SMB, dữ liệu lưu thành object trong S3, cache cục bộ file mới dùng"on-premises application needs NFS/SMB access to S3", "extend storage to cloud", "cache frequently accessed"Block device cho server
Storage Gateway – Volume GatewayiSCSI block. Cached: dữ liệu chính ở S3, cache on-prem. Stored: dữ liệu chính on-prem, snapshot async lên S3 (EBS snapshot)"iSCSI", "low-latency access to entire dataset" → Stored; "primary data in AWS, frequently accessed cached" → Cached; "backup on-prem volumes as EBS snapshots"Chia sẻ file đa máy
Storage Gateway – Tape GatewayVirtual tape library (VTL) iSCSI cho phần mềm backup (Veeam, NetBackup), lưu S3/Glacier"replace physical tape", "existing backup software", "VTL"Truy cập file hàng ngày
FSx File GatewayCache on-prem cho FSx for Windows"low latency access from branch office to FSx Windows"—
Snowcone / Snowball Edge / (Snowmobile đã ngừng)Thiết bị vật lý chuyển dữ liệu offline; Snowball Edge Storage Optimized ~80–210 TB usable, Compute Optimized chạy EC2/Lambda tại edge"petabytes", "limited/no network", "would take weeks over internet", "edge computing in remote location", "import to S3/Glacier"Đồng bộ liên tục (dùng DataSync). Snowball vào Glacier phải qua S3 + lifecycle, không ghi thẳng Glacier
DataSyncAgent copy dữ liệu NFS/SMB/HDFS/S3 ↔ S3/EFS/FSx qua mạng, nhanh (tối ưu TCP), có schedule, giữ metadata/permission, verify"migrate NFS share to EFS", "one-time or scheduled transfer", "preserve file permissions/metadata", "10× faster than open-source", DataSync cũng chạy được giữa AWS storage (EFS→EFS khác region)Truy cập thường xuyên kiểu gateway; dữ liệu qua database (dùng DMS)
Transfer FamilyManaged SFTP/FTPS/FTP/AS2 endpoint, file rơi vào S3 hoặc EFS, auth qua Directory/Cognito/custom Lambda"partners upload via SFTP", "existing SFTP clients", "no code change", "managed FTP server"Chuyển dữ liệu lớn nội bộ
S3 Transfer AccelerationUpload tới S3 qua CloudFront edge, tối ưu đường dài"users worldwide upload to a single bucket", "long distance"Dữ liệu trong cùng region
Direct Connect / VPNĐường truyền, không phải dịch vụ storage; DX cho throughput ổn định, VPN nhanh dựng"consistent network performance", "dedicated connection", "private connectivity"—
Cây quyết định di chuyển dữ liệu on-prem → AWS:
  Có mạng đủ? (quy tắc: 10 TB qua 100 Mbps ≈ 10 ngày)
    ├─ Không / quá lâu / không có mạng       → Snowball Edge (nhiều TB–PB), Snowcone (vài TB, nhỏ gọn)
    └─ Có
        ├─ Copy file một lần / định kỳ        → DataSync
        ├─ Vẫn giữ app on-prem, cần truy cập liên tục → Storage Gateway (File / Volume / Tape)
        ├─ Đối tác gửi file bằng SFTP         → Transfer Family
        └─ Database                           → DMS (bài 22.18)

7. Khi nào dùng / không dùng

Team bên cạnh tự cài PostgreSQL trên EC2 t3.medium với EBS gp3 500 GB. Họ mua thêm lên 10,000 IOPS mà giờ cao điểm vẫn chậm, iostat thấy %util gần 100. Có phải cứ mua IOPS là xong không?

Chưa đúng, và đây là bẫy mà cả đề thi lẫn thực tế hay đặt: IOPS của volume chỉ là một trong hai nắp. Nắp thứ hai là EBS bandwidth của instance. Mỗi instance type có giới hạn IOPS và MB/s riêng với EBS; t3.medium chỉ đạt vài nghìn IOPS khi burst, baseline thấp hơn nhiều. Volume 10,000 IOPS gắn vào instance có nắp ~2,000 IOPS thì vẫn chỉ được ~2,000.

1. Hai nắp

Ứng dụng ──► OS ──► [nắp 1: instance EBS bandwidth]  ──► [nắp 2: volume IOPS/throughput] ──► EBS
                         t3.medium: thấp, có burst            gp3: 3,000 baseline, mua tới 16,000
                         m6i.large: ~10k IOPS, 650 MB/s       io2: tới 256,000
                         r6i.4xlarge: ~40k IOPS, 1,250 MB/s
Hiệu năng thực = min(nắp 1, nắp 2)

Kiểm tra bằng CloudWatch (22.15): metric EBSIOBalance% và EBSByteBalance% của instance (chỉ có với instance có burst); về 0 là nắp 1 đang chặn. Metric VolumeQueueLength của volume cao mà VolumeReadOps không tăng cũng là dấu hiệu nắp instance.

2. Cách sửa theo thứ tự rẻ → đắt

  1. Đổi instance type có nắp EBS cao hơn (m6i, r6i; hoặc thêm hậu tố EBS-optimized đã mặc định với Nitro). Đề thi: "EBS-optimized instance" là câu trả lời cho "volume IOPS đủ nhưng vẫn chậm".
  2. Kiểm tra I/O size: IOPS tính theo I/O 16 KiB (SSD) / 1 MiB (HDD). PostgreSQL ghi page 8 KB nhưng checkpoint ghi lớn; nếu throughput MB/s mới là nút thắt thì tăng Throughput của gp3 (tối đa 1,000 MB/s), không phải IOPS.
  3. RAID 0 nhiều volume (gộp IOPS) khi cần > 16k với gp3; RAID 1 thì không cần vì EBS đã replicate trong AZ.
  4. io2 Block Express nếu cần > 64k IOPS hoặc latency ổn định sub-ms.
  5. Và câu hỏi lớn: vì sao tự cài Postgres? RDS (22.7) đã lo storage autoscaling, Multi-AZ, backup; Aurora còn tách storage khỏi compute hoàn toàn.

3. Hiểu "burst" của t3 và gp2

t3 có CPU credit; gp2 có I/O credit (volume < 1 TB burst lên 3,000 IOPS rồi hết credit tụt về 3 IOPS/GB). Hai bể credit này cạn đúng vào giờ cao điểm, vì vậy "chạy ngon buổi sáng, chậm buổi chiều" là chữ ký của burst. gp3 bỏ cơ chế credit nên ổn định hơn, một lý do nữa để migrate gp2 → gp3 (rẻ hơn ~20% và tách IOPS khỏi dung lượng).

Mình bật EFS lifecycle chuyển sang IA sau 7 ngày để tiết kiệm, dung lượng chỉ 40 GB mà hóa đơn tháng lại tăng. Mình hiểu sai chỗ nào về cách EFS tính tiền?

Bạn hiểu đúng một nửa: IA rẻ hơn Standard rất nhiều về tiền lưu trữ, nhưng IA có thêm phí truy cập theo GB đọc/ghi. Với 7 ngày, file hóa đơn của shop-app bị đẩy sang IA rồi khách hàng (hay báo cáo cuối tháng) đọc lại, mỗi lần đọc đều tốn phí. Nếu dữ liệu được đọc đi đọc lại, IA thành đắt hơn Standard.

1. Bốn khoản trong hóa đơn EFS

KhoảnTính theoGhi chú
Storage StandardGB-thángĐắt nhất về lưu, không phí truy cập
Storage IA / ArchiveGB-thángRẻ ~90–95%, cộng phí mỗi GB đọc/ghi
ThroughputElastic: GB đọc/ghi thật · Provisioned: MB/s cấu hình × giờ, dù không dùngProvisioned quên không hạ là nguyên nhân hóa đơn cao số 1
Replication, backupGBNếu bật EFS Replication hoặc AWS Backup

2. Cách chọn lifecycle đúng

3. Nguyên tắc chi phí chung cho cả storage AWS

Giá lưu trữ giảm theo bậc: EBS io2 > EBS gp3 ≈ EFS Standard > EFS IA > S3 Standard > S3 IA > Glacier
Giá truy cập tăng ngược lại: lớp càng rẻ, đọc càng đắt / càng chậm
→ "Dữ liệu đọc thường xuyên để lớp đắt, dữ liệu để yên để lớp rẻ" đúng cho EFS lẫn S3.

Đề thi hay hỏi câu "EFS costs increased after enabling lifecycle" với đáp án là "files in IA are accessed frequently; increase the transition period / enable Intelligent-Tiering".

Cho mình bài lab để tự tay làm phần này nhé.

Lab 22.16: EFS dùng chung cho 2 AZ, đo EBS gp3, snapshot và instance store

Mục tiêu

Chi phí & thời gian

Chuẩn bị

export AWS_REGION=ap-southeast-1
export ACCOUNT_ID=$(aws sts get-caller-identity --profile shop-lab --query Account --output text)
export VPC_ID=$(aws ec2 describe-vpcs --profile shop-lab --filters Name=tag:Name,Values=shop-vpc --query 'Vpcs[0].VpcId' --output text)
export PRIV_A=$(aws ec2 describe-subnets --profile shop-lab --filters Name=tag:Name,Values=shop-private-a --query 'Subnets[0].SubnetId' --output text)
export PRIV_B=$(aws ec2 describe-subnets --profile shop-lab --filters Name=tag:Name,Values=shop-private-b --query 'Subnets[0].SubnetId' --output text)
export APP_SG=$(aws ec2 describe-security-groups --profile shop-lab --filters Name=group-name,Values=shop-app-sg --query 'SecurityGroups[0].GroupId' --output text)
export AMI=$(aws ssm get-parameter --profile shop-lab --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 --query Parameter.Value --output text)
export TAGS='{Key=Project,Value=shop-app},{Key=Env,Value=lab}'

Các bước

Bước 1: SG cho EFS.

EFS_SG=$(aws ec2 create-security-group --profile shop-lab --group-name shop-efs-sg \
  --description "NFS 2049 from shop-app-sg" --vpc-id $VPC_ID \
  --tag-specifications "ResourceType=security-group,Tags=[$TAGS,{Key=Name,Value=shop-efs-sg}]" \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --profile shop-lab --group-id $EFS_SG \
  --protocol tcp --port 2049 --source-group $APP_SG

Console: VPC → Security Groups → Create → Inbound rule NFS, Source = shop-app-sg.

Bước 2: Tạo EFS + 2 mount target + lifecycle + filesystem policy (bắt buộc TLS, cho phép role EC2).

FS_ID=$(aws efs create-file-system --profile shop-lab --creation-token shop-efs-$RANDOM \
  --performance-mode generalPurpose --throughput-mode elastic --encrypted \
  --tags Key=Name,Value=shop-efs Key=Project,Value=shop-app Key=Env,Value=lab \
  --query FileSystemId --output text); echo $FS_ID
# chờ trạng thái available
aws efs describe-file-systems --profile shop-lab --file-system-id $FS_ID --query 'FileSystems[0].LifeCycleState'
aws efs create-mount-target --profile shop-lab --file-system-id $FS_ID --subnet-id $PRIV_A --security-groups $EFS_SG
aws efs create-mount-target --profile shop-lab --file-system-id $FS_ID --subnet-id $PRIV_B --security-groups $EFS_SG
aws efs put-lifecycle-configuration --profile shop-lab --file-system-id $FS_ID \
  --lifecycle-policies '[{"TransitionToIA":"AFTER_30_DAYS"},{"TransitionToPrimaryStorageClass":"AFTER_1_ACCESS"}]'
cat > efs-policy.json <<EOF
{ "Version": "2012-10-17", "Statement": [
  { "Sid": "AllowShopApp", "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::$ACCOUNT_ID:role/shop-app-ec2-role" },
    "Action": ["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite"],
    "Resource": "arn:aws:elasticfilesystem:$AWS_REGION:$ACCOUNT_ID:file-system/$FS_ID" },
  { "Sid": "DenyNoTLS", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": "*",
    "Resource": "arn:aws:elasticfilesystem:$AWS_REGION:$ACCOUNT_ID:file-system/$FS_ID",
    "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }
EOF
aws efs put-file-system-policy --profile shop-lab --file-system-id $FS_ID --policy file://efs-policy.json

Console: EFS → Create file system → Customize: Regional, Elastic, encrypted; Network: chọn 2 private subnet + shop-efs-sg; sau đó tab File system policy.

Bước 3: Chạy 2 EC2 ở 2 AZ với user data mount EFS.

cat > ud-efs.sh <<EOF
#!/bin/bash
dnf install -y amazon-efs-utils fio
mkdir -p /opt/shop/uploads
echo "$FS_ID:/ /opt/shop/uploads efs _netdev,tls,iam,noresvport 0 0" >> /etc/fstab
for i in 1 2 3 4 5; do mount -a && break; sleep 10; done   # chờ mount target available
chown ec2-user:ec2-user /opt/shop/uploads
EOF
for AZ in a b; do
  SUBNET_VAR=PRIV_$(echo $AZ | tr a-z A-Z); SUBNET=${!SUBNET_VAR}
  aws ec2 run-instances --profile shop-lab --image-id $AMI --instance-type t3.micro \
    --subnet-id $SUBNET --security-group-ids $APP_SG \
    --iam-instance-profile Name=shop-app-ec2-role \
    --user-data file://ud-efs.sh \
    --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeType":"gp3","VolumeSize":10,"Encrypted":true,"DeleteOnTermination":true}}]' \
    --tag-specifications "ResourceType=instance,Tags=[$TAGS,{Key=Name,Value=shop-efs-test-$AZ}]" \
                         "ResourceType=volume,Tags=[$TAGS]" \
    --query 'Instances[0].InstanceId' --output text
done
# lưu id
INST_A=$(aws ec2 describe-instances --profile shop-lab --filters Name=tag:Name,Values=shop-efs-test-a Name=instance-state-name,Values=pending,running --query 'Reservations[0].Instances[0].InstanceId' --output text)
INST_B=$(aws ec2 describe-instances --profile shop-lab --filters Name=tag:Name,Values=shop-efs-test-b Name=instance-state-name,Values=pending,running --query 'Reservations[0].Instances[0].InstanceId' --output text)

Console: EC2 → Launch instance → Advanced details → IAM instance profile, User data. (Console còn có tab "File systems" tự sinh script mount EFS.)

Bước 4: Ghi từ A, đọc từ B qua SSM Run Command (không cần SSH).

run() { aws ssm send-command --profile shop-lab --instance-ids $1 --document-name AWS-RunShellScript \
  --parameters "commands=[\"$2\"]" --query Command.CommandId --output text; }
show() { sleep 4; aws ssm get-command-invocation --profile shop-lab --command-id $1 --instance-id $2 --query StandardOutputContent --output text; }

CMD=$(run $INST_A "df -hT /opt/shop/uploads; echo hello-from-a-\$(hostname) > /opt/shop/uploads/inv-1042.txt; ls -l /opt/shop/uploads")
show $CMD $INST_A
CMD=$(run $INST_B "cat /opt/shop/uploads/inv-1042.txt")
show $CMD $INST_B
# → hello-from-a-ip-10-0-11-xx   (đọc được ngay từ AZ 1b)

Console: Systems Manager → Run Command → AWS-RunShellScript; hoặc EC2 → Connect → Session Manager.

Bước 5: Volume gp3 riêng, gắn vào A, format xfs, đo bằng fio.

VOL=$(aws ec2 create-volume --profile shop-lab --availability-zone ${AWS_REGION}a --size 20 \
  --volume-type gp3 --iops 3000 --throughput 125 --encrypted \
  --tag-specifications "ResourceType=volume,Tags=[$TAGS,{Key=Name,Value=shop-data}]" \
  --query VolumeId --output text)
aws ec2 wait volume-available --profile shop-lab --volume-ids $VOL
aws ec2 attach-volume --profile shop-lab --volume-id $VOL --instance-id $INST_A --device /dev/sdf
# Trên Nitro, /dev/sdf xuất hiện là /dev/nvme1n1
CMD=$(run $INST_A "lsblk; mkfs.xfs /dev/nvme1n1 && mkdir -p /data && mount /dev/nvme1n1 /data && df -h /data")
show $CMD $INST_A
# Đo random read 4k, 60 giây (sẽ thấy ~3000 IOPS nếu nắp instance không chặn)
CMD=$(run $INST_A "fio --name=randread --filename=/data/fio.bin --size=2G --rw=randread --bs=4k --iodepth=32 --direct=1 --runtime=60 --time_based --ioengine=libaio | grep -E 'IOPS|lat \\(usec\\)' | head -3")
show $CMD $INST_A

Console: EC2 → Volumes → Create volume (chú ý AZ phải trùng instance) → Actions → Attach volume.

Bước 6: Tăng size online 20 → 30 GB (Elastic Volumes).

aws ec2 modify-volume --profile shop-lab --volume-id $VOL --size 30
aws ec2 describe-volumes-modifications --profile shop-lab --volume-ids $VOL --query 'VolumesModifications[0].ModificationState'
# khi "optimizing" hoặc "completed" là filesystem có thể grow
CMD=$(run $INST_A "xfs_growfs /data && df -h /data")
show $CMD $INST_A      # 30G

Console: Volumes → Actions → Modify volume. Lưu ý: sau một lần modify phải chờ 6 giờ mới modify tiếp.

Bước 7: Snapshot → volume mới ở AZ 1b → gắn vào B.

CMD=$(run $INST_A "echo snapshot-test > /data/marker.txt; sync"); show $CMD $INST_A
SNAP=$(aws ec2 create-snapshot --profile shop-lab --volume-id $VOL --description "shop-data lab" \
  --tag-specifications "ResourceType=snapshot,Tags=[$TAGS]" --query SnapshotId --output text)
aws ec2 wait snapshot-completed --profile shop-lab --snapshot-ids $SNAP
VOL_B=$(aws ec2 create-volume --profile shop-lab --availability-zone ${AWS_REGION}b --snapshot-id $SNAP \
  --volume-type gp3 --tag-specifications "ResourceType=volume,Tags=[$TAGS,{Key=Name,Value=shop-data-b}]" \
  --query VolumeId --output text)
aws ec2 wait volume-available --profile shop-lab --volume-ids $VOL_B
aws ec2 attach-volume --profile shop-lab --volume-id $VOL_B --instance-id $INST_B --device /dev/sdf
CMD=$(run $INST_B "mkdir -p /data && mount /dev/nvme1n1 /data && cat /data/marker.txt"); show $CMD $INST_B
# → snapshot-test   (dữ liệu đi từ AZ 1a sang 1b qua snapshot; EBS trực tiếp không qua được AZ)

Console: Volumes → Actions → Create snapshot; Snapshots → Actions → Create volume from snapshot (chọn AZ b).

Bước 8 (tùy chọn, ngoài Free Tier): instance store.

INST_D=$(aws ec2 run-instances --profile shop-lab --image-id $AMI --instance-type m5d.large \
  --subnet-id $PRIV_A --security-group-ids $APP_SG --iam-instance-profile Name=shop-app-ec2-role \
  --tag-specifications "ResourceType=instance,Tags=[$TAGS,{Key=Name,Value=shop-istore-test}]" \
  --query 'Instances[0].InstanceId' --output text)
aws ec2 wait instance-status-ok --profile shop-lab --instance-ids $INST_D
CMD=$(run $INST_D "lsblk -o NAME,SIZE,MODEL; mkfs.xfs /dev/nvme1n1 && mkdir -p /scratch && mount /dev/nvme1n1 /scratch && echo temp > /scratch/x && fio --name=t --filename=/scratch/fio.bin --size=2G --rw=randread --bs=4k --iodepth=32 --direct=1 --runtime=20 --time_based --ioengine=libaio | grep IOPS")
show $CMD $INST_D      # IOPS cao hơn gp3 nhiều lần
aws ec2 stop-instances --profile shop-lab --instance-ids $INST_D && aws ec2 wait instance-stopped --profile shop-lab --instance-ids $INST_D
aws ec2 start-instances --profile shop-lab --instance-ids $INST_D && aws ec2 wait instance-status-ok --profile shop-lab --instance-ids $INST_D
CMD=$(run $INST_D "lsblk -f /dev/nvme1n1; mount /dev/nvme1n1 /scratch 2>&1 | head -1"); show $CMD $INST_D
# → không còn filesystem: dữ liệu instance store mất sau stop/start
aws ec2 terminate-instances --profile shop-lab --instance-ids $INST_D

Kiểm tra kết quả

# EFS: 2 mount target available, 2 instance đang mount
aws efs describe-mount-targets --profile shop-lab --file-system-id $FS_ID --query 'MountTargets[].[AvailabilityZoneName,IpAddress,LifeCycleState]' --output table
CMD=$(run $INST_B "ls -l /opt/shop/uploads; mount | grep efs"); show $CMD $INST_B

# EFS metric: có byte được ghi
aws cloudwatch get-metric-statistics --profile shop-lab --namespace AWS/EFS --metric-name DataWriteIOBytes \
  --dimensions Name=FileSystemId,Value=$FS_ID --statistics Sum --period 300 \
  --start-time $(date -u -d '30 min ago' +%FT%TZ) --end-time $(date -u +%FT%TZ)

# EBS: volume 30 GB gp3 attached, snapshot completed
aws ec2 describe-volumes --profile shop-lab --volume-ids $VOL $VOL_B --query 'Volumes[].[VolumeId,Size,VolumeType,Iops,State,Attachments[0].InstanceId]' --output table
aws ec2 describe-snapshots --profile shop-lab --snapshot-ids $SNAP --query 'Snapshots[0].[State,Progress,VolumeSize]'

Kết quả mong đợi: file ghi ở A đọc được ở B trong < 1 giây; fio gp3 báo khoảng 3,000 IOPS (có thể thấp hơn nếu t3.micro bị nắp instance – đây chính là bài học ở câu hỏi phụ); volume từ snapshot ở AZ b có file marker.

Thử thêm

Dọn tài nguyên

# 1. Instance (volume root DeleteOnTermination)
aws ec2 terminate-instances --profile shop-lab --instance-ids $INST_A $INST_B
aws ec2 wait instance-terminated --profile shop-lab --instance-ids $INST_A $INST_B
# 2. Volume data (detach xong khi instance terminated) và snapshot
aws ec2 delete-volume --profile shop-lab --volume-id $VOL
aws ec2 delete-volume --profile shop-lab --volume-id $VOL_B
aws ec2 delete-snapshot --profile shop-lab --snapshot-id $SNAP
# 3. EFS: phải xóa mount target trước, chờ deleted, rồi xóa filesystem
for MT in $(aws efs describe-mount-targets --profile shop-lab --file-system-id $FS_ID --query 'MountTargets[].MountTargetId' --output text); do
  aws efs delete-mount-target --profile shop-lab --mount-target-id $MT; done
sleep 60
aws efs delete-file-system --profile shop-lab --file-system-id $FS_ID
# 4. SG EFS (sau khi ENI mount target biến mất)
aws ec2 delete-security-group --profile shop-lab --group-id $EFS_SG
# 5. Kiểm tra không còn volume/snapshot gắn tag lab
aws ec2 describe-volumes --profile shop-lab --filters Name=tag:Env,Values=lab --query 'Volumes[].VolumeId'
aws ec2 describe-snapshots --profile shop-lab --owner-ids self --filters Name=tag:Env,Values=lab --query 'Snapshots[].SnapshotId'

Nhắc: volume EBS không gắn vào instance vẫn tính tiền theo GB-tháng, snapshot cũng vậy; EFS Provisioned throughput (nếu bạn đổi mode để thử) tính tiền dù không dùng; instance m5d không trong Free Tier.

Phỏng vấn và đề thi SAA hỏi về EBS, EFS và storage hybrid thì sao?

Q1. EBS, EFS, instance store và S3 khác nhau thế nào? Chọn gì cho file upload của app chạy nhiều instance?

🇻🇳 Tiếng Việt:

EBS là block storage gắn vào một instance trong một AZ, giống ổ cứng mạng, dùng cho root và database. Instance store là ổ vật lý trên host, nhanh nhất nhưng mất dữ liệu khi stop/terminate, chỉ dùng cho cache và dữ liệu tạm. EFS là file system NFS nhiều instance ở nhiều AZ mount cùng lúc, tự scale, trả theo GB dùng. S3 là object storage truy cập qua HTTP API, rẻ và bền nhất. Với file upload của app chạy nhiều instance, em chọn S3 với presigned URL; nếu code cũ ghi file POSIX và chưa kịp sửa thì mount EFS, không bao giờ dùng EBS vì không chia sẻ được giữa AZ.

🇬🇧 English:

EBS is block storage attached to one instance within one AZ, like a network disk, used for root volumes and databases. Instance store is physical disk on the host, the fastest option, but data is lost on stop or terminate, so it is only for cache and scratch. EFS is an NFS file system that many instances across AZs mount simultaneously; it scales automatically and bills per GB used. S3 is object storage over an HTTP API, the cheapest and most durable. For uploads from a multi-instance app I pick S3 with presigned URLs; if legacy code writes POSIX files and cannot be changed yet, I mount EFS. I never use EBS for that because it cannot be shared across AZs.

Q2. Khi nào chọn gp3, io2, st1, sc1? Vì sao mua thêm IOPS mà vẫn chậm?

🇻🇳 Tiếng Việt:

gp3 là mặc định: 3,000 IOPS và 125 MB/s baseline, mua thêm IOPS độc lập với dung lượng, rẻ hơn gp2 khoảng 20%. io2 Block Express cho database cần trên 16,000 IOPS, latency ổn định sub-ms, độ bền 99.999% và hỗ trợ Multi-Attach. st1 là HDD throughput cho đọc tuần tự lớn như log, big data; sc1 là HDD lạnh rẻ nhất; cả hai không làm boot volume được. Mua IOPS mà vẫn chậm thường vì nắp EBS bandwidth của instance type thấp hơn volume, hoặc nút thắt là throughput MB/s chứ không phải IOPS; cách sửa là đổi instance EBS-optimized lớn hơn hoặc tăng throughput.

🇬🇧 English:

gp3 is the default: 3,000 IOPS and 125 MB/s baseline, with extra IOPS purchased independently of size, about 20% cheaper than gp2. io2 Block Express is for databases needing more than 16,000 IOPS, consistent sub-millisecond latency, 99.999% durability and Multi-Attach. st1 is throughput HDD for large sequential reads such as logs or big data; sc1 is the cheapest cold HDD; neither can be a boot volume. Buying IOPS without improvement usually means the instance type's EBS bandwidth cap is lower than the volume, or the bottleneck is MB/s throughput rather than IOPS; the fix is a larger EBS-optimized instance or more throughput.

Q3. EBS snapshot hoạt động thế nào? Chuyển dữ liệu sang AZ/region khác bằng gì?

🇻🇳 Tiếng Việt:

Snapshot là bản sao incremental, lần đầu chụp toàn bộ block, các lần sau chỉ block thay đổi, lưu trong S3 do AWS quản lý. Xóa snapshot giữa chuỗi vẫn an toàn vì AWS giữ block cần cho snapshot sau. Volume chỉ sống trong một AZ, nên muốn sang AZ khác em tạo snapshot rồi tạo volume từ snapshot ở AZ đó; sang region khác thì copy snapshot (có thể đổi KMS key). Tự động hóa bằng Data Lifecycle Manager hoặc AWS Backup; cần hiệu năng ngay sau restore thì bật Fast Snapshot Restore.

🇬🇧 English:

A snapshot is incremental: the first captures all blocks, later ones only changed blocks, stored in AWS-managed S3. Deleting a snapshot in the middle of the chain is safe because AWS keeps the blocks later snapshots need. A volume lives in one AZ, so to move to another AZ I take a snapshot and create a volume from it there; for another region I copy the snapshot, optionally re-encrypting with a different KMS key. I automate with Data Lifecycle Manager or AWS Backup, and enable Fast Snapshot Restore when full performance is needed right after restore.

Q4. Khách hàng muốn chuyển 200 TB từ data center lên S3 trong 2 tuần, mạng 100 Mbps. Bạn đề xuất gì?

🇻🇳 Tiếng Việt:

200 TB qua 100 Mbps mất khoảng 6 tháng, không khả thi. Em đề xuất Snowball Edge Storage Optimized: đặt thiết bị, copy dữ liệu tại chỗ, gửi về AWS, AWS import vào S3; cần Glacier thì đặt lifecycle rule trên bucket vì Snowball không ghi thẳng Glacier. Phần dữ liệu thay đổi sau khi gửi thiết bị thì đồng bộ bằng DataSync. Nếu họ vẫn giữ app on-prem và cần truy cập file trên S3 như NFS, thêm S3 File Gateway.

🇬🇧 English:

200 TB over 100 Mbps takes roughly six months, so it is not feasible. I would use Snowball Edge Storage Optimized: order the devices, copy data on site, ship them back and AWS imports into S3; for Glacier, add a lifecycle rule on the bucket because Snowball cannot write directly to Glacier. Data that changes after shipping is synced with DataSync. If they keep applications on premises and need NFS access to the S3 data, I add an S3 File Gateway.

Góc thi SAA-C03

Câu 1: Một ứng dụng web Linux chạy trên nhiều EC2 trong Auto Scaling group ở 2 AZ. Người dùng upload tài liệu và mọi instance phải đọc/ghi được cùng một thư mục với POSIX permission; code không được sửa. Giải pháp nào đáp ứng với LEAST operational overhead?
A. Một EBS io2 volume bật Multi-Attach, gắn vào tất cả instance.
B. Amazon EFS với mount target ở mỗi AZ, mount lên các instance.
C. Amazon S3 với cron đồng bộ xuống từng instance.
D. Amazon FSx for Windows File Server.

Đáp án: B. Shared POSIX file system, nhiều AZ, Linux, không sửa code = EFS. A: Multi-Attach chỉ cùng AZ, cần cluster-aware filesystem, không dùng cho ext4/xfs thường. C: không phải shared filesystem thật, có độ trễ và tự vận hành. D: SMB cho Windows, không phù hợp Linux/POSIX.

Câu 2: Một database tự quản lý trên EC2 cần 40,000 IOPS ổn định với latency dưới 1 ms và yêu cầu durability cao nhất. Volume type nào phù hợp nhất?
A. gp3
B. io2 Block Express
C. st1
D. gp2

Đáp án: B. >16,000 IOPS, sub-ms, "highest durability" (99.999%) = io2 Block Express. A/D: gp3 và gp2 tối đa 16,000 IOPS. C: HDD throughput, IOPS thấp, không cho DB random I/O.

Câu 3: Công ty có 50 TB dữ liệu phân tích trên NFS server on-premises, kết nối Internet 1 Gbps. Họ cần copy lên Amazon S3 trong tuần này, giữ metadata file, và sau đó đồng bộ hàng đêm các thay đổi. Giải pháp nào MOST cost-effective?
A. AWS Snowball Edge, rồi dùng Snowball mỗi đêm.
B. AWS DataSync với agent on-prem, task chạy lần đầu rồi đặt lịch hàng đêm.
C. AWS Storage Gateway Volume Gateway stored mode.
D. AWS Transfer Family với script SFTP hàng đêm.

Đáp án: B. 50 TB qua 1 Gbps ≈ 5 ngày, khả thi; "preserve metadata" + "scheduled sync" là từ khóa DataSync. A: Snowball cho trường hợp mạng không đủ, và không dùng cho đồng bộ hàng đêm. C: Volume Gateway là block iSCSI cho app, không phải công cụ migrate dataset NFS. D: SFTP là endpoint cho đối tác đẩy file, không tối ưu cho 50 TB và không giữ metadata POSIX.

Cách nhớ ngắn gọn

Từ khóa trong đềDịch vụ
shared file system, Linux, multi-AZ, POSIX, thousands of instancesEFS
SMB, Active Directory, Windows shared driveFSx for Windows File Server
HPC, ML training, S3-linked, hundreds of GB/sFSx for Lustre
NFS + SMB + iSCSI multi-protocol, NetApp migrationFSx for NetApp ONTAP
highest IOPS, sub-ms, mission-critical DBEBS io2 Block Express
throughput-intensive sequential, big data, cheapest blockst1 / sc1
temporary, highest performance, data loss acceptableInstance store
attach one volume to multiple instancesio1/io2 Multi-Attach (same AZ, cluster FS)
on-prem NFS/SMB access to S3, cache locallyS3 File Gateway
iSCSI, on-prem block, backup to EBS snapshotsVolume Gateway (cached / stored)
replace tape backup, VTLTape Gateway
migrate / schedule copy NFS→EFS/S3, preserve metadataDataSync
petabytes, no bandwidth, remote site, edge computeSnowball Edge / Snowcone
partners upload via SFTP/FTPSTransfer Family
global users upload to one bucket fasterS3 Transfer Acceleration

Tự kiểm tra

Vì sao không gắn một EBS volume cho 2 EC2 ở 2 AZ để chia sẻ thư mục upload?

EBS sống trong một AZ và gắn vào một instance; Multi-Attach chỉ cho io1/io2 cùng AZ và cần cluster-aware filesystem. Shared thư mục đa AZ dùng EFS, hoặc tốt hơn chuyển sang S3.

gp3 khác gp2 ở điểm gì khiến AWS khuyên migrate?

gp3 có 3,000 IOPS và 125 MB/s baseline bất kể dung lượng, mua thêm IOPS/throughput độc lập với GB, không có burst credit, rẻ hơn ~20%. gp2 gắn IOPS vào dung lượng (3 IOPS/GB) và dùng burst credit.

Volume đã 10,000 IOPS nhưng app vẫn chậm, nguyên nhân hay gặp?

Nắp EBS bandwidth của instance type thấp hơn volume (xem EBSIOBalance%), hoặc nút thắt là throughput MB/s. Đổi instance EBS-optimized lớn hơn, tăng throughput, hoặc RAID 0.

EFS mount target là gì và vì sao cần ở mỗi AZ?

Là ENI có IP trong một subnet, điểm vào NFS cho instance trong AZ đó. Instance ở AZ không có mount target vẫn mount được xuyên AZ nhưng tốn phí data transfer và latency cao hơn; thiếu mount target ở AZ đang chạy app thì khi AZ kia hỏng app treo.

Storage Gateway, DataSync, Snowball: mỗi cái giải quyết bài toán nào?

Storage Gateway: app on-prem truy cập storage AWS liên tục qua NFS/SMB/iSCSI/VTL với cache. DataSync: copy/đồng bộ dữ liệu qua mạng một lần hoặc theo lịch, giữ metadata. Snowball: chuyển dữ liệu offline bằng thiết bị khi mạng không đủ hoặc không có.