Ngân hàng đề — AWS Certified Solutions Architect Professional
Tìm thấy 1221 câu.
An e-commerce company manages its flagship applications on AWS. The Amazon EC2 instances running the applications are fronted by an Application Load Balancer (ALB). Amazon Route 53 provides public DNS services. Different URLs (mobile.ecomm.com, web.ecomm.com, api.ecomm.com) will serve the required content to the end-users.
As an AWS Certified Solutions Architect Professional, which combination of services would you use to serve the content to the end-users? (Select two)
-
A
Use Path conditions in ALB listener to route *.ecomm.com to appropriate target groups
-
B
Use Path component of Redirect actions in ALB listener configuration to route ecomm.com to appropriate target groups
-
C
Use Host conditions in ALB listener to route $$$$.ecomm.com to appropriate target groups
-
D
Use Host conditions in ALB listener to route ecomm.com to appropriate target groups
-
E
Use Host conditions in ALB listener to route *.ecomm.com to appropriate target groups
Xem giải thích
Đáp án
**D và E — Dùng Host condition trong listener của ALB để định tuyến ecomm.com tới target group phù hợp, và dùng Host condition để định tuyến *.ecomm.com tới target group phù hợp.
Vì sao đúng
Đề nêu một yêu cầu rất rõ: phân biệt theo tên miền, không phải theo đường dẫn:
mobile.ecomm.com
web.ecomm.com
api.ecomm.com
↓
Khác nhau ở phần TÊN MIỀN CON
↓
Đường dẫn có thể giống hệt nhau
→ phải định tuyến theo host
⚠ Điểm mấu chốt: ALB có hai loại điều kiện định tuyến chính: | Điều kiện | Nhìn vào | |---|---| | Host condition | header Host — tức tên miền | | Path condition | đường dẫn sau tên miền |
`mobile.ecomm.com/san-pham`
↓
Host: `mobile.ecomm.com`
Path: `/san-pham`
↓
Đề phân biệt theo tên miền con
→ Host condition
Đây là lý do phương án A sai — nó dùng path condition.
Tạo quy tắc theo host:
aws elbv2 create-rule --listener-arn <arn-listener> \
--priority 10 \
--conditions '[{"Field":"host-header",
"HostHeaderConfig":{"Values":["mobile.ecomm.com"]}}]' \
--actions '[{"Type":"forward",
"TargetGroupArn":"<tg-mobile>"}]'
aws elbv2 create-rule --listener-arn <arn-listener> \
--priority 20 \
--conditions '[{"Field":"host-header",
"HostHeaderConfig":{"Values":["api.ecomm.com"]}}]' \
--actions '[{"Type":"forward",
"TargetGroupArn":"<tg-api>"}]'
⚠ Và host condition hỗ trợ ký tự đại diện: | Ký tự | Nghĩa | |---|---| | * | không hoặc nhiều ký tự bất kỳ | | ? | đúng một ký tự |
`*.ecomm.com` khớp:
mobile.ecomm.com ✅
web.ecomm.com ✅
api.ecomm.com ✅
↓
KHÔNG khớp:
ecomm.com ❌
⚠ Đây chính là lý do cần CẢ HAI đáp án:
`*.ecomm.com` không phủ tên miền
gốc
↓
Người dùng gõ `ecomm.com`
→ không quy tắc nào khớp
→ rơi vào default action
↓
Phải có một quy tắc riêng cho
`ecomm.com`
⚠ Và vì sao phương án C sai — $$$$ không phải cú pháp hợp lệ:
C viết `$$$$.ecomm.com`
↓
ALB chỉ hỗ trợ `*` và `?`
↓
Không có ký tự `$` nào có nghĩa
→ chuỗi này khớp đúng nghĩa đen
và không bao giờ đúng
⚠ Và vì sao phương án B sai — redirect không phải định tuyến:
B nói dùng "Path component of
Redirect actions"
↓
Redirect action TRẢ VỀ 301/302
cho client
↓
Client phải gọi lại một URL khác
↓
Không phải chuyển tới target
group
⚠ Và bốn loại action của ALB — phải phân biệt: | Action | Việc | |---|---| | forward | chuyển tới target group | | redirect | trả 301/302, client gọi lại | | fixed-response | trả nội dung cố định | | authenticate-cognito/oidc | xác thực trước khi chuyển |
⚠ Và một listener rule có thể gộp nhiều điều kiện:
--conditions '[
{"Field":"host-header",
"HostHeaderConfig":{"Values":["api.ecomm.com"]}},
{"Field":"path-pattern",
"PathPatternConfig":{"Values":["/v2/*"]}}]'
Cả HAI điều kiện phải đúng
↓
`api.ecomm.com/v2/don-hang` → khớp
`api.ecomm.com/v1/don-hang` → không
⚠ Và thứ tự ưu tiên quyết định quy tắc nào thắng:
Priority thấp xét trước
↓
Quy tắc khớp đầu tiên thắng
↓
Đặt `*.ecomm.com` priority thấp
hơn các quy tắc cụ thể
→ nếu không nó nuốt hết
Priority 10: mobile.ecomm.com
Priority 20: api.ecomm.com
Priority 30: *.ecomm.com ← bắt phần còn lại
Default: ecomm.com
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một ALB phục vụ nhiều tên miền | | | Mỗi tên miền một đội máy riêng | | | Thêm tên miền con chỉ cần thêm quy tắc | |
⚠ Và một ALB gắn được nhiều chứng chỉ nhờ SNI:
aws elbv2 add-listener-certificates \
--listener-arn <arn> \
--certificates CertificateArn=<cc-wildcard>
Chứng chỉ wildcard `*.ecomm.com`
↓
Phủ mọi tên miền con
↓
Thêm chứng chỉ riêng cho
`ecomm.com`
→ hoặc đưa nó vào SAN
⚠ Và Route 53 phải trỏ mọi tên miền đó về ALB:
aws route53 change-resource-record-sets --hosted-zone-id Z123 \
--change-batch '{"Changes":[{
"Action":"UPSERT",
"ResourceRecordSet":{
"Name":"*.ecomm.com","Type":"A",
"AliasTarget":{"HostedZoneId":"Z_ALB",
"DNSName":"alb.elb.amazonaws.com",
"EvaluateTargetHealth":true}}}]}'
⚠ Và hạn ngạch quy tắc của ALB đáng nhớ: | Hạn ngạch | Mặc định | |---|---| | Quy tắc mỗi listener | 100 | | Target group mỗi ALB | 100 | | Chứng chỉ mỗi listener | 25 | | Giá trị mỗi điều kiện | 5 |
Vì sao các phương án khác sai
- **C. Dùng Host condition để định tuyến
$$$$.ecomm.com— đây là phương án gần nhất và dùng đúng loại điều kiện, nhưng ALB chỉ hỗ trợ ký tự đại diện*và?; chuỗi$$$$được hiểu theo nghĩa đen và sẽ không bao giờ khớp. - **A. Dùng Path condition để định tuyến
*.ecomm.com— path condition xét đường dẫn sau tên miền, không xét tên miền. - **B. Dùng thành phần Path của Redirect action để định tuyến
ecomm.com— redirect trả về mã 301/302 cho client chứ không chuyển tới target group.
Ghi nhớ
⚠ Năm loại điều kiện của ALB listener rule — bảng phải thuộc: | Điều kiện | Xét gì | |---|---| | host-header | tên miền | | path-pattern | đường dẫn | | http-header | header tuỳ ý | | query-string | tham số truy vấn | | source-ip | IP nguồn | | http-request-method | GET, POST... |
Từ khoá nhận diện:
"different subdomains to different targets" → host condition "different paths to different targets" → path condition "wildcard subdomain" →
*.domain.com, không phủ apex "redirect HTTP to HTTPS" → redirect action
⚠ Ký tự đại diện của ALB: | Ký tự | Nghĩa | |---|---| | * | không hoặc nhiều ký tự | | ? | đúng một ký tự |
`*.ecomm.com` KHÔNG khớp
`ecomm.com`
↓
Vì phải có ít nhất dấu chấm
↓
Đây là hành vi giống chứng chỉ
wildcard
Ba lưu ý về thứ tự quy tắc: | Lưu ý | Chi tiết | |---|---| | Priority 1 xét trước | | | Quy tắc khớp đầu tiên thắng | | | Default action ở cuối cùng | |
Ba lưu ý về target group: | Lưu ý | Chi tiết | |---|---| | Kiểu instance, IP, hoặc Lambda | | | Health check riêng cho mỗi target group | | | Weighted target group cho canary | |
⚠ Weighted target group cho triển khai canary:
--actions '[{"Type":"forward","ForwardConfig":
{"TargetGroups":[
{"TargetGroupArn":"<tg-cu>","Weight":90},
{"TargetGroupArn":"<tg-moi>","Weight":10}]}}]'
Ba lưu ý về chứng chỉ: | Lưu ý | Chi tiết | |---|---| | Nhiều chứng chỉ trên một listener, chọn theo SNI | | | Wildcard phủ một cấp tên miền con | | | Chứng chỉ mặc định dùng khi client không gửi SNI | |
Ba lưu ý về CloudFront trước ALB: | Lưu ý | Chi tiết | |---|---| | Cache behavior định tuyến theo path | | | Nhiều origin cho nhiều loại nội dung | | | Bảo vệ ALB bằng header bí mật | |
Ba lưu ý về Route 53: | Lưu ý | Chi tiết | |---|---| | Alias record cho ALB, miễn phí truy vấn | | | Bản ghi wildcard *.ecomm.com được | | | Bản ghi cụ thể thắng bản ghi wildcard | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | curl -H "Host: api.ecomm.com" http://alb-dns | | | Kiểm mỗi tên miền tới đúng target group | | | Thử ecomm.com xem có rơi vào default không | |
Và một lời khuyên: hãy thêm một quy tắc riêng cho tên miền gốc bên cạnh quy tắc wildcard. Chứng chỉ wildcard và điều kiện *.ecomm.com đều không phủ ecomm.com — nên người dùng gõ tên miền không có tiền tố sẽ rơi vào default action, thường là một trang không phải trang họ muốn.
The development team at a gaming company has been tasked to reduce the in-game latency and jitters. The team wants traffic from its end users to be routed to the AWS Region that is closest to the end users geographically. When maintenance occurs in an AWS Region, traffic must be routed to the next closest AWS Region with no changes to the IP addresses being used as connections by the end-users.
As an AWS Certified Solutions Architect Professional, which solution will you suggest to meet these requirements?
-
A
Configure a Route 53 latency routing policy to navigate traffic to the closest AWS Region
-
B
Configure a Route 53 geoproximity routing policy to navigate traffic to the closest AWS Region
-
C
Set up AWS Global Accelerator in front of all the AWS Regions
-
D
Set up a CloudFront distribution in front of all the AWS Regions
Xem giải thích
Đáp án
**C — Dựng AWS Global Accelerator đứng trước tất cả các AWS Region.
Vì sao đúng
Đề nêu ba yêu cầu, và chỉ Global Accelerator đáp ứng cả ba: | Yêu cầu | Cách đáp ứng | |---|---| | Định tuyến tới Region gần nhất về mặt địa lý | anycast, vào mạng AWS ở điểm biên gần nhất | | Bảo trì một Region → chuyển sang Region gần thứ hai | health check + tự chuyển trong vài giây | | KHÔNG đổi địa chỉ IP mà người dùng đang kết nối | hai IP tĩnh anycast, không bao giờ đổi |
⚠ Điểm mấu chốt: "không đổi địa chỉ IP" loại mọi giải pháp dựa trên DNS:
Route 53 điều khiển lưu lượng bằng
cách trả về IP KHÁC NHAU
↓
Chuyển Region = đổi IP
↓
Đề nói rõ IP không được đổi
→ Route 53 bị loại
Đây là lý do phương án A và B đều sai.
⚠ Và game dùng UDP làm CloudFront không dùng được:
CloudFront phân phối HTTP/HTTPS
↓
Đề nói game chạy trên UDP
↓
CloudFront không proxy UDP tuỳ ý
→ phương án D bị loại
⚠ Và Global Accelerator hỗ trợ cả TCP lẫn UDP: | Dịch vụ | Giao thức | |---|---| | CloudFront | HTTP/HTTPS | | Global Accelerator | TCP và UDP |
Tạo accelerator:
aws globalaccelerator create-accelerator \
--name tang-toc-game --ip-address-type IPV4
aws globalaccelerator create-listener \
--accelerator-arn <arn> \
--protocol UDP --port-ranges FromPort=7777,ToPort=7777 \
--client-affinity SOURCE_IP
aws globalaccelerator create-endpoint-group \
--listener-arn <arn-listener> \
--endpoint-group-region ap-southeast-1 \
--endpoint-configurations EndpointId=<arn-nlb>,Weight=100
⚠ Anycast là cơ chế khiến IP tĩnh vẫn định tuyến theo địa lý:
Cùng MỘT địa chỉ IP được quảng bá
từ hơn 100 điểm biên AWS
↓
Router Internet gửi gói tới điểm
biên GẦN NHẤT
↓
Từ đó đi trên mạng xương sống
AWS tới Region
→ IP không đổi, đường đi tối ưu
⚠ Và đây là lý do độ trễ và jitter giảm:
Internet công cộng: nhiều chặng,
nhiều nhà mạng
↓
Đường đi thay đổi, độ trễ dao
động — đó chính là jitter
↓
Mạng AWS: đường đi ổn định,
băng thông đảm bảo
→ jitter giảm rõ rệt
⚠ Và chuyển đổi khi bảo trì diễn ra trong vài giây:
Health check phát hiện endpoint hỏng
↓
Global Accelerator ngừng gửi
lưu lượng tới nhóm đó
↓
Chuyển sang nhóm endpoint tiếp
theo
↓
Client vẫn dùng CÙNG địa chỉ IP
→ không cần chờ TTL DNS nào
⚠ Hoặc chủ động rút một Region bằng traffic dial:
aws globalaccelerator update-endpoint-group \
--endpoint-group-arn <arn-nhom> \
--traffic-dial-percentage 0
Đặt về 0 trước khi bảo trì
↓
Lưu lượng chuyển sang Region khác
có kiểm soát
↓
Xong bảo trì → đặt về 100
⚠ Và client affinity giữ người chơi ở một endpoint:
`ClientAffinity: SOURCE_IP`
↓
Cùng IP nguồn → luôn cùng endpoint
↓
Quan trọng với game có trạng thái
phiên
↓
Không có → mỗi gói có thể tới
máy chủ khác
⚠ Và vì sao geoproximity không giải quyết được:
Geoproximity routing của Route 53
↓
Định tuyến theo khoảng cách địa
lý, có bias điều chỉnh được
↓
Nhưng vẫn là DNS
→ vẫn trả về IP khác nhau
→ và vẫn phụ thuộc TTL
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Hai IP tĩnh không bao giờ đổi | | | Chuyển Region trong vài giây | | | Độ trễ và jitter giảm nhờ mạng AWS | |
⚠ Và hai IP tĩnh đến từ hai vùng mạng khác nhau:
Global Accelerator cấp 2 IP
↓
Từ hai network zone độc lập
↓
Sự cố ở một vùng mạng
→ vùng kia vẫn hoạt động
↓
Client nên thử cả hai
⚠ Và game client thường cài cứng địa chỉ máy chủ:
Client cũ đã phát hành
↓
Không cập nhật được ngay
↓
IP tĩnh cho phép đổi hạ tầng
phía sau mà không đụng client
→ đây là giá trị lớn nhất
⚠ Nhưng chi phí cao hơn Route 53 đáng kể:
Global Accelerator: phí cố định
~0,025 USD/giờ + phí truyền dữ
liệu theo Region
↓
Route 53: chỉ phí truy vấn
↓
Với game cần độ trễ thấp thì
đáng
→ nhưng phải tính vào ngân sách
Vì sao các phương án khác sai
- **B. Cấu hình Route 53 geoproximity routing để đưa lưu lượng tới Region gần nhất — đây là phương án gần nhất và thật sự định tuyến theo khoảng cách địa lý, nhưng nó hoạt động ở tầng DNS nên mỗi Region có địa chỉ IP khác nhau, vi phạm yêu cầu không đổi IP.
- **A. Cấu hình Route 53 latency routing — cùng vấn đề: định tuyến bằng cách trả về IP khác nhau, và chuyển đổi phụ thuộc TTL.
- **D. Dựng CloudFront đứng trước các Region — CloudFront phân phối HTTP/HTTPS, không proxy được lưu lượng UDP của game.
Ghi nhớ
⚠ Global Accelerator và CloudFront — bảng phải thuộc: | Tiêu chí | Global Accelerator | CloudFront | |---|---|---| | Giao thức | TCP, UDP | HTTP/HTTPS | | Cache | KHÔNG | CÓ | | IP tĩnh | CÓ, anycast | không | | Chuyển Region | vài giây | origin failover |
Từ khoá nhận diện:
"static IP addresses must not change" → Global Accelerator "UDP traffic" → Global Accelerator hoặc NLB "cache static content globally" → CloudFront "route to nearest Region by DNS" → Route 53 latency/geoproximity
Ba lưu ý về Global Accelerator: | Lưu ý | Chi tiết | |---|---| | Hai IP tĩnh từ hai network zone | | | Traffic dial 0-100% mỗi nhóm endpoint | | | Client affinity theo IP nguồn | |
⚠ Hai loại accelerator: | Loại | Dùng cho | |---|---| | Standard | định tuyến tới endpoint gần nhất, có health check | | Custom routing | định tuyến tất định tới một instance cụ thể |
Custom routing accelerator
↓
Ánh xạ cổng tới đúng một instance
trong subnet
↓
Dùng cho game cần gán người chơi
vào đúng một máy chủ phiên
Ba lưu ý về endpoint được hỗ trợ: | Endpoint | Hỗ trợ | |---|---| | ALB, NLB | CÓ | | EC2 instance | CÓ | | Elastic IP | CÓ | | S3, Lambda | KHÔNG |
Ba lưu ý về health check: | Lưu ý | Chi tiết | |---|---| | Kế thừa health check của ALB/NLB | | | Với EC2 và EIP thì cấu hình riêng | | | Chuyển đổi trong khoảng 30 giây | |
Ba lưu ý về game trên AWS: | Dịch vụ | Việc | |---|---| | GameLift | quản đội máy chủ game, ghép cặp người chơi | | Global Accelerator | giảm độ trễ, IP tĩnh | | NLB | cân bằng tải UDP trong một Region |
Ba lưu ý về chi phí: | Khoản | Ghi chú | |---|---| | Phí cố định mỗi accelerator | ~0,025 USD/giờ | | Phí truyền dữ liệu premium | theo Region nguồn và đích | | Tính cho cả hai chiều | |
Ba lưu ý về Shield: | Lưu ý | Chi tiết | |---|---| | Global Accelerator có Shield Standard sẵn | | | Shield Advanced bảo vệ được accelerator | | | IP tĩnh giúp việc chặn dễ hơn | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo độ trễ từ nhiều khu vực | | | Đặt traffic dial về 0 và xem có chuyển không | | | Kiểm IP không đổi sau khi chuyển Region | |
Và một lời khuyên: hãy dùng traffic dial để rút một Region trước khi bảo trì thay vì chờ health check phát hiện. Chuyển đổi có kiểm soát cho phép người chơi đang trong trận kết thúc bình thường, còn để health check phát hiện nghĩa là họ bị ngắt giữa chừng.
During a quarterly audit, it has come to light that employees have not followed the security standards mandated by the company while using the AWS Key Management Service (AWS KMS) keys. The senior management has decided that access to AWS KMS keys should be restricted to only the principals belonging to their AWS Organizations.
How will you implement this requirement?
-
A
The
aws:PrincipalOrgIDglobal condition key can be used with the Principal element in a resource-based policy with AWS KMS. List all the AWS account IDs in theConditionelement -
B
The
aws:PrincipalIsAWSServiceglobal condition key can be used with the Principal element in a resource-based policy with AWS KMS. List all the AWS account IDs in theConditionelement -
C
The
aws:PrincipalOrgIDglobal condition key can be used with the Principal element in a resource-based policy with AWS KMS. You need to specify the Organization ID in theConditionelement -
D
The
aws:PrincipalOrgIDglobal condition context key can be used to restrict access to an AWS service principal
Xem giải thích
Đáp án
**C — Dùng khoá điều kiện toàn cục aws:PrincipalOrgID cùng với phần tử Principal trong resource-based policy của KMS, và khai ID của Organization trong phần tử Condition.
Vì sao đúng
Đề yêu cầu giới hạn quyền dùng khoá KMS cho mọi principal thuộc AWS Organizations của công ty:
Không phải một vài tài khoản cụ thể
↓
Mà là TOÀN BỘ tổ chức
↓
Và tổ chức thay đổi theo thời gian
→ thêm tài khoản mới
⚠ Điểm mấu chốt: aws:PrincipalOrgID nhận MỘT giá trị — ID của tổ chức:
{"Condition": {"StringEquals": {
"aws:PrincipalOrgID": "o-abc123xyz"}}}
Một chuỗi duy nhất
↓
Áp cho mọi tài khoản trong tổ chức
↓
Tài khoản mới gia nhập → tự động
được phép
→ không phải sửa chính sách
⚠ Và đây là lý do phương án A sai — nó liệt kê từng tài khoản:
A nói "liệt kê tất cả AWS account ID
trong phần tử Condition"
↓
`aws:PrincipalOrgID` không nhận
danh sách account ID
↓
Nó nhận ID của TỔ CHỨC
↓
Muốn liệt kê tài khoản → dùng
`aws:PrincipalAccount`
⚠ Và liệt kê từng tài khoản là đúng thứ cần tránh:
Tổ chức có 50 tài khoản
↓
Thêm tài khoản thứ 51
↓
Phải sửa chính sách khoá của
MỌI khoá KMS
→ không mở rộng được
Chính sách khoá KMS đầy đủ:
{"Version": "2012-10-17",
"Statement": [
{"Sid": "ChoPhepQuanTri",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"},
{"Sid": "ChiChoPhepTrongToChuc",
"Effect": "Allow",
"Principal": {"AWS": "*"},
"Action": ["kms:Decrypt", "kms:GenerateDataKey",
"kms:DescribeKey"],
"Resource": "*",
"Condition": {"StringEquals": {
"aws:PrincipalOrgID": "o-abc123xyz"}}}]}
⚠ Principal: "*" kết hợp với điều kiện là mẫu chuẩn:
Principal `*` một mình = mọi người
↓
Nhưng điều kiện `PrincipalOrgID`
thu hẹp lại
↓
Chỉ danh tính trong tổ chức mới
thoả điều kiện
→ an toàn
⚠ Và vì sao phương án B sai — sai khoá điều kiện:
`aws:PrincipalIsAWSService`
↓
Kiểm tra người gọi có phải là
DỊCH VỤ AWS không
↓
Trả về true/false
↓
Không liên quan tới tổ chức
⚠ Và khoá đó dùng cho việc khác:
{"Condition": {"Bool": {
"aws:PrincipalIsAWSService": "false"}}}
Loại trừ lời gọi từ dịch vụ AWS
↓
Ví dụ: chỉ cho phép người thật,
không cho phép dịch vụ tự gọi
⚠ Và vì sao phương án D sai — nói ngược mục đích:
D nói dùng `aws:PrincipalOrgID` để
"giới hạn quyền cho một AWS
SERVICE PRINCIPAL"
↓
Service principal (ví dụ
`s3.amazonaws.com`) KHÔNG
thuộc tổ chức nào
↓
Điều kiện đó không áp được
→ và sẽ chặn luôn dịch vụ AWS
⚠ Đây là bẫy thật khi triển khai:
Thêm điều kiện PrincipalOrgID
↓
Dịch vụ AWS (S3, CloudTrail...)
gọi KMS thay mặt bạn
↓
Chúng không có PrincipalOrgID
→ bị chặn
↓
Phải thêm ngoại lệ
{"Sid": "ChoPhepDichVuAWS",
"Effect": "Allow",
"Principal": {"Service": "s3.amazonaws.com"},
"Action": ["kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "*",
"Condition": {"StringEquals": {
"aws:SourceAccount": "111122223333"}}}
⚠ Và có khoá tương tự cho chiều ngược lại: | Khoá | Kiểm tra | |---|---| | aws:PrincipalOrgID | NGƯỜI GỌI thuộc tổ chức nào | | aws:ResourceOrgID | TÀI NGUYÊN thuộc tổ chức nào | | aws:PrincipalOrgPaths | người gọi thuộc OU nào |
⚠ aws:PrincipalOrgPaths cho phép giới hạn tới OU:
{"Condition": {"ForAnyValue:StringLike": {
"aws:PrincipalOrgPaths": [
"o-abc123xyz/r-root/ou-san-xuat/*"]}}}
Chỉ tài khoản trong OU sản xuất
↓
Chi tiết hơn cả tổ chức
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một điều kiện cho toàn tổ chức | | | Tài khoản mới tự được phép | | | Tài khoản rời tổ chức tự mất quyền | |
⚠ Và điểm cuối là lợi ích an ninh quan trọng:
Tài khoản bị tách khỏi tổ chức
↓
`aws:PrincipalOrgID` không còn
khớp
↓
Mất quyền dùng khoá NGAY
→ không cần ai nhớ thu hồi
⚠ Và nên áp cùng điều kiện đó ở nhiều nơi:
KMS key policy
↓
S3 bucket policy
↓
Secrets Manager resource policy
↓
SNS topic policy, SQS queue policy
→ phòng thủ nhất quán
⚠ Và RCP áp điều kiện đó cho toàn tổ chức bằng một lần:
{"Effect": "Deny",
"Principal": "*",
"Action": ["kms:*", "s3:*"],
"Resource": "*",
"Condition": {"StringNotEquals": {
"aws:PrincipalOrgID": "o-abc123xyz"}}}
Resource control policy (2024)
↓
Áp cho MỌI tài nguyên trong tổ
chức
↓
Không phải sửa từng chính sách
tài nguyên
Vì sao các phương án khác sai
- **A. Dùng
aws:PrincipalOrgIDvớiPrincipaltrong resource-based policy, liệt kê tất cả AWS account ID trongCondition— đây là phương án gần nhất và dùng đúng khoá điều kiện, nhưngaws:PrincipalOrgIDnhận ID của tổ chức chứ không nhận danh sách account ID; liệt kê từng tài khoản cũng chính là điều cần tránh. - **B. Dùng
aws:PrincipalIsAWSServicevà liệt kê account ID — khoá đó kiểm tra người gọi có phải dịch vụ AWS không, không liên quan tới tổ chức. - **D. Dùng
aws:PrincipalOrgIDđể giới hạn quyền cho một service principal — service principal không thuộc tổ chức nào nên điều kiện này sẽ chặn chúng.
Ghi nhớ
⚠ Bốn khoá điều kiện về Organizations — bảng phải thuộc: | Khoá | Kiểm tra | |---|---| | aws:PrincipalOrgID | người gọi thuộc tổ chức này | | aws:PrincipalOrgPaths | người gọi thuộc OU này | | aws:ResourceOrgID | tài nguyên thuộc tổ chức này | | aws:PrincipalAccount | người gọi thuộc tài khoản này |
Từ khoá nhận diện:
"restrict to principals in my Organization" →
aws:PrincipalOrgID"prevent access to resources outside my Org" →aws:ResourceOrgID"restrict to a specific OU" →aws:PrincipalOrgPaths"only AWS services" →aws:PrincipalIsAWSService
Ba lưu ý về chính sách khoá KMS: | Lưu ý | Chi tiết | |---|---| | Khoá LUÔN cần chính sách khoá | | | IAM policy một mình KHÔNG đủ | | | Chính sách khoá là nguồn quyền chính | |
⚠ Đây là khác biệt lớn so với S3:
S3: IAM policy đủ (cùng tài khoản)
↓
KMS: chính sách khoá phải cho
phép, dù cùng tài khoản
↓
Thường bằng câu "cho phép IAM
policy quyết định"
{"Sid": "ChoPhepIAM", "Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*", "Resource": "*"}
Ba lưu ý về khoá KMS liên tài khoản: | Lưu ý | Chi tiết | |---|---| | Chính sách khoá phải cho phép tài khoản kia | | | Và IAM policy bên đó cũng phải cho phép | | | Khoá mặc định aws/... KHÔNG chia sẻ được | |
Ba hành động KMS thường cần: | Hành động | Khi nào | |---|---| | kms:Decrypt | đọc dữ liệu đã mã hoá | | kms:GenerateDataKey | ghi dữ liệu mới | | kms:DescribeKey | dịch vụ hỏi thông tin khoá |
Ba lưu ý về điều kiện bổ trợ: | Điều kiện | Tác dụng | |---|---| | kms:ViaService | chỉ dùng khoá qua một dịch vụ | | aws:SourceAccount | chống confused deputy | | kms:EncryptionContext | ràng buộc theo ngữ cảnh |
⚠ kms:ViaService giới hạn phạm vi rất tốt:
{"Condition": {"StringEquals": {
"kms:ViaService": "s3.ap-southeast-1.amazonaws.com"}}}
Khoá chỉ dùng được khi đi qua S3
↓
Không gọi thẳng KMS để giải mã
thứ khác
Ba lưu ý về multi-Region key: | Lưu ý | Chi tiết | |---|---| | Cùng key material ở nhiều Region | | | Chính sách khoá đặt riêng ở mỗi Region | | | Hữu ích cho sao chép liên Region | |
Ba lưu ý về giám sát: | Lưu ý | Chi tiết | |---|---| | CloudTrail ghi mọi lời gọi KMS | | | Đặt cảnh báo khi có Decrypt bị từ chối | | | Xoay khoá tự động hằng năm | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Thử giải mã từ tài khoản trong tổ chức — phải được | | | Thử từ tài khoản ngoài — phải bị từ chối | | | Kiểm dịch vụ AWS vẫn dùng khoá được | |
Và một lời khuyên: hãy thêm ngoại lệ cho service principal khi áp điều kiện aws:PrincipalOrgID lên chính sách khoá KMS. Các dịch vụ AWS gọi KMS thay mặt bạn không mang theo thông tin tổ chức, nên một chính sách chặt chẽ về mặt lý thuyết sẽ làm S3, CloudTrail và mọi thứ dùng SSE-KMS ngừng hoạt động.
A business has hosted their custom made log data analyzer application on AWS. The application examines the generated log data using the date ranges. Every day the application generates around 15 GB of data which is expected to keep growing in the future. As a solutions architect, you are responsible for storing the data in Amazon S3 and analyzing it using Amazon Athena.
What combination of steps will you recommend for the best-performing solution? (Select two)
-
A
Leverage bucketed tables within Athena by using Apache Spark bucketing format
-
B
Store the data in Amazon S3 in an uncompressed format
-
C
Partition the data in Amazon S3 using Apache Hive partitioning. Use a date column as partition key
-
D
Store the data in Amazon S3 in a columnar format such as Apache Parquet
-
E
Store the data in Amazon S3 in objects that are smaller than 10 MB
Xem giải thích
Đáp án
**C và D — Phân vùng dữ liệu trên S3 theo kiểu Apache Hive, dùng cột ngày làm khoá phân vùng; và lưu dữ liệu ở định dạng cột như Apache Parquet.
Vì sao đúng
Đề cho một dữ kiện quyết định cách tối ưu:
Ứng dụng phân tích log THEO KHOẢNG
NGÀY
↓
Mọi truy vấn đều có điều kiện
về ngày
↓
→ phân vùng theo ngày là tối ưu
lớn nhất
⚠ Điểm mấu chốt: Athena tính tiền theo lượng dữ liệu QUÉT:
5 USD mỗi TB quét
↓
15 GB mỗi ngày, tăng dần
↓
Một năm ≈ 5,5 TB
↓
Không phân vùng: mỗi truy vấn
quét toàn bộ
→ 27,5 USD mỗi lần chạy
Phân vùng theo kiểu Hive:
s3://kho-log/du-lieu/nam=2026/thang=09/ngay=01/
s3://kho-log/du-lieu/nam=2026/thang=09/ngay=02/
CREATE EXTERNAL TABLE log_ung_dung (
thoi_diem TIMESTAMP,
muc_do STRING,
thong_diep STRING,
ma_nguoi_dung STRING)
PARTITIONED BY (nam STRING, thang STRING, ngay STRING)
STORED AS PARQUET
LOCATION 's3://kho-log/du-lieu/';
⚠ Kiểu Hive dùng khoa=giatri trong đường dẫn — đây là điểm quan trọng:
Đường dẫn `nam=2026/thang=09/`
↓
Athena và Glue crawler TỰ nhận
ra phân vùng
↓
Đường dẫn `2026/09/`
→ phải khai thủ công từng phân
vùng
MSCK REPAIR TABLE log_ung_dung;
Lệnh này chỉ hoạt động với kiểu Hive
↓
Tự quét S3 và thêm mọi phân vùng
tìm thấy
⚠ Và partition projection tốt hơn nữa cho dữ liệu theo ngày:
TBLPROPERTIES (
'projection.enabled'='true',
'projection.nam.type'='integer',
'projection.nam.range'='2024,2030',
'projection.thang.type'='integer',
'projection.thang.range'='1,12',
'projection.thang.digits'='2',
'projection.ngay.type'='integer',
'projection.ngay.range'='1,31',
'projection.ngay.digits'='2',
'storage.location.template'=
's3://kho-log/du-lieu/nam=${nam}/thang=${thang}/ngay=${ngay}')
Không cần crawler
↓
Không cần MSCK REPAIR
↓
Athena suy ra phân vùng từ mẫu
→ và không bị chậm khi có hàng
chục nghìn phân vùng
⚠ Và Parquet giảm quét theo hai cơ chế cộng dồn: | Cơ chế | Tác dụng | |---|---| | Lưu theo CỘT | chỉ đọc cột được chọn | | Nén theo cột | cùng kiểu dữ liệu nén rất tốt | | Thống kê theo row group | bỏ qua cả khối không khớp điều kiện |
Bảng 20 cột, truy vấn dùng 3 cột
↓
Parquet đọc 3 cột
↓
Cộng nén Snappy khoảng 4 lần
→ tổng giảm khoảng 25 lần
⚠ Và đây là lý do phương án B sai:
B nói lưu ở định dạng KHÔNG NÉN
↓
Ngược hoàn toàn với tối ưu
↓
Quét nhiều hơn, chậm hơn, đắt
hơn
⚠ Và vì sao phương án E sai — tệp nhỏ là chống mẫu:
E nói lưu object NHỎ HƠN 10 MB
↓
Hàng triệu tệp nhỏ
↓
Chi phí liệt kê và mở tệp lấn át
↓
AWS khuyến nghị 128 MB - 512 MB
mỗi tệp
⚠ Và tệp nhỏ làm Athena chậm rõ rệt:
Mỗi tệp là một lần gọi S3
↓
10.000 tệp 1 MB vs 20 tệp 512 MB
↓
Cùng lượng dữ liệu
→ nhưng cái đầu chậm hơn nhiều lần
⚠ Và vì sao phương án A không phải lựa chọn tốt nhất ở đây:
A nói dùng bucketing kiểu Spark
↓
Athena hỗ trợ bucketing kiểu Hive
↓
Nhưng bucketing hợp khi lọc theo
cột có ĐỘ PHÂN TÁN CAO
(mã người dùng, mã đơn hàng)
↓
Đề nói lọc theo KHOẢNG NGÀY
→ phân vùng hợp hơn
⚠ Và phân vùng với bucketing khác nhau: | Kỹ thuật | Hợp với | |---|---| | Phân vùng | cột ít giá trị, lọc theo khoảng (ngày, Region) | | Bucketing | cột nhiều giá trị, lọc bằng nhau (mã người dùng) |
Phân vùng theo mã người dùng
↓
Hàng triệu thư mục
→ siêu dữ liệu quá lớn, Athena chậm
↓
Bucketing: chia thành số lượng
file cố định theo hash
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Chi phí quét giảm hàng trăm lần | | | Truy vấn nhanh hơn tương ứng | | | Không cần dựng cụm nào | |
⚠ Và chuyển sang Parquet bằng Glue hoặc CTAS:
CREATE TABLE log_parquet
WITH (format = 'PARQUET',
parquet_compression = 'SNAPPY',
partitioned_by = ARRAY['nam','thang','ngay'],
external_location = 's3://kho-log/parquet/')
AS SELECT * FROM log_tho;
⚠ Và nên đặt giới hạn quét cho workgroup:
aws athena create-work-group --name phan-tich-log \
--configuration '{
"ResultConfiguration": {"OutputLocation": "s3://ket-qua/"},
"BytesScannedCutoffPerQuery": 10737418240,
"EnforceWorkGroupConfiguration": true}'
Truy vấn quên điều kiện phân vùng
↓
Bị huỷ khi quét quá 10 GB
↓
Chống một câu lệnh đốt hết ngân
sách
⚠ Và kiểm chứng phân vùng có hoạt động không:
EXPLAIN SELECT COUNT(*) FROM log_ung_dung
WHERE nam='2026' AND thang='09';
Xem kế hoạch thực thi
↓
Nếu thấy quét toàn bảng
→ điều kiện chưa dùng đúng cột
phân vùng
Vì sao các phương án khác sai
- **A. Dùng bucketed table trong Athena bằng định dạng bucketing của Apache Spark — đây là phương án gần nhất và bucketing thật sự là kỹ thuật tối ưu hợp lệ, nhưng nó hợp với việc lọc bằng nhau trên cột có độ phân tán cao, còn đề nói lọc theo khoảng ngày nên phân vùng mới đúng.
- **B. Lưu dữ liệu ở định dạng không nén — làm tăng lượng quét, ngược với mọi mục tiêu tối ưu.
- **E. Lưu dữ liệu trong các object nhỏ hơn 10 MB — quá nhiều tệp nhỏ làm chi phí siêu dữ liệu lấn át và Athena chậm hẳn.
Ghi nhớ
⚠ Bốn kỹ thuật tối ưu Athena — bảng phải thuộc: | Kỹ thuật | Mức giảm | |---|---| | Phân vùng theo cột hay lọc | lớn nhất | | Định dạng cột (Parquet/ORC) | lớn | | Nén (Snappy, ZSTD) | vừa | | Gom tệp nhỏ | cải thiện tốc độ |
Từ khoá nhận diện:
"query by date ranges" → phân vùng theo ngày "columnar format" → Parquet hoặc ORC "filter by high-cardinality column" → bucketing "many small files" → gom lại, chống mẫu
Ba lưu ý về phân vùng: | Lưu ý | Chi tiết | |---|---| | Kiểu Hive khoa=giatri tự nhận diện | | | Quá nhiều phân vùng cũng gây chậm | | | Partition projection bỏ được crawler | |
⚠ Số phân vùng có giới hạn thực tế:
Vài chục nghìn phân vùng
↓
Việc liệt kê siêu dữ liệu tự nó
chậm
↓
Phân vùng theo ngày: 365/năm
→ hợp lý
↓
Phân vùng theo giờ: 8.760/năm
→ cân nhắc kỹ
Ba lưu ý về Parquet: | Lưu ý | Chi tiết | |---|---| | Lưu theo cột, có thống kê min/max | | | Row group mặc định 128 MB | | | Snappy cân bằng tốt giữa tốc độ và nén | |
Ba codec nén: | Codec | Đặc điểm | |---|---| | Snappy | nhanh, nén vừa — mặc định | | GZIP | nén tốt hơn, chậm hơn | | ZSTD | cân bằng tốt nhất hiện nay |
Ba lưu ý về Glue: | Lưu ý | Chi tiết | |---|---| | Crawler tự phát hiện schema và phân vùng | | | Job bookmark tránh xử lý lại | | | groupFiles gom tệp nhỏ khi đọc | |
Ba lưu ý về kích thước tệp: | Kích thước | Đánh giá | |---|---| | Dưới 10 MB | quá nhỏ | | 128-512 MB | tối ưu | | Trên 1 GB | giảm mức song song |
Ba lưu ý về chi phí: | Khoản | Ghi chú | |---|---| | Athena | 5 USD mỗi TB quét | | S3 lưu trữ | theo GB-tháng | | Phí yêu cầu S3 | đáng kể với nhiều tệp nhỏ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem DataScannedInBytes mỗi truy vấn | | | Chạy EXPLAIN kiểm partition pruning | | | So chi phí trước và sau khi đổi Parquet | |
Và một lời khuyên: hãy dùng partition projection thay vì crawler cho dữ liệu theo ngày. Log sinh ra mỗi ngày một phân vùng mới, và một crawler chạy theo lịch sẽ luôn chậm hơn dữ liệu vài giờ — còn projection thì suy ra phân vùng ngay từ mẫu đường dẫn, không bao giờ lỡ nhịp.
A company uses Amazon S3 storage service for storing its business data. Multiple S3 event notifications have been configured to be delivered to Amazon Simple Queue Service (Amazon SQS) queue when objects pass through the storage lifecycle. The team has noticed that notifications are not being delivered to the queue. Amazon SQS queue has server-side encryption (SSE) turned on.
What should be done to receive the S3 event notifications to an Amazon SQS queue that uses SSE?
-
A
Create an AWS-managed KMS key and configure the key policy to grant permissions to the Amazon S3 service principal
-
B
Create a customer-managed AWS KMS key and configure the key policy to grant permissions to the Amazon S3 service principal
-
C
Create an AWS-owned KMS key and configure the key policy to grant permissions to the Amazon S3 service principal
-
D
Create a KMS custom key store using Hardware Security Module (HSM) and configure the key policy to grant permissions to the Amazon S3 service principal
Xem giải thích
Đáp án
**B — Tạo một khoá KMS tự quản (customer-managed) và cấu hình chính sách khoá để cấp quyền cho service principal của Amazon S3.
Vì sao đúng
Đề mô tả một triệu chứng rất cụ thể:
S3 event notification cấu hình đúng
↓
SQS queue bật mã hoá phía máy chủ
↓
Thông báo KHÔNG tới hàng đợi
↓
Và không có lỗi rõ ràng nào
⚠ Điểm mấu chốt: S3 phải mã hoá tin nhắn khi gửi vào SQS đã bật SSE:
S3 gửi thông báo vào SQS
↓
SQS mã hoá tin bằng khoá KMS
↓
Nhưng người GỬI (S3) phải gọi
`kms:GenerateDataKey`
↓
Không có quyền → tin bị từ chối
im lặng
⚠ Và đây là lý do phải dùng khoá TỰ QUẢN: | Loại khoá | Sửa được chính sách khoá | |---|---| | AWS-owned key | KHÔNG — bạn không thấy nó | | AWS-managed key (aws/sqs) | KHÔNG — AWS quản | | Customer-managed key | CÓ |
Cần cấp quyền cho service principal
của S3
↓
Phải sửa chính sách khoá
↓
Chỉ khoá tự quản mới sửa được
Đây là lý do phương án A và C đều sai.
Chính sách khoá cho phép S3:
{"Version": "2012-10-17",
"Statement": [
{"Sid": "ChoPhepQuanTri",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*", "Resource": "*"},
{"Sid": "ChoPhepS3GuiThongBao",
"Effect": "Allow",
"Principal": {"Service": "s3.amazonaws.com"},
"Action": ["kms:GenerateDataKey", "kms:Decrypt"],
"Resource": "*",
"Condition": {"StringEquals": {
"aws:SourceAccount": "111122223333"}}}]}
⚠ Hai hành động đó đều cần — thiếu một là hỏng: | Hành động | Vì sao cần | |---|---| | kms:GenerateDataKey | sinh khoá dữ liệu để mã hoá tin nhắn | | kms:Decrypt | S3 cần trong quy trình mã hoá phong bì |
⚠ Và aws:SourceAccount chống confused deputy:
Không có điều kiện đó
↓
Bucket của tài khoản khác cũng
gửi được vào hàng đợi của bạn
↓
Và dùng khoá của bạn
→ chi phí và rủi ro
⚠ Và cần thêm aws:SourceArn cho chặt hơn:
"Condition": {
"StringEquals": {"aws:SourceAccount": "111122223333"},
"ArnLike": {"aws:SourceArn": "arn:aws:s3:::kho-du-lieu"}}
Gán khoá cho hàng đợi:
aws sqs set-queue-attributes --queue-url <url> \
--attributes '{
"KmsMasterKeyId": "arn:aws:kms:ap-southeast-1:111122223333:key/abc",
"KmsDataKeyReusePeriodSeconds": "300"}'
⚠ KmsDataKeyReusePeriodSeconds ảnh hưởng chi phí KMS:
Mặc định 300 giây
↓
SQS dùng lại khoá dữ liệu trong
khoảng đó
↓
Đặt dài hơn (tối đa 86.400) →
ít lời gọi KMS hơn
→ rẻ hơn, nhưng khoá dữ liệu
tồn tại lâu hơn
Và queue policy cho phép S3 gửi:
{"Effect": "Allow",
"Principal": {"Service": "s3.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:ap-southeast-1:111122223333:hang-doi-s3",
"Condition": {
"StringEquals": {"aws:SourceAccount": "111122223333"},
"ArnLike": {"aws:SourceArn": "arn:aws:s3:::kho-du-lieu"}}}
⚠ Hai chính sách phải có ĐỦ — đây là chỗ hay thiếu:
Queue policy: cho S3 GỬI tin
↓
Key policy: cho S3 MÃ HOÁ tin
↓
Có cái đầu, thiếu cái sau
→ tin bị từ chối
→ và không có thông báo lỗi nào
tới bạn
⚠ Và vì sao phương án D quá phức tạp:
D dùng KMS custom key store với HSM
↓
CloudHSM cluster cho khoá nằm
trong thiết bị chuyên dụng
↓
Đắt (khoảng 1,60 USD/giờ mỗi HSM)
và phức tạp
↓
Đề không có yêu cầu tuân thủ nào
đòi HSM
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Thông báo tới được hàng đợi | | | Tin nhắn vẫn được mã hoá | | | Kiểm soát được ai dùng khoá | |
⚠ Và cách chẩn đoán loại lỗi này:
S3 event notification thất bại im
lặng
↓
Không có chỉ số nào báo trực tiếp
↓
Kiểm bằng cách tạm tắt SSE của
hàng đợi
→ tin tới được → chắc chắn là
vấn đề KMS
⚠ Và CloudTrail ghi lại lời gọi KMS bị từ chối:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GenerateDataKey \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`)]'
⚠ Và cùng vấn đề xảy ra với SNS và EventBridge:
S3 → SNS topic có SSE
↓
EventBridge → SQS có SSE
↓
Lambda đọc từ SQS có SSE
↓
Mọi trường hợp đều cần cấp quyền
KMS cho bên gọi
⚠ Và Lambda đọc từ hàng đợi mã hoá cũng cần quyền:
{"Effect": "Allow",
"Action": ["kms:Decrypt"],
"Resource": "arn:aws:kms:ap-southeast-1:111122223333:key/abc"}
Execution role của Lambda
↓
Thiếu `kms:Decrypt`
→ event source mapping báo lỗi
và không xử lý được tin nào
⚠ Và S3 Bucket Keys không áp cho trường hợp này:
Bucket Keys giảm lời gọi KMS cho
việc mã hoá OBJECT
↓
Không liên quan tới việc gửi
thông báo
↓
Đây là hai luồng khác nhau
Vì sao các phương án khác sai
- **A. Tạo một AWS-managed KMS key và cấu hình chính sách khoá cấp quyền cho service principal của S3 — đây là phương án gần nhất và mô tả đúng việc cần làm, nhưng chính sách của khoá do AWS quản lý không sửa được; bạn không cấp thêm quyền cho ai được.
- **C. Tạo một AWS-owned KMS key — loại khoá này thậm chí không hiển thị trong tài khoản của bạn, hoàn toàn không cấu hình được.
- **D. Tạo KMS custom key store dùng HSM — giải pháp đúng về mặt kỹ thuật nhưng đắt và phức tạp quá mức cần thiết; đề không có yêu cầu tuân thủ nào đòi HSM chuyên dụng.
Ghi nhớ
⚠ Ba loại khoá KMS — bảng phải thuộc: | Loại | Ai quản | Sửa chính sách khoá | |---|---|---| | AWS-owned | AWS, dùng chung nhiều khách | KHÔNG thấy | | AWS-managed (aws/dichvu) | AWS, riêng tài khoản bạn | KHÔNG sửa được | | Customer-managed | bạn | CÓ |
Từ khoá nhận diện:
"grant service principal access to key" → customer-managed key "S3 notifications not reaching encrypted SQS" → thiếu quyền KMS "encryption key in dedicated hardware" → CloudHSM custom key store "rotate key automatically" → customer-managed key
Ba lưu ý về SSE-SQS: | Lưu ý | Chi tiết | |---|---| | SSE-SQS (khoá do SQS quản) miễn phí | | | SSE-KMS cho phép kiểm soát và kiểm toán | | | Người gửi và người nhận đều cần quyền KMS | |
⚠ SSE-SQS là lựa chọn đơn giản hơn nếu không cần kiểm soát khoá:
aws sqs set-queue-attributes --queue-url <url> \
--attributes SqsManagedSseEnabled=true
Mã hoá bằng khoá do SQS quản
↓
Không cần cấp quyền KMS cho ai
↓
Nhưng không kiểm toán được việc
dùng khoá
Ba lưu ý về chính sách khoá: | Lưu ý | Chi tiết | |---|---| | Khoá LUÔN cần chính sách khoá | | | IAM policy một mình không đủ | | | Luôn giữ câu cho phép quản trị viên | |
⚠ Khoá không có câu quản trị là khoá KHÔNG SỬA ĐƯỢC:
Xoá câu cho phép root
↓
Không ai sửa được chính sách nữa
↓
Phải liên hệ AWS Support
→ luôn giữ câu đó
Ba lưu ý về confused deputy: | Điều kiện | Chống gì | |---|---| | aws:SourceAccount | tài khoản khác lợi dụng dịch vụ | | aws:SourceArn | tài nguyên khác trong cùng tài khoản | | kms:ViaService | dùng khoá qua dịch vụ khác |
Ba lưu ý về chi phí KMS: | Khoản | Giá xấp xỉ | |---|---| | Mỗi khoá | 1 USD/tháng | | 10.000 lời gọi API | 0,03 USD | | Custom key store (CloudHSM) | ~1,60 USD/giờ mỗi HSM |
Ba lưu ý về S3 event notification: | Đích | Ghi chú | |---|---| | SQS | cần queue policy + key policy | | SNS | cần topic policy + key policy | | Lambda | cần resource-based policy | | EventBridge | chỉ cần bật, không cần policy |
⚠ EventBridge là đích đơn giản nhất:
aws s3api put-bucket-notification-configuration \
--bucket kho-du-lieu \
--notification-configuration '{"EventBridgeConfiguration": {}}'
Không cần cấp quyền gì cho S3
↓
Rồi EventBridge định tuyến tới
SQS, Lambda, Step Functions...
Ba lưu ý về chẩn đoán: | Việc | Cách | |---|---| | Tạm tắt SSE để khoanh vùng | | | Đọc CloudTrail tìm GenerateDataKey bị từ chối | | | Kiểm cả queue policy lẫn key policy | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tải lên một object và xem tin có vào hàng đợi | | | Kiểm NumberOfMessagesSent của hàng đợi | | | Xem CloudTrail có lời gọi KMS thành công | |
Và một lời khuyên: hãy cấp quyền KMS cho service principal cùng lúc với việc cấu hình queue policy. Hai chính sách này luôn đi cùng nhau nhưng nằm ở hai nơi khác nhau, và thiếu cái thứ hai gây ra một lỗi hoàn toàn im lặng — không có tin nhắn, không có lỗi, không có chỉ số nào thay đổi.
The research department at a healthcare company stores its entire data on Amazon S3. The research department is concerned about the increased costs of storing large amounts of data, most of which is in the form of images. As of now, all data is stored using the S3 Standard storage class. The research department has the following data archival requirements:
-
Need optimum storage for medical reports that are accessed infrequently (about twice a year). But, when accessed, the data has to be retrieved in real-time.
-
Need optimum storage for medical images that are accessed very rarely but have to be stored durably for up to 10 years. These images can be retrieved in a flexible time frame.
What will you recommend as the most cost-effective storage option that addresses the given requirements?
-
A
Amazon S3 Intelligent-Tiering (S3 Intelligent-Tiering) is the best fit for data accessed twice a year. Amazon S3 Glacier is cost-effective for data that is stored for long-term retention
-
B
Amazon S3 Glacier Deep Archive alone caters to both the above-mentioned requirements
-
C
Amazon S3 Glacier Instant Retrieval is the best fit for data accessed twice a year. Amazon S3 Glacier Deep Archive is cost-effective for data that is stored for long-term retention
-
D
Amazon S3 Glacier Flexible Retrieval is the best fit for data accessed twice a year. Amazon S3 Glacier Deep Archive is cost-effective for data that is stored for long-term retention
Xem giải thích
Đáp án
**C — S3 Glacier Instant Retrieval cho dữ liệu truy cập hai lần mỗi năm, và S3 Glacier Deep Archive cho dữ liệu lưu trữ dài hạn.
Vì sao đúng
Đề nêu hai nhóm dữ liệu với hai yêu cầu khác nhau, và mỗi nhóm có một lớp lưu trữ tối ưu: | Nhóm | Yêu cầu | Lớp | |---|---|---| | Báo cáo y tế | truy cập ~2 lần/năm, lấy ra THỜI GIAN THỰC | Glacier Instant Retrieval | | Ảnh y tế | rất hiếm khi truy cập, giữ 10 năm, thời gian lấy LINH HOẠT | Glacier Deep Archive |
⚠ Điểm mấu chốt thứ nhất: "lấy ra thời gian thực" loại mọi lớp cần khôi phục:
Glacier Flexible Retrieval:
1 phút - 12 giờ
↓
Glacier Deep Archive: 12-48 giờ
↓
Cả hai đều phải KHÔI PHỤC trước
↓
Glacier Instant Retrieval: đọc
NGAY như S3 Standard
Đây là lý do phương án D sai — nó dùng Flexible Retrieval cho dữ liệu cần đọc ngay.
⚠ Và Glacier Instant Retrieval là lớp ít người biết nhưng rất hợp ở đây: | Lớp | Giá lưu trữ | Thời gian lấy | Tối thiểu | |---|---|---|---| | Standard | 0,023 USD/GB | tức thì | không | | Standard-IA | 0,0125 USD/GB | tức thì | 30 ngày | | Glacier Instant Retrieval | 0,004 USD/GB | tức thì | 90 ngày | | Glacier Flexible Retrieval | 0,0036 USD/GB | phút tới giờ | 90 ngày | | Glacier Deep Archive | 0,00099 USD/GB | 12-48 giờ | 180 ngày |
Glacier Instant Retrieval rẻ hơn
Standard-IA khoảng 68%
↓
Mà vẫn đọc tức thì
↓
Đổi lại: phí lấy ra cao hơn
(0,03 vs 0,01 USD/GB)
→ hợp khi truy cập RẤT ít
⚠ Và "hai lần mỗi năm" đúng là mức mà Instant Retrieval thắng:
Truy cập vài lần mỗi tháng
↓
Standard-IA rẻ hơn (phí lấy ra
thấp hơn)
↓
Truy cập vài lần mỗi NĂM
→ Instant Retrieval rẻ hơn nhiều
(phí lưu trữ thấp hơn 68%)
⚠ Điểm mấu chốt thứ hai: "thời gian lấy linh hoạt" cho phép Deep Archive:
Ảnh y tế giữ 10 năm
↓
Rất hiếm khi cần
↓
Khi cần thì chờ được
↓
Deep Archive rẻ hơn Standard
23 lần
⚠ Và giữ 10 năm thì phí tối thiểu 180 ngày không thành vấn đề:
Deep Archive tính tối thiểu 180 ngày
↓
Dữ liệu ở đó 10 năm
↓
Không bao giờ chạm ràng buộc đó
Luật vòng đời cho hai nhóm:
{"Rules": [
{"ID": "bao-cao-sang-instant-retrieval",
"Filter": {"Prefix": "bao-cao/"},
"Status": "Enabled",
"Transitions": [{"Days": 90,
"StorageClass": "GLACIER_IR"}]},
{"ID": "anh-sang-deep-archive",
"Filter": {"Prefix": "anh-y-te/"},
"Status": "Enabled",
"Transitions": [{"Days": 30,
"StorageClass": "DEEP_ARCHIVE"}],
"Expiration": {"Days": 3700}}]}
⚠ Và vì sao phương án B sai — Deep Archive không đáp ứng nhóm thứ nhất:
B nói Deep Archive lo được CẢ HAI
↓
Báo cáo cần lấy ra THỜI GIAN THỰC
↓
Deep Archive mất 12-48 giờ
→ vi phạm yêu cầu
⚠ Và vì sao phương án A không tối ưu:
A dùng Intelligent-Tiering cho
báo cáo
↓
Intelligent-Tiering tự chuyển
tầng theo mẫu truy cập
↓
Nhưng đề đã BIẾT rõ mẫu truy cập
(2 lần/năm)
→ không cần trả phí giám sát
⚠ Intelligent-Tiering có phí giám sát mỗi object:
~0,0025 USD cho 1.000 object mỗi
tháng
↓
Với hàng triệu ảnh, khoản này
đáng kể
↓
Biết rõ mẫu truy cập
→ đặt luật vòng đời trực tiếp
rẻ hơn
⚠ Nhưng Intelligent-Tiering có ưu điểm riêng: | Tiêu chí | Intelligent-Tiering | Vòng đời thủ công | |---|---|---| | Phí lấy ra | KHÔNG có | có | | Phí giám sát | có | không | | Cần biết mẫu truy cập | không | CÓ |
Không đoán được mẫu truy cập
↓
Intelligent-Tiering an toàn hơn
↓
Đề mô tả rõ mẫu
→ vòng đời trực tiếp tối ưu hơn
⚠ Và Intelligent-Tiering cũng có tầng lưu trữ sâu:
aws s3api put-bucket-intelligent-tiering-configuration \
--bucket du-lieu-y-te --id tu-phan-tang \
--intelligent-tiering-configuration '{
"Id": "tu-phan-tang", "Status": "Enabled",
"Tierings": [
{"Days": 90, "AccessTier": "ARCHIVE_ACCESS"},
{"Days": 180, "AccessTier": "DEEP_ARCHIVE_ACCESS"}]}'
Hai tầng cuối là TUỲ CHỌN
↓
Bật thì object có thể xuống tầng
cần khôi phục
↓
Không bật: chỉ Frequent, Infrequent,
Archive Instant Access — đều
đọc ngay
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Báo cáo vẫn đọc ngay, rẻ hơn 82% so với Standard | | | Ảnh lưu 10 năm với chi phí thấp nhất | | | Mỗi nhóm dữ liệu đúng lớp của nó | |
⚠ Và tính thử với 100 TB mỗi nhóm:
Báo cáo 100 TB:
Standard: ~2.300 USD/tháng
Glacier IR: ~400 USD/tháng
↓
Ảnh 100 TB:
Standard: ~2.300 USD/tháng
Deep Archive: ~99 USD/tháng
↓
Tổng tiết kiệm: ~4.100 USD/tháng
⚠ Và với dữ liệu y tế cần chú ý tuân thủ:
HIPAA đòi mã hoá khi lưu
↓
SSE-KMS với khoá riêng
↓
Và Object Lock nếu cần WORM
↓
Bật CloudTrail data event để
ghi lại ai đọc ảnh nào
⚠ Và kích thước object tối thiểu cần chú ý: | Lớp | Tối thiểu tính tiền | |---|---| | Standard-IA, One Zone-IA | 128 KB | | Glacier Instant Retrieval | 128 KB | | Glacier Flexible, Deep Archive | 40 KB |
Ảnh y tế thường lớn
↓
Không chạm ràng buộc này
↓
Nhưng báo cáo dạng văn bản nhỏ
→ cân nhắc gom lại
Vì sao các phương án khác sai
- **D. Glacier Flexible Retrieval cho dữ liệu truy cập hai lần mỗi năm và Deep Archive cho lưu trữ dài hạn — đây là phương án gần nhất và vế thứ hai hoàn toàn đúng, nhưng Flexible Retrieval cần khôi phục từ 1 phút tới 12 giờ, không đáp ứng yêu cầu lấy ra thời gian thực.
- **A. Intelligent-Tiering cho dữ liệu truy cập hai lần mỗi năm và Glacier cho lưu trữ dài hạn — Intelligent-Tiering hợp khi không đoán được mẫu truy cập; ở đây mẫu đã rõ nên trả phí giám sát là thừa.
- **B. Chỉ dùng Glacier Deep Archive cho cả hai — không đáp ứng yêu cầu lấy ra thời gian thực của nhóm báo cáo.
Ghi nhớ
⚠ Sáu lớp lưu trữ S3 theo thời gian lấy ra — bảng phải thuộc: | Lớp | Lấy ra | Hợp với | |---|---|---| | Standard | tức thì | truy cập thường xuyên | | Standard-IA | tức thì | vài lần mỗi tháng | | Glacier Instant Retrieval | tức thì | vài lần mỗi NĂM | | Glacier Flexible Retrieval | 1 phút - 12 giờ | lưu trữ, chờ được | | Glacier Deep Archive | 12-48 giờ | tuân thủ dài hạn | | Intelligent-Tiering | tuỳ tầng | mẫu truy cập không đoán được |
Từ khoá nhận diện:
"accessed twice a year, real-time retrieval" → Glacier Instant Retrieval "rarely accessed, flexible retrieval time" → Deep Archive "unknown access pattern" → Intelligent-Tiering "must retrieve in minutes" → Flexible Retrieval chế độ Expedited
Ba lưu ý về phí lấy ra: | Lớp | Phí lấy ra xấp xỉ | |---|---| | Standard-IA | 0,01 USD/GB | | Glacier Instant Retrieval | 0,03 USD/GB | | Glacier Flexible (Bulk) | 0,0025 USD/GB | | Deep Archive (Standard) | 0,02 USD/GB |
⚠ Phí lấy ra quyết định lớp nào rẻ hơn:
Truy cập nhiều → phí lấy ra lấn át
↓
Truy cập ít → phí lưu trữ lấn át
↓
Tính điểm hoà vốn cho từng
trường hợp
Ba lưu ý về ba tốc độ lấy ra của Glacier: | Tốc độ | Flexible | Deep Archive | |---|---|---| | Expedited | 1-5 phút | không có | | Standard | 3-5 giờ | 12 giờ | | Bulk | 5-12 giờ | 48 giờ |
Ba lưu ý về phí tối thiểu: | Lớp | Thời gian | |---|---| | IA | 30 ngày | | Glacier IR, Flexible | 90 ngày | | Deep Archive | 180 ngày |
Ba lưu ý về vòng đời: | Lưu ý | Chi tiết | |---|---| | Phí chuyển tầng theo số object | | | Gom tệp nhỏ trước khi chuyển | | | Lọc theo tiền tố hoặc thẻ | |
Ba lưu ý về dữ liệu y tế: | Lưu ý | Chi tiết | |---|---| | Mã hoá SSE-KMS với khoá riêng | | | Object Lock nếu cần WORM | | | CloudTrail data event ghi truy cập | |
Ba lưu ý về S3 Storage Lens: | Lưu ý | Chi tiết | |---|---| | Xem phân bố lớp lưu trữ toàn tài khoản | | | Đề xuất tối ưu chi phí | | | Bản miễn phí có 28 chỉ số | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đọc một báo cáo — phải tức thì | | | Khôi phục thử một ảnh và bấm giờ | | | So chi phí trong Cost Explorer | |
Và một lời khuyên: hãy cân nhắc Glacier Instant Retrieval mỗi khi thấy yêu cầu "ít truy cập nhưng phải đọc ngay". Rất nhiều kiến trúc mặc định chọn Standard-IA cho trường hợp này, trong khi Instant Retrieval rẻ hơn 68% về lưu trữ và vẫn đọc tức thì — chỉ cần tần suất truy cập thật sự thấp.
A media company uses Amazon S3 under the hood to power its offerings which allow the customers to upload and view the media files immediately. Currently, all the customer files are uploaded directly under a single S3 bucket. The systems administration team has started seeing scalability issues where customer file uploads are failing during the peak access hours with more than 5000 requests per second.
Which of the following represents the MOST resource-efficient and cost-optimal way of resolving this issue?
-
A
Change the application architecture to create a new S3 bucket for each day's data and then upload the daily files directly under that day's bucket
-
B
Change the application architecture to create a new S3 bucket for each customer and then upload each customer's files directly under the respective buckets
-
C
Change the application architecture to use S3 Glacier Deep Archive storage class
-
D
Change the application architecture to create customer-specific custom prefixes within the single bucket and then upload the daily files into those prefixed locations
Xem giải thích
Đáp án
**D — Đổi kiến trúc ứng dụng để tạo tiền tố (prefix) riêng cho từng khách hàng trong CÙNG một bucket, rồi tải tệp vào các vị trí có tiền tố đó.
Vì sao đúng
Đề mô tả một giới hạn rất cụ thể của S3:
Mọi tệp đổ vào MỘT bucket, không
có tiền tố phân biệt
↓
Hơn 5.000 yêu cầu mỗi giây
↓
Tải lên bắt đầu thất bại
↓
→ chạm giới hạn thông lượng
theo TIỀN TỐ
⚠ Điểm mấu chốt: hạn ngạch của S3 tính theo TIỀN TỐ, không theo bucket: | Thao tác | Giới hạn mỗi tiền tố | |---|---| | PUT, COPY, POST, DELETE | 3.500 yêu cầu/giây | | GET, HEAD | 5.500 yêu cầu/giây |
Một tiền tố → chạm trần
↓
Nhiều tiền tố → hạn ngạch nhân lên
↓
10 tiền tố → 35.000 PUT/giây
⚠ Và bucket KHÔNG có giới hạn thông lượng riêng:
Số bucket không quyết định thông
lượng
↓
Tách ra nhiều bucket không giúp
gì hơn nhiều tiền tố
↓
Mà lại thêm rất nhiều việc quản lý
⚠ Và đây là lý do phương án A và B kém hơn:
B: một bucket cho mỗi khách hàng
↓
Hạn ngạch mặc định 100 bucket
mỗi tài khoản (nâng lên 1.000)
↓
Hàng nghìn khách hàng
→ chạm trần
↓
Và phải quản chính sách, vòng đời,
giám sát cho từng bucket
A: một bucket cho mỗi NGÀY
↓
Không giải quyết vấn đề đồng thời
trong cùng một ngày
↓
Và tích luỹ hàng nghìn bucket
theo thời gian
Cấu trúc tiền tố theo khách hàng:
s3://kho-media/khach-hang-a1b2/2026/09/tep.mp4
s3://kho-media/khach-hang-c3d4/2026/09/tep.mp4
import boto3, hashlib
s3 = boto3.client('s3')
def tai_len(ma_khach, ten_tep, du_lieu):
khoa = f'{ma_khach}/{nam}/{thang}/{ten_tep}'
s3.put_object(Bucket='kho-media', Key=khoa, Body=du_lieu)
⚠ Và tiền tố là mọi thứ trước ký tự cuối cùng trong khoá:
`khach-hang-a1b2/2026/09/tep.mp4`
↓
S3 chia phân vùng theo tiền tố
↓
Mỗi khách hàng có không gian
thông lượng riêng
⚠ Và S3 tự chia phân vùng theo thời gian:
Tiền tố mới bắt đầu ở một phân vùng
↓
Lưu lượng tăng → S3 tự tách
phân vùng
↓
Quá trình đó mất khoảng 30-60 phút
↓
Đỉnh tải đột ngột vẫn có thể bị
chặn tạm thời
⚠ Và với đỉnh tải rất cao, nên báo trước cho AWS:
Sự kiện dự kiến hàng chục nghìn
yêu cầu/giây
↓
Mở ticket Support để AWS chuẩn
bị phân vùng
↓
Hoặc tăng tải dần trong vài giờ
⚠ Và vì sao phương án C hoàn toàn sai hướng:
C chuyển sang Glacier Deep Archive
↓
Đề nói khách hàng "xem tệp NGAY
LẬP TỨC"
↓
Deep Archive mất 12-48 giờ để
lấy ra
→ phá hỏng chức năng chính
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Thông lượng nhân lên theo số khách | | | Vẫn một bucket, một bộ chính sách | | | Không chạm hạn ngạch số bucket | |
⚠ Và tiền tố theo khách hàng còn giúp phân quyền:
{"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::kho-media/${aws:userid}/*"}
Mỗi khách chỉ chạm được thư mục
của mình
↓
Một chính sách cho mọi khách
→ không phải viết lại khi thêm
khách mới
⚠ Và phân bổ chi phí theo tiền tố bằng S3 Storage Lens:
Storage Lens nhóm theo tiền tố
↓
Biết khách nào dùng nhiều dung
lượng
↓
Bucket riêng cũng làm được
→ nhưng tiền tố đủ và đơn giản
hơn
Ghi nhớ về chất lượng câu hỏi
⚠ Lời khuyên "rải tiền tố ngẫu nhiên" đã LỖI THỜI từ tháng 7/2018.
Trước 2018: S3 chia phân vùng theo
TIỀN TỐ TỪ TRÁI SANG
↓
Tiền tố tuần tự (theo ngày) →
dồn vào một phân vùng
↓
Phải thêm hash ngẫu nhiên vào đầu
khoá
↓
Ví dụ: `a3f9/2026-09-01/tep.mp4`
Từ 7/2018: S3 tự chia phân vùng
thông minh
↓
3.500 PUT và 5.500 GET mỗi giây
MỖI TIỀN TỐ
↓
Không cần hash ngẫu nhiên nữa
→ tổ chức tiền tố theo NGHIỆP VỤ
Với kiến thức hiện tại, đáp án D vẫn đúng nhưng vì lý do khác: tiền tố theo khách hàng cho thông lượng nhân lên, chứ không phải để "phá vỡ tính tuần tự" như hướng dẫn cũ.
Và có một điểm nữa đáng nhắc: đề nói lỗi xảy ra ở mức "hơn 5.000 yêu cầu mỗi giây". Con số 5.500 là giới hạn GET, còn PUT chỉ 3.500 — nên với việc tải lên, ngưỡng thật thấp hơn con số đề đưa ra.
Vì sao các phương án khác sai
- **B. Tạo một bucket riêng cho mỗi khách hàng và tải tệp vào bucket tương ứng — đây là phương án gần nhất và thật sự tách được thông lượng, nhưng hạn ngạch số bucket mỗi tài khoản chỉ 100 (nâng tối đa 1.000), và phải quản lý chính sách, vòng đời, giám sát cho từng bucket.
- **A. Tạo một bucket mới cho dữ liệu mỗi ngày — không giải quyết được vấn đề đồng thời trong cùng một ngày, và tích luỹ bucket vô hạn theo thời gian.
- **C. Chuyển sang lớp Glacier Deep Archive — khách hàng cần xem tệp ngay lập tức, còn Deep Archive mất 12-48 giờ để lấy ra.
Ghi nhớ
⚠ Hạn ngạch thông lượng của S3 — bảng phải thuộc: | Thao tác | Giới hạn mỗi tiền tố | |---|---| | PUT, COPY, POST, DELETE | 3.500/giây | | GET, HEAD | 5.500/giây | | Số bucket mỗi tài khoản | 100 (nâng tới 1.000) | | Kích thước object tối đa | 5 TB |
Từ khoá nhận diện:
"5,000 requests per second failing" → chạm giới hạn theo tiền tố "random hash prefix" → lời khuyên LỖI THỜI từ 2018 "one bucket per customer" → chạm hạn ngạch bucket "immediate access required" → không dùng Glacier Flexible/Deep
Ba lưu ý về tiền tố: | Lưu ý | Chi tiết | |---|---| | S3 tự chia phân vùng theo tiền tố | | | Chia phân vùng mất 30-60 phút | | | Tổ chức tiền tố theo nghiệp vụ, không cần hash | |
⚠ Đỉnh tải đột ngột vẫn có thể bị chặn:
Tiền tố mới, lưu lượng tăng vọt
↓
S3 chưa kịp chia phân vùng
↓
Nhận lỗi 503 SlowDown
↓
SDK tự thử lại với exponential
backoff
Ba lưu ý về xử lý lỗi 503: | Lưu ý | Chi tiết | |---|---| | SDK mặc định có retry với backoff | | | Tăng max_attempts nếu cần | | | Tăng tải dần thay vì đột ngột | |
from botocore.config import Config
s3 = boto3.client('s3', config=Config(
retries={'max_attempts': 10, 'mode': 'adaptive'}))
Ba lưu ý về multipart upload: | Lưu ý | Chi tiết | |---|---| | Mỗi phần là một yêu cầu PUT riêng | | | Tăng số yêu cầu, nhưng tăng thông lượng | | | Đặt luật dọn phần dở dang | |
Ba lưu ý về S3 Transfer Acceleration: | Lưu ý | Chi tiết | |---|---| | Tăng tốc đường đi, không tăng hạn ngạch | | | Không giải quyết vấn đề chặn theo tiền tố | | | Chỉ tính phí khi thật sự nhanh hơn | |
Ba lưu ý về giám sát: | Chỉ số | Ý nghĩa | |---|---| | 5xxErrors | có bị chặn không | | AllRequests | tổng số yêu cầu | | FirstByteLatency | độ trễ phản hồi |
⚠ Bật request metrics để thấy chi tiết:
aws s3api put-bucket-metrics-configuration \
--bucket kho-media --id toan-bo \
--metrics-configuration '{"Id": "toan-bo"}'
Ba lưu ý về S3 Storage Lens: | Lưu ý | Chi tiết | |---|---| | Nhóm chỉ số theo tiền tố | | | Thấy khách nào dùng nhiều nhất | | | Đề xuất tối ưu chi phí | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy thử tải với đỉnh dự kiến | | | Kiểm 5xxErrors có về 0 không | | | Xem phân bố yêu cầu theo tiền tố | |
Và một lời khuyên: hãy tăng tải dần thay vì bật đột ngột lên mức đỉnh. S3 tự chia phân vùng theo tiền tố nhưng quá trình đó mất nửa tiếng — nên một chiến dịch bật cùng lúc cho hàng nghìn khách hàng sẽ gặp lỗi 503 trong giai đoạn đầu dù cấu trúc tiền tố đã đúng.
A company has many AWS accounts for its different business units. As per the company's policy, developers should have limited access to a few AWS Regions (known as Core Regions). This restricted access was implemented using custom code. The company now wants to use AWS services to implement this restriction and relinquish the custom application.
Which of the following represents the most optimal solution that is easy to set up and maintain?
-
A
Use Permissions boundaries on IAM users belonging to Non-Core Regions to restrict access to Core Regions. Use an AWS managed policy to create the necessary Permissions boundary
-
B
Create IAM Groups for users in Core and Non-Core Regions. Attach appropriate IAM policies to implement restrictions on user access belonging to each of these IAM Groups
-
C
Set up AWS Single Sign-On and attach the AWS accounts of all business units. Create permission sets with policies to restrict access to Non-Core Regions. Create IAM users and IAM groups in each account
-
D
Enable AWS Organizations and attach the AWS accounts of all business units to it. Create a Service Control Policy to deny access to the Non-Core Regions and attach the policy to the root OU
Xem giải thích
Đáp án
**D — Bật AWS Organizations, đưa tài khoản của mọi đơn vị kinh doanh vào, tạo một Service Control Policy từ chối truy cập các Region không phải Core, và gắn SCP đó vào root OU.
Vì sao đúng
Đề nêu ba yêu cầu, và SCP đáp ứng cả ba: | Yêu cầu | Cách đáp ứng | |---|---| | Áp cho NHIỀU tài khoản | SCP gắn vào root OU | | Bỏ được ứng dụng tự viết | dịch vụ có sẵn, không viết mã | | Dễ dựng và dễ bảo trì | một chính sách cho toàn tổ chức |
⚠ Điểm mấu chốt: SCP là cách duy nhất áp ràng buộc cho nhiều tài khoản bằng một lần:
IAM policy: gắn vào từng user,
group, role
↓
Nhiều tài khoản → phải làm ở
từng tài khoản
↓
SCP: gắn vào OU
→ mọi tài khoản trong đó tự
thừa hưởng
SCP chặn Region không phải Core:
{"Version": "2012-10-17",
"Statement": [{
"Sid": "ChanRegionNgoaiDanhSach",
"Effect": "Deny",
"NotAction": [
"iam:*", "organizations:*", "route53:*",
"cloudfront:*", "support:*", "sts:*",
"waf:*", "shield:*", "budgets:*",
"globalaccelerator:*", "health:*"],
"Resource": "*",
"Condition": {"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "ap-southeast-1"]}}}]}
⚠ NotAction với các dịch vụ TOÀN CẦU là bắt buộc:
IAM, Organizations, CloudFront,
Route 53 có endpoint ở us-east-1
↓
Không loại trừ → chặn luôn cả
việc tạo IAM user
↓
Tài khoản gần như không dùng
được
⚠ Và aws:RequestedRegion là khoá điều kiện phải nhớ:
Nó là Region mà LỜI GỌI API nhắm tới
↓
Không phải Region của người gọi
→ không phải Region của tài
nguyên đã có
↓
Chặn được ngay lúc tạo
⚠ Và vì sao phương án B không mở rộng được:
B tạo IAM group ở mỗi tài khoản
↓
Đề nói có NHIỀU tài khoản
↓
Phải tạo group và chính sách ở
từng tài khoản
↓
Và quản trị viên tài khoản đó
sửa được
→ không phải ràng buộc thật
⚠ Và vì sao phương án A không đúng cách dùng:
A dùng permissions boundary trên
IAM user "thuộc Region không phải
Core"
↓
IAM user không thuộc Region nào
↓
IAM là dịch vụ toàn cầu
→ khái niệm "user của Region X"
không tồn tại
⚠ Nhưng permissions boundary vẫn là công cụ hợp lệ cho việc khác:
Uỷ quyền cho đội tự tạo vai trò
↓
Đặt boundary giới hạn quyền tối
đa của vai trò họ tạo
↓
Chống leo thang quyền
⚠ Và vì sao phương án C phức tạp hơn cần thiết:
C dùng IAM Identity Center với
permission set
↓
Rồi lại "tạo IAM user và IAM
group ở mỗi tài khoản"
↓
Hai cơ chế mâu thuẫn nhau
↓
Identity Center sinh ra để KHÔNG
cần IAM user ở từng tài khoản
⚠ Nhưng Identity Center với permission set là lựa chọn hợp lý:
{"Effect": "Deny", "NotAction": ["iam:*", "sts:*"],
"Resource": "*",
"Condition": {"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1"]}}}
Gắn chính sách đó vào permission set
↓
Áp cho mọi tài khoản mà permission
set được gán
↓
Nhưng SCP mạnh hơn: nó chặn cả
quản trị viên tài khoản
⚠ Và có một cách thứ ba: tắt hẳn Region:
aws account disable-region \
--region-name eu-west-1 \
--account-id 222222222222
Tắt Region ở cấp tài khoản
↓
Không ai dùng được, kể cả root
↓
Nhưng chỉ áp cho Region bật/tắt
được (Region ra sau 2019)
↓
Region cũ luôn bật, không tắt
được
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một chính sách cho toàn tổ chức | | | Tài khoản mới tự thừa hưởng | | | Quản trị viên tài khoản không gỡ được | |
⚠ Và SCP áp cả cho root user của tài khoản thành viên:
Đây là điều IAM policy không làm
được
↓
Root luôn có toàn quyền trong
tài khoản
↓
SCP là ranh giới duy nhất chặn
được root
⚠ Nhưng SCP KHÔNG áp cho tài khoản quản lý:
Tài khoản quản lý miễn nhiễm mọi SCP
↓
Đừng chạy workload trong đó
↓
Nếu cần chặn cả nó → phải dùng
IAM policy riêng
⚠ Và nên thử trên OU nhỏ trước khi gắn vào root:
aws organizations attach-policy \
--policy-id p-abc123 \
--target-id ou-thu-nghiem
Gắn vào root ngay
↓
Chặn nhầm một dịch vụ nào đó
↓
Cả tổ chức bị ảnh hưởng
↓
Thử trên một OU trước
⚠ Và nên rà CloudTrail trước khi áp:
SELECT awsregion, eventsource, COUNT(*) AS so_luot
FROM cloudtrail_logs
WHERE eventtime > '2026-08-01'
GROUP BY awsregion, eventsource
ORDER BY so_luot DESC;
Xem thực tế đang dùng Region nào
↓
Phát hiện dịch vụ nào đó chạy ở
Region ngoài danh sách
→ tránh chặn nhầm
Vì sao các phương án khác sai
- **C. Dùng IAM Identity Center, tạo permission set giới hạn Region, và tạo IAM user và IAM group ở mỗi tài khoản — đây là phương án gần nhất và Identity Center với permission set thật sự áp được ràng buộc Region cho nhiều tài khoản, nhưng vế cuối mâu thuẫn: Identity Center sinh ra để không cần IAM user ở từng tài khoản.
- **B. Tạo IAM group cho người dùng ở Core và không phải Core, gắn chính sách tương ứng — phải làm ở từng tài khoản, và quản trị viên tài khoản gỡ được.
- **A. Dùng permissions boundary trên IAM user thuộc Region không phải Core — IAM là dịch vụ toàn cầu, không có khái niệm user thuộc một Region.
Ghi nhớ
⚠ Bốn cách giới hạn theo Region — bảng phải thuộc: | Cách | Phạm vi | Ai gỡ được | |---|---|---| | SCP | toàn tổ chức hoặc OU | chỉ tài khoản quản lý | | Permission set (Identity Center) | người dùng liên kết | quản trị Identity Center | | IAM policy | một danh tính | quản trị viên tài khoản | | Tắt Region | cả tài khoản | root của tài khoản |
Từ khoá nhận diện:
"restrict Regions across many accounts" → SCP gắn vào root OU "prevent even the account admin" → SCP "replace custom application with AWS service" → Organizations + SCP "delegate role creation safely" → permissions boundary
Ba lưu ý về SCP: | Lưu ý | Chi tiết | |---|---| | KHÔNG cấp quyền, chỉ giới hạn | | | KHÔNG áp cho tài khoản quản lý | | | KHÔNG áp cho service-linked role | |
⚠ Dịch vụ toàn cầu phải loại trừ:
iam, organizations, route53,
cloudfront, support, sts,
waf, shield, globalaccelerator,
budgets, health, artifact
↓
Endpoint của chúng ở us-east-1
↓
Chặn Region → chặn luôn chúng
Ba lưu ý về aws:RequestedRegion: | Lưu ý | Chi tiết | |---|---| | Là Region mà lời gọi API nhắm tới | | | Dùng với StringNotEquals để chặn | | | Kết hợp NotAction cho dịch vụ toàn cầu | |
Ba lưu ý về triển khai SCP: | Lưu ý | Chi tiết | |---|---| | Thử trên OU nhỏ trước | | | Rà CloudTrail tìm lời gọi sẽ bị chặn | | | Đọc errorMessage để biết SCP hay IAM chặn | |
⚠ CloudTrail nói rõ lớp nào từ chối:
"errorMessage": "... with an explicit deny
in a service control policy"
Ba chiến lược SCP: | Chiến lược | Cách làm | |---|---| | Deny list | giữ FullAWSAccess + thêm Deny — khuyến nghị | | Allow list | gỡ FullAWSAccess, chỉ Allow cái cần | | Hỗn hợp | Allow rộng ở root, Deny hẹp ở OU |
Ba lưu ý về Control Tower: | Lưu ý | Chi tiết | |---|---| | Dựng sẵn landing zone nhiều tài khoản | | | Guardrail = SCP + Config rule đóng gói | | | Có sẵn guardrail giới hạn Region | |
Ba lưu ý về chi phí: | Lưu ý | Chi tiết | |---|---| | Organizations và SCP miễn phí | | | Chặn Region ngăn chi phí bất ngờ | | | Cost Anomaly Detection bổ trợ | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Thử tạo EC2 ở Region bị cấm — phải bị từ chối | | | Thử tạo IAM user — phải chạy được | | | Kiểm tài khoản mới có thừa hưởng SCP | |
Và một lời khuyên: hãy rà CloudTrail của vài tuần gần nhất trước khi gắn SCP vào root OU. Một chính sách chặn Region trông rất đơn giản thường vô tình chặn một dịch vụ toàn cầu nào đó mà không ai nghĩ tới — và khi gắn ở root thì mọi tài khoản trong tổ chức đều hỏng cùng lúc.
A company wants to migrate its on-premises resources to AWS. The IT environment consists of 200 virtual machines (VMs) with a combined storage capacity of 50 TB. While the majority of VMs may be taken down for migration since they are only used during business hours, others are mission-critical, so the downtime must be minimized. The on-premises network engineer has allocated 10 Mbps of internet bandwidth for the migration. The capacity of the on-premises network has peaked and increasing it would be prohibitively expensive.
You have been hired as an AWS Certified Solutions Architect Professional to develop a migration strategy that can be implemented in the next three months. Which of the following would you recommend?
-
A
Leverage AWS Migration Hub to analyze each application for further refactoring and optimizations using AWS services or AWS Marketplace solutions
-
B
Migrate mission-critical VMs using AWS Application Migration Service (MGN). Export the other VMs locally and transfer them to Amazon S3 using AWS Snowball Edge. Leverage VM Import/Export to import the VMs into Amazon EC2
-
C
Create a 10 Gbps AWS Direct Connect connection and then configure a private virtual interface. Leverage AWS Server Migration Service (SMS) to migrate the VMs into Amazon EC2
-
D
Export the VMs locally, starting with the most mission-critical servers first. Configure a 1.25 Gbps AWS site-to-site VPN to securely upload each VM to Amazon S3 after they are exported. Use VM Import/Export to import the VMs into Amazon EC2
Xem giải thích
Đáp án
**B — Di trú các máy ảo trọng yếu bằng AWS Application Migration Service (MGN); xuất các máy còn lại ra tại chỗ và chuyển sang Amazon S3 bằng AWS Snowball Edge; rồi dùng VM Import/Export để nhập chúng thành EC2.
Vì sao đúng
Đề cho những con số phải ghép lại:
200 máy ảo, tổng 50 TB
↓
Băng thông chỉ 10 Mbps
→ và không tăng thêm được
↓
Phải xong trong 3 tháng
↓
Phần lớn máy được phép dừng
→ một số ít thì không
⚠ Tính thời gian truyền 50 TB qua 10 Mbps:
50 TB = 400.000.000 Mb
↓
Ở 10 Mbps: 40.000.000 giây
= 463 NGÀY
↓
Hiệu suất thực tế còn thấp hơn
→ hơn một năm
↓
Hạn là 3 tháng → hoàn toàn
không khả thi qua mạng
⚠ Điểm mấu chốt: đề chia máy thành hai nhóm với hai cách xử lý: | Nhóm | Ràng buộc | Cách di trú | |---|---|---| | Trọng yếu | ngừng dịch vụ tối thiểu | MGN qua mạng | | Còn lại | dừng được | Snowball Edge |
⚠ Và MGN cho nhóm trọng yếu là đúng vì nó sao chép LIÊN TỤC:
MGN cài Replication Agent trên máy
nguồn
↓
Sao chép block-level liên tục
↓
Máy nguồn VẪN CHẠY suốt quá trình
↓
Cutover chỉ mất vài phút
⚠ Và số máy trọng yếu ít nên băng thông đủ:
10 Mbps chia cho vài chục máy
trọng yếu
↓
Sao chép ban đầu chậm nhưng
chạy nền
↓
Sau đó chỉ đồng bộ phần thay đổi
→ lượng nhỏ
⚠ Và Snowball Edge cho nhóm còn lại vì chúng dừng được:
Máy chỉ dùng trong giờ hành chính
↓
Dừng vào cuối tuần
↓
Xuất ra ảnh đĩa (OVA, VHD, VMDK)
↓
Chép vào Snowball, gửi về AWS
⚠ Và VM Import/Export nhận đúng những định dạng đó:
aws ec2 import-image \
--description "may-chu-ung-dung" \
--disk-containers '[{
"Description": "dia-he-thong",
"Format": "VMDK",
"UserBucket": {"S3Bucket": "kho-di-tru",
"S3Key": "may-01.vmdk"}}]'
⚠ Và VM Import/Export hỗ trợ: | Định dạng | Ghi chú | |---|---| | OVA | gói máy ảo hoàn chỉnh | | VMDK | VMware | | VHD/VHDX | Hyper-V | | RAW | ảnh đĩa thô |
⚠ Và vì sao phương án D thất bại về mặt thời gian:
D dùng VPN 1,25 Gbps
↓
Nhưng đề nói băng thông Internet
chỉ 10 Mbps
↓
VPN chạy TRÊN đường truyền đó
→ không tạo ra băng thông mới
↓
Con số 1,25 Gbps là giới hạn của
tunnel, không phải của đường
truyền
⚠ Đây là hiểu lầm rất phổ biến:
Site-to-Site VPN tunnel: tối đa
~1,25 Gbps
↓
Đó là TRẦN của tunnel
↓
Thông lượng thật = min(trần
tunnel, băng thông đường truyền)
→ ở đây là 10 Mbps
⚠ Và vì sao phương án C không khả thi:
C tạo Direct Connect 10 Gbps
↓
Đề nói tăng băng thông là "đắt
đến mức không chấp nhận được"
↓
Và Direct Connect mất hàng tuần
tới hàng tháng để lắp đặt
↓
Trong 3 tháng thì rất rủi ro
⚠ Và phương án C còn nhắc SMS đã ngừng:
AWS Server Migration Service
↓
Đã ngừng, thay bằng MGN
↓
Không dùng cho dự án mới được
⚠ Và vì sao phương án A không phải giải pháp di trú:
A dùng Migration Hub phân tích ứng
dụng để refactor
↓
Migration Hub là công cụ THEO DÕI
tiến độ
↓
Nó không di trú gì cả
↓
Và refactor 200 ứng dụng trong
3 tháng là không thực tế
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Vượt được giới hạn băng thông | | | Máy trọng yếu ngừng rất ngắn | | | Kịp hạn ba tháng | |
⚠ Và nên chạy Application Discovery Service trước:
aws discovery start-data-collection-by-agent-ids \
--agent-ids <danh-sach-agent>
Danh sách 200 máy trong tài liệu
thường lệch thực tế
↓
Discovery Service thu thập cấu
hình, hiệu năng, phụ thuộc mạng
↓
Thường phát hiện 10-20% máy
không ai dùng
→ không cần di trú
⚠ Và Migration Hub theo dõi tiến độ của cả hai luồng:
MGN và Snowball đều báo cáo về
Migration Hub
↓
Một bảng điều khiển cho toàn bộ
dự án
↓
Biết máy nào xong, máy nào đang
chạy
⚠ Và tính số Snowball Edge cần:
50 TB tổng
↓
Trừ phần máy trọng yếu đi qua
mạng
↓
Snowball Edge Storage Optimized:
80 TB dùng được
↓
Một thiết bị là đủ
→ nhưng dùng vài cái để chép
song song cho nhanh
⚠ Và VM Import/Export có ràng buộc phải biết: | Ràng buộc | Chi tiết | |---|---| | Hệ điều hành | danh sách được hỗ trợ, kiểm trước | | Ổ đĩa | tối đa 100 volume mỗi máy | | Giấy phép Windows | BYOL hoặc license included | | Không hỗ trợ | một số cấu hình khởi động đặc biệt |
⚠ Và với Linux nên cân nhắc dựng lại từ AMI sạch:
Nhập ảnh đĩa cũ
↓
Mang theo mọi thứ cũ: driver,
cấu hình, rác
↓
Dựng AMI mới + cài ứng dụng
→ sạch hơn, nhưng nhiều việc hơn
Vì sao các phương án khác sai
- **D. Xuất máy ảo ra tại chỗ, dựng VPN 1,25 Gbps để tải lên S3 rồi dùng VM Import/Export — đây là phương án gần nhất và luồng xử lý hoàn toàn đúng, nhưng con số 1,25 Gbps là trần của tunnel VPN chứ không phải băng thông thật; đường truyền chỉ có 10 Mbps nên vẫn mất hơn một năm.
- **C. Tạo Direct Connect 10 Gbps và dùng AWS SMS — đề nói tăng băng thông là quá đắt, Direct Connect mất hàng tháng để lắp, và SMS đã ngừng.
- **A. Dùng Migration Hub phân tích để refactor — Migration Hub theo dõi tiến độ chứ không di trú, và refactor 200 ứng dụng trong ba tháng là không thực tế.
Ghi nhớ
⚠ Bốn công cụ di trú và trường hợp dùng — bảng phải thuộc: | Công cụ | Dùng khi | |---|---| | MGN | máy chủ, ngừng dịch vụ tối thiểu, có băng thông | | Snowball Edge + VM Import | lượng lớn, băng thông kém, dừng được | | DMS | cơ sở dữ liệu | | DataSync | tệp |
Từ khoá nhận diện:
"limited bandwidth, cannot increase" → Snow Family "mission-critical, minimize downtime" → MGN "import VM images into EC2" → VM Import/Export "track migration progress" → Migration Hub
⚠ Công thức tính thời gian truyền:
Số ngày ≈ (TB × 8.000.000) /
(Mbps × 86.400 × 0,65)
↓
50 TB ở 10 Mbps ≈ 712 ngày
50 TB ở 1 Gbps ≈ 7 ngày
Ba lưu ý về MGN: | Lưu ý | Chi tiết | |---|---| | Miễn phí 90 ngày mỗi máy chủ nguồn | | | Cần cổng 443 và 1500 ra AWS | | | Có test instance để kiểm thử trước | |
⚠ Cổng 1500 hay bị tường lửa chặn:
Agent gửi dữ liệu sao chép qua
cổng 1500
↓
Tường lửa chặn → cài xong mà
không sao chép được
↓
Kiểm trước khi triển khai hàng
loạt
Ba lưu ý về Snowball Edge: | Lưu ý | Chi tiết | |---|---| | Storage Optimized 80 TB dùng được | | | Chu trình 1-2 tuần | | | Nhập dữ liệu vào AWS miễn phí | |
Ba lưu ý về VM Import/Export: | Lưu ý | Chi tiết | |---|---| | Nguồn phải ở S3 | | | Cần vai trò vmimport | | | Kiểm hệ điều hành có được hỗ trợ | |
⚠ Vai trò vmimport phải tạo trước:
{"Effect": "Allow",
"Principal": {"Service": "vmie.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {"StringEquals": {
"sts:ExternalId": "vmimport"}}}
Ba lưu ý về Discovery Service: | Lưu ý | Chi tiết | |---|---| | Agent-based hoặc agentless (VMware) | | | Thu thập cấu hình, hiệu năng, phụ thuộc | | | Kết quả xem trong Migration Hub | |
Ba lưu ý về chiến lược 6R: | Chiến lược | Áp dụng cho | |---|---| | Rehost | phần lớn máy trong đề này | | Replatform | CSDL sang RDS | | Retire | máy không ai dùng |
Ba lưu ý về kế hoạch: | Lưu ý | Chi tiết | |---|---| | Khảo sát trước, di trú sau | | | Đặt Snowball sớm — chu trình 1-2 tuần | | | Chạy thử cutover trên máy không quan trọng | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Khởi động test instance từ MGN | | | So checksum ảnh đĩa sau khi nhập | | | Đếm số máy đã di trú trong Migration Hub | |
Và một lời khuyên: hãy chạy Application Discovery Service trước khi đặt Snowball. Danh sách 200 máy trong tài liệu của một trung tâm dữ liệu mười năm tuổi gần như chắc chắn chứa những máy không ai còn dùng — và biết được con số đó có thể đổi cả kế hoạch dung lượng lẫn số thiết bị cần đặt.
A payment service provider company has a legacy application built on high throughput and resilient queueing system to send messages to the customers. The implementation relied on a manually-managed RabbitMQ cluster and consumers. The system was able to process a large load of messages within a reasonable delivery time. The cluster and consumers were both deployed on Amazon Elastic Compute Cloud (Amazon EC2) instances. However, when the messages in the queue piled up due to network failures on the customer side, the latency of the overall flow was affected, resulting in a breach of the service level agreement (SLA). The development team had to manually scale the queues to resolve the issue. Also, while doing manual upgrades on RabbitMQ and the hosting operating system, the company faced downtimes.
The company is growing and has to maintain a strict delivery time SLA. The company is now looking for a serverless solution for its messaging queues. The queue functions of handling concurrency, message delays and retries, maintaining message order, secure delivery, and scalability are needed in the proposed solution architecture.
Which of the following would you propose for a cost-effective solution for the requirement?
-
A
Design a cost-effective, serverless architecture by use of Amazon Simple Queue Service (SQS) with Amazon ECS Classic
-
B
Design the serverless architecture by use of Amazon Simple Queue Service (SQS) with Amazon ECS Fargate. To save costs, run the Amazon SQS FIFO queues and Amazon ECS Fargate tasks only when needed
-
C
Design the serverless architecture by use of Amazon MQ for RabbitMQ with Amazon ECS Fargate. To save costs, run the Amazon MQ for RabbitMQ queues and Amazon ECS Fargate tasks only when needed
-
D
Design the serverless architecture by use of Amazon MQ for RabbitMQ with Amazon ECS Classic
Xem giải thích
Đáp án
**B — Thiết kế kiến trúc serverless bằng Amazon SQS kết hợp Amazon ECS Fargate; để tiết kiệm chi phí, chỉ chạy SQS FIFO queue và tác vụ Fargate khi cần.
Vì sao đúng
Đề liệt kê sáu chức năng cần có và một yêu cầu về mô hình: | Yêu cầu | SQS FIFO đáp ứng | |---|---| | Xử lý đồng thời | nhiều consumer theo message group | | Trì hoãn và thử lại tin nhắn | message timer, visibility timeout, DLQ | | Giữ thứ tự tin nhắn | FIFO queue | | Giao hàng an toàn | mã hoá SSE, IAM | | Co giãn | tự động, không giới hạn | | SERVERLESS | SQS không có máy chủ nào |
⚠ Điểm mấu chốt: "serverless" loại Amazon MQ ngay:
Amazon MQ for RabbitMQ
↓
Là dịch vụ QUẢN LÝ, không phải
serverless
↓
Vẫn phải chọn kích thước broker
→ và trả tiền theo giờ dù có
dùng hay không
↓
Và vẫn phải nâng cấp phiên bản
broker
Đây là lý do phương án C và D đều sai.
⚠ Và đây chính là vấn đề mà công ty đang gặp:
"Downtime khi nâng cấp RabbitMQ và
hệ điều hành"
↓
Amazon MQ vẫn có cửa sổ bảo trì
↓
Chuyển sang Amazon MQ chỉ giảm
công việc
→ không loại bỏ vấn đề
↓
SQS: AWS lo hết, không có phiên
bản nào để nâng cấp
⚠ Và "ECS Classic" trong phương án A và D là khái niệm không tồn tại:
ECS có hai launch type:
- EC2 launch type
- Fargate launch type
↓
Không có cái nào tên "ECS Classic"
↓
(Có "EC2-Classic" nhưng đó là
mạng cũ của EC2, đã ngừng 2022)
⚠ Và EC2 launch type cũng không phải serverless:
ECS trên EC2: bạn quản đội máy chủ
↓
Phải vá, phải co giãn cụm
↓
Fargate: không có máy chủ nào
→ đúng nghĩa serverless
Tạo FIFO queue:
aws sqs create-queue --queue-name giao-dich.fifo \
--attributes '{
"FifoQueue": "true",
"ContentBasedDeduplication": "false",
"VisibilityTimeout": "300",
"MessageRetentionPeriod": "1209600",
"FifoThroughputLimit": "perMessageGroupId",
"DeduplicationScope": "messageGroup",
"SqsManagedSseEnabled": "true",
"RedrivePolicy": "{\"deadLetterTargetArn\":
\"arn:aws:sqs:ap-southeast-1:111122223333:giao-dich-loi.fifo\",
\"maxReceiveCount\":\"5\"}"}'
⚠ FifoThroughputLimit: perMessageGroupId bật chế độ thông lượng cao:
Mặc định: 300 thao tác/giây
↓
Chế độ cao: tới 70.000 tin/giây
↓
Cần cả `DeduplicationScope:
messageGroup`
↓
Và phải có NHIỀU message group
⚠ Và message group là chìa khoá cho cả thứ tự lẫn thông lượng:
Dùng mã khách hàng làm
`MessageGroupId`
↓
Tin của mỗi khách đúng thứ tự
↓
Khách khác nhau xử lý song song
→ vừa có thứ tự vừa có thông lượng
⚠ Và đây là điều RabbitMQ khó làm bằng:
RabbitMQ: một queue, một consumer
để giữ thứ tự
↓
Muốn song song → phải tự chia
queue theo khách hàng
↓
SQS FIFO: một queue, thứ tự theo
nhóm, song song tự động
⚠ Và vấn đề "hàng đợi dồn ứ khi khách hàng có sự cố mạng" được giải quyết:
SQS giữ tin tới 14 ngày
↓
Không có "hàng đợi đầy"
↓
Và consumer co giãn theo độ dài
hàng đợi
→ không phải mở rộng thủ công
Co giãn Fargate theo độ dài hàng đợi:
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--resource-id service/cum/dich-vu-xu-ly \
--scalable-dimension ecs:service:DesiredCount \
--policy-name theo-hang-doi \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 10,
"CustomizedMetricSpecification": {
"MetricName": "BacklogPerTask",
"Namespace": "XuLyGiaoDich",
"Statistic": "Average"}}'
⚠ Và "chỉ chạy khi cần" là cách tiết kiệm quan trọng:
Fargate tính tiền theo vCPU-giây
và GB-giây
↓
Không có tác vụ nào chạy → không
tốn gì
↓
Đặt `desiredCount = 0` khi hàng
đợi rỗng
→ EventBridge bật lại khi có tin
⚠ Và Fargate Spot giảm thêm tới 70%:
{"capacityProviderStrategy": [
{"capacityProvider": "FARGATE_SPOT", "weight": 4},
{"capacityProvider": "FARGATE", "weight": 1}]}
Xử lý tin nhắn chịu được gián đoạn
↓
Tin quay lại hàng đợi khi tác vụ
bị thu hồi
→ an toàn với Spot
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không còn nâng cấp gây gián đoạn | | | Co giãn tự động, không phải can thiệp | | | Trả tiền theo lượng dùng thật | |
⚠ Nhưng cần biết SQS không có mọi tính năng của RabbitMQ: | Tính năng | RabbitMQ | SQS | |---|---|---| | Định tuyến theo topic/routing key | CÓ | không (dùng SNS) | | Priority queue | CÓ | không | | Publish/subscribe | CÓ | SNS + SQS | | Giao thức AMQP/MQTT/STOMP | CÓ | chỉ API AWS |
Ứng dụng cũ dùng giao thức AMQP
↓
Chuyển sang SQS = viết lại tầng
nhắn tin
↓
Đề nói "tìm giải pháp serverless"
→ chấp nhận việc viết lại
⚠ Và Lambda là lựa chọn serverless hơn nữa:
Lambda đọc từ SQS FIFO
↓
Không có container nào để quản
↓
Nhưng timeout 15 phút
↓
Xử lý lâu hơn → Fargate
Vì sao các phương án khác sai
- **C. Dùng Amazon MQ for RabbitMQ với ECS Fargate, chỉ chạy khi cần — đây là phương án gần nhất và giữ được giao thức AMQP nên ít phải viết lại nhất, nhưng Amazon MQ là dịch vụ quản lý chứ không phải serverless: vẫn phải chọn kích thước broker, trả tiền theo giờ và chịu cửa sổ bảo trì khi nâng cấp.
- **D. Dùng Amazon MQ for RabbitMQ với "ECS Classic" — cùng vấn đề với C, thêm vào đó "ECS Classic" không phải một khái niệm tồn tại.
- **A. Dùng SQS với "ECS Classic" — chọn đúng hàng đợi nhưng "ECS Classic" không tồn tại; và EC2 launch type cũng không phải serverless.
Ghi nhớ
⚠ Ba dịch vụ nhắn tin của AWS — bảng phải thuộc: | Dịch vụ | Mô hình | Serverless | |---|---|---| | SQS | hàng đợi, kéo | CÓ | | SNS | chủ đề, đẩy | CÓ | | Amazon MQ | broker quản lý (RabbitMQ, ActiveMQ) | KHÔNG |
Từ khoá nhận diện:
"serverless messaging" → SQS, không phải Amazon MQ "keep AMQP/MQTT protocol" → Amazon MQ "maintain message order" → SQS FIFO "no server management" → Fargate, không phải EC2 launch type
Ba lưu ý về SQS FIFO: | Lưu ý | Chi tiết | |---|---| | Tên phải kết thúc .fifo | | | MessageGroupId bắt buộc | | | Chế độ thông lượng cao cần nhiều message group | |
⚠ Hai chế độ thông lượng của FIFO: | Chế độ | Thông lượng | |---|---| | Mặc định | 300 thao tác/giây (3.000 tin với batch) | | High throughput | tới 70.000 tin/giây |
Ba lưu ý về Fargate: | Lưu ý | Chi tiết | |---|---| | Tính tiền theo vCPU-giây và GB-giây | | | Không quản máy chủ, không vá gì | | | Fargate Spot rẻ hơn tới 70% | |
Ba lưu ý về co giãn theo hàng đợi: | Chỉ số | Ghi chú | |---|---| | ApproximateNumberOfMessagesVisible | số tin tồn đọng | | BacklogPerTask | chỉ số tuỳ chỉnh, tốt hơn | | ApproximateAgeOfOldestMessage | có tin kẹt không |
⚠ BacklogPerTask là chỉ số đúng để co giãn:
500 tin trong hàng đợi
↓
Nhiều hay ít? Tuỳ số tác vụ
↓
Backlog / số tác vụ
→ chỉ số này co giãn đúng
Ba lưu ý về DLQ: | Lưu ý | Chi tiết | |---|---| | DLQ của FIFO queue cũng phải là FIFO | | | maxReceiveCount quyết định ngưỡng | | | Đặt cảnh báo khi DLQ có tin | |
Ba lưu ý về mã hoá: | Cách | Đặc điểm | |---|---| | SSE-SQS | miễn phí, khoá do SQS quản | | SSE-KMS | kiểm soát và kiểm toán được, tính phí |
Ba lưu ý về di trú từ RabbitMQ: | Bước | Việc | |---|---| | Rà soát tính năng đang dùng | định tuyến, priority, giao thức | | Ánh xạ sang SQS/SNS | exchange → SNS, queue → SQS | | Chạy song song một thời gian | so kết quả trước khi cắt |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy thử với đỉnh tin nhắn dự kiến | | | Xác nhận thứ tự trong từng message group | | | Đo ApproximateAgeOfOldestMessage | |
Và một lời khuyên: hãy chọn MessageGroupId có độ phân tán cao ngay từ khi thiết kế. SQS FIFO chỉ đạt thông lượng cao khi có nhiều nhóm chạy song song — một nhóm duy nhất biến hàng đợi thành đường ống tuần tự và bạn sẽ gặp lại đúng vấn đề SLA mà việc chuyển đổi này định giải quyết.