Ngân hàng đề — AWS Certified Solutions Architect Associate
Tìm thấy 2194 câu.
A company operates a critical Python-based application that analyzes incoming real-time data. The application runs every 15 minutes and takes approximately 2 minutes to complete a run. It requires 1.5 GB of memory and uses the CPU intensively during its operation. The company wants to minimize the costs associated with running this application.
Which solution will meet these requirements?
-
A
Implement the application as an AWS Lambda function configured with 1.5 GB of memory. Use Amazon EventBridge to schedule the function to run every 15 minutes.
-
B
Use AWS App2Container (A2C) to containerize the application. Run the application as an Amazon Elastic Container Service (Amazon ECS) task on AWS Fargate with 1 virtual CPU (vCPU) and 1.5 GB of memory.
-
C
Use AWS App2Container (A2C) to containerize the application. Deploy the container on an Amazon EC2 instance, configure an Amazon CloudWatch alarm to stop the instance when the application is not running.
-
D
Deploy the application on an Amazon EC2 instance and manually start and stop the instance in alignment with the schedule of the application run.
Xem giải thích
Đáp án
A — Triển khai ứng dụng thành một hàm AWS Lambda cấu hình 1,5 GB bộ nhớ, dùng Amazon EventBridge lên lịch chạy mỗi 15 phút.
Vì sao đúng
Đề cho bốn con số, và cả bốn đều nằm gọn trong vùng hoạt động của Lambda: | Dữ kiện | Lambda | |---|---| | Chạy mỗi 15 phút | ✅ EventBridge Scheduler | | Mỗi lần mất ~2 phút | ✅ giới hạn 15 phút | | Cần 1,5 GB bộ nhớ | ✅ tới 10 GB | | Dùng CPU nhiều | ✅ CPU tỷ lệ với bộ nhớ |
⚠ Tính chi phí — đây là chỗ Lambda thắng rõ ràng:
Chạy 96 lần mỗi ngày × 30 ngày = 2.880 lần/tháng
2 phút × 1,5 GB = 180 GB-giây mỗi lần
→ 2.880 × 180 = 518.400 GB-giây
↓
~8,6 USD/tháng
So với EC2 t3.small chạy 24/7: ~15 USD/tháng
+ công vá và quản lý
↓
Và máy đó RẢNH 93% thời gian
⚠ Tỷ lệ thời gian chạy là chi tiết quyết định:
Chạy 2 phút mỗi 15 phút
→ chỉ hoạt động 13% thời gian
↓
87% thời gian còn lại là máy không làm gì
→ mọi phương án dựa trên máy chạy liên tục
đều lãng phí
Dựng bằng EventBridge Scheduler:
aws scheduler create-schedule --name chay-moi-15-phut \
--schedule-expression "rate(15 minutes)" \
--flexible-time-window Mode=OFF \
--target '{"Arn":"<arn-ham>",
"RoleArn":"<arn-role>",
"RetryPolicy":{"MaximumRetryAttempts":2}}'
⚠ EventBridge Scheduler mới hơn và tốt hơn EventBridge rule: | Tiêu chí | Scheduler | Rule | |---|---|---| | Múi giờ | ✅ hỗ trợ | ❌ chỉ UTC | | Cửa sổ linh hoạt | ✅ | ❌ | | Số lịch | hàng triệu | 300 rule | | Chính sách thử lại | ✅ | hạn chế |
Cấu hình hàm:
aws lambda create-function --function-name phan-tich-du-lieu \
--runtime python3.12 --handler app.handler \
--memory-size 1536 --timeout 300 \
--role <arn-role> --zip-file fileb://ma.zip
⚠ Cân nhắc tăng bộ nhớ vì tải nặng CPU:
Lambda cấp CPU TỶ LỆ với bộ nhớ
→ 1.769 MB ≈ 1 vCPU đầy đủ
↓
Đề nói "uses the CPU intensively"
→ tăng lên 3.008 MB có thể chạy trong 1 phút
→ tổng chi phí THẤP HƠN dù bộ nhớ gấp đôi
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không trả tiền 87% thời gian rảnh | | | Không quản lý máy chủ nào | | | Thử lại tự động khi lỗi | |
Vì sao các phương án khác sai
- **B. App2Container rồi chạy ECS task trên Fargate — đây là phương án gần nhất và cũng không quản lý máy chủ, nhưng Fargate tính phí cả thời gian khởi động task, và với tác vụ chỉ 2 phút thì khoản đó chiếm tỷ trọng lớn; cộng thêm công đóng gói container.
- **C. Container trên EC2 với CloudWatch alarm tự dừng máy — dừng và khởi động máy mỗi 15 phút là công vận hành phức tạp, thời gian boot chiếm phần lớn chu kỳ, và vẫn phải quản lý máy.
- **D. EC2 khởi động và dừng THỦ CÔNG theo lịch chạy — thủ công 96 lần mỗi ngày là điều không ai làm được; và đề nói mục tiêu là giảm chi phí, không phải tăng công việc.
Ghi nhớ
⚠ Chọn compute theo thời lượng và tần suất — bảng phải thuộc: | Đặc điểm | Lựa chọn | |---|---| | Dưới 15 phút, chạy thưa | Lambda | | Trên 15 phút, hoặc cần container | Fargate | | Job theo lô có phụ thuộc | AWS Batch | | Chạy liên tục | EC2 / Fargate service |
Từ khoá nhận diện:
"runs every N minutes, takes a few minutes" → Lambda + EventBridge "longer than 15 minutes" → Fargate hoặc Batch "thousands of queued jobs" → AWS Batch "containerize a legacy app" → App2Container
⚠ App2Container là công cụ thật, nhưng không cần ở đây:
A2C chuyển ứng dụng .NET và Java đang chạy
thành container image
↓
Ứng dụng Python nhỏ như đề mô tả
→ đóng gói thẳng thành Lambda, không cần A2C
Bốn giới hạn Lambda phải thuộc: | Giới hạn | Giá trị | |---|---| | Thời gian chạy | 15 phút | | Bộ nhớ | 128 MB – 10 GB | | /tmp | 512 MB – 10 GB | | Kích thước gói (zip) | 50 MB nén / 250 MB giải nén |
⚠ Container image cho Lambda tới 10 GB:
Thư viện khoa học dữ liệu (numpy, pandas, scipy)
→ vượt giới hạn 250 MB của zip
↓
Đóng gói thành container image
→ Lambda hỗ trợ tới 10 GB
aws lambda create-function --function-name phan-tich-du-lieu \
--package-type Image \
--code ImageUri=<id>.dkr.ecr.ap-southeast-1.amazonaws.com/phan-tich:1.0 \
--role <arn-role> --memory-size 3008 --timeout 300
Ba lưu ý về tối ưu bộ nhớ: | Lưu ý | Chi tiết | |---|---| | CPU tỷ lệ với bộ nhớ | | | 1.769 MB ≈ 1 vCPU | | | Trên 1.769 MB có nhiều luồng hơn | |
⚠ Dùng Lambda Power Tuning để tìm điểm tối ưu:
128 MB × 20 giây = 2.560 GB-ms
1024 MB × 2 giây = 2.048 GB-ms
3008 MB × 0,8 giây = 2.406 GB-ms
↓
Có một điểm ngọt — phải ĐO mới biết
Ba lưu ý về khởi động nguội: | Lưu ý | Chi tiết | |---|---| | Chạy mỗi 15 phút = thường có khởi động nguội | | | Không quan trọng với tác vụ nền | | | Đừng bật provisioned concurrency ở đây | |
⚠ Provisioned concurrency sẽ phá hỏng lợi thế chi phí:
Nó giữ môi trường sẵn 24/7
→ trả tiền cả 87% thời gian rảnh
↓
Đúng thứ mà chọn Lambda đang tránh
Ba lưu ý về EventBridge Scheduler: | Lưu ý | Chi tiết | |---|---| | rate(15 minutes) hoặc cron | | | Hỗ trợ múi giờ | | | Cần vai trò IAM để gọi đích | |
Ba lưu ý về xử lý lỗi: | Lưu ý | Chi tiết | |---|---| | Đặt MaximumRetryAttempts | | | Cấu hình DLQ cho lần chạy thất bại | | | Cảnh báo cho metric Errors | |
aws lambda put-function-event-invoke-config \
--function-name phan-tich-du-lieu \
--maximum-retry-attempts 2 \
--destination-config '{"OnFailure":{"Destination":"<arn-sqs>"}}'
Ba lưu ý về chồng lấn lần chạy: | Lưu ý | Chi tiết | |---|---| | Chạy 2 phút mỗi 15 phút — không chồng lấn | | | Nhưng nếu chậm bất thường thì có thể | | | Dùng reserved concurrency = 1 để chặn | |
⚠ reserved-concurrent-executions 1 bảo đảm chỉ một lần chạy:
aws lambda put-function-concurrency \
--function-name phan-tich-du-lieu \
--reserved-concurrent-executions 1
Ba lưu ý về giám sát: | Metric | Ý nghĩa | |---|---| | Duration | so với timeout | | Errors | | | Throttles | |
Ba lưu ý về log: | Lưu ý | Chi tiết | |---|---| | Đặt retention cho log group | | | Mặc định giữ vĩnh viễn | | | Log Insights truy vấn được | |
aws logs put-retention-policy \
--log-group-name /aws/lambda/phan-tich-du-lieu \
--retention-in-days 14
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem thời gian chạy thật trong log | | | Kiểm tra bộ nhớ dùng thật (Max Memory Used) | | | So chi phí sau một tháng | |
Và một lời khuyên: hãy thử tăng bộ nhớ lên trên 1.769 MB và đo lại. Đề nói ứng dụng dùng CPU nhiều, mà Lambda cấp CPU theo tỷ lệ với bộ nhớ — nên cấu hình lớn hơn có thể chạy nhanh hơn nhiều và cho ra hoá đơn nhỏ hơn, một trường hợp hiếm hoi không phải đánh đổi gì.
A media company hosts several terabytes of multimedia content across multiple AWS accounts. The company uses AWS Lake Formation to manage its data lake. The company's marketing team needs to securely access and analyze selective data from various accounts for targeted advertisement campaigns.
Which solution will meet these requirements with the LEAST operational overhead?
-
A
Use the Lake Formation permissions Grant command in each account where the data is stored to permit the required marketing team users to access the data.
-
B
Use AWS DataSync to synchronize the necessary data to the marketing team accounts.
-
C
Utilize Lake Formation tag-based access control to authorize and grant cross-account permissions for the required data to the marketing team accounts.
-
D
Replicate the required data to a shared account. Create an IAM access role in that account. Grant access by defining a permission policy that includes users from the marketing team accounts as trusted entities.
Xem giải thích
Đáp án
C — Dùng Lake Formation tag-based access control (TBAC) để cấp quyền xuyên tài khoản cho dữ liệu mà đội tiếp thị cần.
Vì sao đúng
Đề nêu ba yêu cầu, và TBAC là cơ chế đáp ứng cả ba với ít việc nhất: | Yêu cầu | Cách đáp ứng | |---|---| | Truy cập dữ liệu CHỌN LỌC | gắn tag cho bảng và cột cần chia sẻ | | Từ NHIỀU tài khoản khác nhau | TBAC cấp quyền xuyên tài khoản | | CÔNG VẬN HÀNH ÍT NHẤT | cấp theo tag, không theo từng tài nguyên |
⚠ TBAC thay đổi cách quản lý quyền từ "theo tài nguyên" sang "theo thuộc tính":
Không có TBAC:
→ cấp quyền cho từng bảng, từng tài khoản
→ 50 bảng × 5 tài khoản = 250 lần cấp quyền
↓
Có TBAC:
→ gắn tag `PhamVi=TiepThi` cho bảng
→ cấp quyền cho tag đó một lần
→ bảng mới gắn tag là tự động được chia sẻ
Tạo LF-Tag:
aws lakeformation create-lf-tag \
--tag-key PhamVi \
--tag-values TiepThi NoiBo NhayCam
Gắn tag cho bảng:
aws lakeformation add-lf-tags-to-resource \
--resource '{"Table":{"DatabaseName":"kho_media",
"Name":"luot_xem"}}' \
--lf-tags '[{"TagKey":"PhamVi","TagValues":["TiepThi"]}]'
Cấp quyền xuyên tài khoản theo tag:
aws lakeformation grant-permissions \
--principal '{"DataLakePrincipalIdentifier":"222222222222"}' \
--resource '{"LFTagPolicy":{
"ResourceType":"TABLE",
"Expression":[{"TagKey":"PhamVi","TagValues":["TiepThi"]}]}}' \
--permissions SELECT DESCRIBE \
--permissions-with-grant-option SELECT
⚠ Gắn tag ở cấp CỘT cho phép chia sẻ chọn lọc hơn nữa:
aws lakeformation add-lf-tags-to-resource \
--resource '{"TableWithColumns":{
"DatabaseName":"kho_media","Name":"nguoi_dung",
"ColumnNames":["email","so_dien_thoai"]}}' \
--lf-tags '[{"TagKey":"PhamVi","TagValues":["NhayCam"]}]'
Bảng gắn tag TiepThi
→ nhưng cột email gắn tag NhayCam
↓
Đội tiếp thị thấy bảng, KHÔNG thấy cột email
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Dữ liệu ở NGUYÊN chỗ, không nhân bản | | | Bảng mới tự động theo chính sách tag | | | Kiểm soát tới mức cột và hàng | |
⚠ "Không nhân bản" là lợi thế lớn nhất so với hai phương án còn lại:
Nhân bản dữ liệu: tốn lưu trữ gấp đôi
+ phải đồng bộ liên tục
+ hai bản có thể lệch nhau
↓
TBAC: một bản duy nhất, cấp quyền đọc
Vì sao các phương án khác sai
- **A. Dùng lệnh Grant của Lake Formation ở TỪNG tài khoản — đây là phương án gần nhất và cũng dùng đúng dịch vụ, nhưng cấp quyền theo từng tài nguyên ở từng tài khoản là công việc lặp lại nhân lên theo số bảng và số tài khoản; đề nói rõ "LEAST operational overhead".
- **D. Nhân bản dữ liệu sang một tài khoản dùng chung rồi tạo IAM role — nhân đôi lưu trữ hàng terabyte, phải đồng bộ, và hai bản dữ liệu có thể lệch nhau.
- **B. Dùng DataSync đồng bộ sang tài khoản tiếp thị — cũng nhân bản dữ liệu, và DataSync không có khái niệm phân quyền tới mức bảng hay cột.
Ghi nhớ
⚠ Ba mô hình phân quyền của Lake Formation — bảng phải thuộc: | Mô hình | Cách cấp | |---|---| | Named resource | chỉ đích danh CSDL, bảng, cột | | Tag-based (TBAC) | cấp theo tag — mở rộng tốt nhất | | Hybrid với IAM | dùng IAM policy song song |
Từ khoá nhận diện:
"share selective data across accounts, least overhead" → Lake Formation TBAC "copy data between accounts" → DataSync / S3 replication "query data across accounts without moving it" → Lake Formation + Athena "catalog metadata" → Glue Data Catalog
⚠ Lake Formation nằm trên Glue Data Catalog:
Glue Data Catalog: siêu dữ liệu (bảng, schema, phân vùng)
↓
Lake Formation: tầng phân quyền cho catalog đó
→ và cho dữ liệu trong S3
Ba mức phân quyền: | Mức | Chi tiết | |---|---| | Database | toàn bộ CSDL | | Table | một bảng | | Column / Row / Cell | chi tiết nhất |
⚠ Row-level và cell-level filter rất mạnh:
aws lakeformation create-data-cells-filter \
--table-data '{"DatabaseName":"kho_media",
"TableName":"luot_xem",
"Name":"chi-khu-vuc-a",
"RowFilter":{"FilterExpression":"khu_vuc = '\''A'\''"},
"ColumnWildcard":{"ExcludedColumnNames":["email"]}}'
Cùng một bảng
→ đội A chỉ thấy hàng của khu vực A
→ và không thấy cột email
Ba bước bật Lake Formation: | Bước | Chi tiết | |---|---| | Chỉ định data lake administrator | | | Đăng ký vị trí S3 với Lake Formation | | | Gỡ quyền IAMAllowedPrincipals mặc định | |
⚠ Bước ba là bước hay bị quên nhất:
Mặc định Lake Formation cấp `IAMAllowedPrincipals`
→ tức là "ai có IAM policy thì được"
→ phân quyền của Lake Formation KHÔNG có tác dụng
↓
Phải GỠ nó thì TBAC mới thật sự kiểm soát
aws lakeformation revoke-permissions \
--principal '{"DataLakePrincipalIdentifier":"IAM_ALLOWED_PRINCIPALS"}' \
--resource '{"Database":{"Name":"kho_media"}}' \
--permissions ALL
Ba lưu ý về xuyên tài khoản: | Lưu ý | Chi tiết | |---|---| | Tài khoản nhận phải chấp nhận resource share | | | Dùng AWS RAM bên dưới | | | Cần cấp quyền cho ID tài khoản hoặc ID tổ chức | |
⚠ Cấp cho ID TỔ CHỨC là cách ít việc nhất:
aws lakeformation grant-permissions \
--principal '{"DataLakePrincipalIdentifier":"o-abc123def4"}' \
...
Tài khoản mới gia nhập tổ chức
→ tự động có quyền theo tag
Ba lưu ý về công cụ truy vấn: | Công cụ | Tôn trọng quyền Lake Formation | |---|---| | Athena | ✅ | | Redshift Spectrum | ✅ | | EMR | ✅ (cần cấu hình) | | Glue ETL | ✅ | | Truy cập S3 TRỰC TIẾP | ❌ bỏ qua hoàn toàn |
⚠ Đây là lỗ hổng phải bịt:
Ai có s3:GetObject trên bucket
→ đọc thẳng tệp Parquet
→ bỏ qua mọi phân quyền Lake Formation
↓
Bucket policy chỉ cho phép vai trò của Lake Formation
Ba lưu ý về audit: | Lưu ý | Chi tiết | |---|---| | CloudTrail ghi mọi lần cấp và dùng quyền | | | Lake Formation có nhật ký truy cập riêng | | | Truy vấn Athena ghi lại được | |
Ba lưu ý về thiết kế tag: | Lưu ý | Chi tiết | |---|---| | Ít khoá tag, nhiều giá trị | | | Đặt tên theo nghiệp vụ, không theo kỹ thuật | | | Ghi tài liệu ý nghĩa từng tag | |
⚠ Ví dụ bộ tag tốt:
PhamVi: TiepThi | TaiChinh | NoiBo
DoNhayCam: Cong | NoiBo | Mat
Vung: APAC | EMEA | AMER
↓
Tổ hợp biểu đạt được hầu hết chính sách
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy Athena từ tài khoản tiếp thị | | | Xác nhận không thấy bảng ngoài phạm vi | | | Kiểm tra cột nhạy cảm bị ẩn | |
aws lakeformation list-permissions \
--principal '{"DataLakePrincipalIdentifier":"222222222222"}'
Và một lời khuyên: hãy gỡ IAMAllowedPrincipals trước khi tin rằng Lake Formation đang bảo vệ dữ liệu. Chừng nào quyền mặc định đó còn tồn tại, mọi chính sách tag bạn viết chỉ là trang trí — ai có IAM policy trên Glue và S3 vẫn đọc được tất cả.
There are badge readers located at every entrance of an organization’s warehouses. A message is sent over HTTPS when badges are scanned to indicate who tried to access the entrance.
A solutions architect must design a system to process these messages. A highly available solution is required. The solution must store results in a durable data store for later analysis.
Which system architecture should the solutions architect recommend?
-
A
Set up an Amazon S3 gateway endpoint in your VPC. Connect the facility network to the VPC via a Site-to-Site VPN connection so that sensor data can be written directly to an S3 bucket.
-
B
Direct incoming messages from the sensor to an AWS Lambda function using Amazon Route 53. Create a Lambda function that processes messages and saves results to Amazon DynamoDB.
-
C
Set up an HTTPS endpoint in Amazon API Gateway. To process the messages and save the results to Amazon DynamoDB, configure an API Gateway endpoint to invoke an AWS Lambda function.
-
D
Create an Amazon EC2 instance to serve as the HTTPS endpoint and to process messages. An Amazon S3 bucket should be configured for the EC2 instance to save the results.
Xem giải thích
Đáp án
C — Dựng HTTPS endpoint bằng Amazon API Gateway, cấu hình nó gọi một hàm AWS Lambda để xử lý tin nhắn và lưu kết quả vào Amazon DynamoDB.
Vì sao đúng
Đề nêu bốn yêu cầu, và kiến trúc này đáp ứng cả bốn: | Yêu cầu | Cách đáp ứng | |---|---| | Nhận tin nhắn qua HTTPS | API Gateway cho endpoint HTTPS | | Sẵn sàng cao | cả ba dịch vụ đều đa AZ sẵn | | Lưu kết quả vào kho BỀN VỮNG | DynamoDB | | Phân tích về sau | DynamoDB + export sang S3 |
⚠ Cả ba thành phần đều sẵn sàng cao mà không cần cấu hình gì:
API Gateway: dịch vụ vùng, tự đa AZ
Lambda: chạy ở nhiều AZ tự động
DynamoDB: dữ liệu nhân bản qua 3 AZ
↓
Không có instance nào để dựng Multi-AZ
→ sẵn sàng cao là mặc định
Dựng bằng SAM:
Resources:
HamXuLyQuet:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
Handler: app.handler
MemorySize: 512
Events:
Quet:
Type: HttpApi
Properties:
Path: /quet-the
Method: POST
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref BangSuKien
BangSuKien:
Type: AWS::DynamoDB::Table
Properties:
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- {AttributeName: maCong, AttributeType: S}
- {AttributeName: thoiDiem, AttributeType: S}
KeySchema:
- {AttributeName: maCong, KeyType: HASH}
- {AttributeName: thoiDiem, KeyType: RANGE}
⚠ Thiết kế khoá quyết định khả năng phân tích:
Partition key = maCong, sort key = thoiDiem
→ truy vấn "mọi lượt quét ở cổng X trong ngày Y"
rất nhanh
↓
Thêm GSI theo maThe để truy vấn
"người này đã vào những cổng nào"
Xác thực thiết bị — việc bắt buộc:
import hmac, hashlib, os
def kiem_chu_ky(than, chu_ky):
bi_mat = os.environ['BI_MAT_THIET_BI'].encode()
tinh = hmac.new(bi_mat, than.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(tinh, chu_ky)
⚠ Endpoint công khai nghĩa là ai cũng POST được:
Không xác thực
→ kẻ tấn công gửi bản ghi giả
→ nhật ký ra vào thành vô giá trị
↓
Chữ ký HMAC, mTLS, hoặc API key
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không máy chủ nào để vá hay giám sát | | | Tự mở rộng theo số lượt quét | | | Trả tiền theo request | |
⚠ Cân nhắc thêm SQS nếu độ tin cậy là ưu tiên:
API Gateway → SQS → Lambda → DynamoDB
↓
Lambda hoặc DynamoDB tạm lỗi
→ tin nhắn nằm trong hàng đợi, không mất
→ và API vẫn trả 200 rất nhanh
Vì sao các phương án khác sai
- **B. Dùng Route 53 định tuyến tin nhắn tới Lambda — Route 53 là DNS; nó phân giải tên miền thành địa chỉ, không gọi Lambda được. Lambda cần một endpoint HTTP (API Gateway, Function URL, hoặc ALB).
- **D. Dùng EC2 làm endpoint HTTPS và lưu vào S3 — một instance là điểm hỏng duy nhất; muốn sẵn sàng cao phải thêm ALB, ASG, nhiều AZ — nhiều việc hơn hẳn.
- **A. Dùng S3 gateway endpoint và Site-to-Site VPN để thiết bị ghi thẳng vào S3 — thiết bị đọc thẻ nói HTTPS, không nói giao thức S3; và dựng VPN tới mọi nhà kho là công việc lớn không cần thiết.
Ghi nhớ
⚠ Ba cách phơi bày Lambda ra HTTP — bảng phải thuộc: | Cách | Đặc điểm | |---|---| | API Gateway | đầy đủ: authorizer, throttling, WAF, stage | | Lambda Function URL | đơn giản nhất, miễn phí, ít tính năng | | Application Load Balancer | khi đã có ALB sẵn |
⚠ Route 53 KHÔNG phải một trong số đó — nó chỉ trả về địa chỉ.
Từ khoá nhận diện:
"HTTPS endpoint, process, store durably, HA" → API Gateway + Lambda + DynamoDB "buffer messages, guarantee no loss" → thêm SQS "IoT devices, MQTT" → IoT Core "stream for real-time analytics" → Kinesis
⚠ IoT Core đáng cân nhắc cho thiết bị thật:
Hàng nghìn thiết bị đầu đọc thẻ
→ IoT Core có chứng chỉ X.509 cho từng thiết bị
→ MQTT tiết kiệm băng thông hơn HTTPS
↓
Nhưng đề nói rõ thiết bị gửi HTTPS
→ API Gateway đúng hơn
Ba lưu ý về DynamoDB cho dữ liệu sự kiện: | Lưu ý | Chi tiết | |---|---| | Partition key phải phân tán đều | | | Sort key theo thời gian cho truy vấn theo khoảng | | | TTL tự xoá dữ liệu cũ | |
⚠ TTL rất hợp cho nhật ký ra vào:
aws dynamodb update-time-to-live --table-name SuKienQuetThe \
--time-to-live-specification 'Enabled=true,AttributeName=hetHan'
Giữ 90 ngày trong DynamoDB
→ tự xoá, KHÔNG tốn WCU
↓
Dữ liệu dài hạn đã có ở S3
Ba cách đưa dữ liệu sang S3 để phân tích: | Cách | Chi tiết | |---|---| | DynamoDB export to S3 | không tốn RCU | | DynamoDB Streams → Firehose → S3 | gần thời gian thực | | Glue ETL job | theo lịch |
⚠ Export sang S3 không ảnh hưởng bảng:
aws dynamodb export-table-to-point-in-time \
--table-arn <arn-bang> \
--s3-bucket kho-phan-tich \
--export-format DYNAMODB_JSON
Đọc từ bản sao lưu liên tục
→ KHÔNG tiêu RCU của bảng
→ không ảnh hưởng ứng dụng
Ba lưu ý về API Gateway: | Lưu ý | Chi tiết | |---|---| | HTTP API rẻ hơn REST API ~70% | | | Đặt throttling bảo vệ backend | | | Timeout 29 giây | |
Ba cách xác thực thiết bị: | Cách | Chi tiết | |---|---| | Chữ ký HMAC trong header | phổ biến | | mTLS trên custom domain | chặt nhất | | API key + usage plan | REST API |
⚠ mTLS phù hợp cho thiết bị cố định:
aws apigatewayv2 create-domain-name \
--domain-name quet-the.congty.vn \
--domain-name-configurations CertificateArn=<arn> \
--mutual-tls-authentication \
TruststoreUri=s3://kho-chung-chi/ca.pem
Ba lưu ý về idempotency: | Lưu ý | Chi tiết | |---|---| | Thiết bị mất mạng có thể gửi lại | | | Dùng ID sự kiện làm khoá | | | ConditionExpression chặn ghi trùng | |
bang.put_item(
Item={'maSuKien': ma, ...},
ConditionExpression='attribute_not_exists(maSuKien)')
Ba lưu ý về giám sát: | Metric | Ý nghĩa | |---|---| | Count của API Gateway | có nhận được tin không | | 4XXError | chữ ký sai | | DynamoDB ThrottledRequests | |
⚠ Cảnh báo khi Count bằng 0 cũng quan trọng:
Thiết bị ngừng gửi hoàn toàn
→ không có lỗi nào, chỉ là im lặng
↓
Cảnh báo khi không có sự kiện nào trong X giờ
Ba việc kiểm chứng: | Việc | Cách | |---|---| | curl thử endpoint | | | Gửi chữ ký sai | phải 401 | | Kiểm tra bản ghi xuất hiện trong DynamoDB | |
Và một lời khuyên: hãy đặt cảnh báo cho trường hợp KHÔNG có sự kiện nào. Hệ thống này chỉ có giá trị khi nó ghi được mọi lượt quét, và tình huống nguy hiểm nhất không phải là lỗi hiện ra trong log mà là một nhà kho lặng lẽ ngừng báo cáo suốt cả tuần.
An application runs on Amazon EC2 instances across multiple Availability Zones. The instances run in an Amazon EC2 Auto Scaling group behind an Application Load Balancer. The application performs best when the CPU utilization of the EC2 instances is at or near 40%.
What should a solutions architect do to maintain the desired performance across all instances in the group?
-
A
Use a simple scaling policy to dynamically scale the Auto Scaling group
-
B
Use scheduled scaling actions to scale up and scale down the Auto Scaling group
-
C
Use an AWS Lambda function to update the desired Auto Scaling group capacity
-
D
Use a target tracking policy to dynamically scale the Auto Scaling group
Xem giải thích
Đáp án
D — Dùng target tracking policy để co giãn Auto Scaling group.
Vì sao đúng
Đề nêu đúng một yêu cầu, và target tracking là chính sách được thiết kế cho câu đó: | Yêu cầu | Cách đáp ứng | |---|---| | Ứng dụng chạy tốt nhất khi CPU ở khoảng 40% | đặt mục tiêu, ASG tự duy trì |
⚠ Target tracking hoạt động như bộ điều nhiệt:
Bạn khai: "giữ CPU trung bình ở 40%"
↓
ASG tự tính số máy cần
→ CPU 80% → thêm nhiều
→ CPU 45% → thêm ít
→ CPU 25% → bớt
↓
Càng lệch mục tiêu, phản ứng càng mạnh
Cấu hình:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name asg-ung-dung \
--policy-name giu-cpu-40 \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"TargetValue": 40.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"}}'
⚠ ASG tự tạo và quản lý CloudWatch alarm:
Chính sách sinh ra AlarmHigh và AlarmLow
→ đừng sửa hay xoá bằng tay
↓
Chúng thuộc về chính sách, không phải của bạn
Ba metric dựng sẵn: | Metric | Dùng khi | |---|---| | ASGAverageCPUUtilization | tải nặng CPU — đúng đề này | | ALBRequestCountPerTarget | ứng dụng web | | ASGAverageNetworkIn/Out | tải nặng mạng |
⚠ Target tracking mở rộng nhanh, thu nhỏ chậm — có chủ ý:
Thêm máy: phản ứng nhanh, tránh quá tải
Bớt máy: từ tốn, tránh dao động
↓
Thiết kế nghiêng về giữ tính sẵn sàng
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Chỉ khai một con số | | | Tự điều chỉnh biên độ theo độ lệch | | | AWS khuyến nghị cho hầu hết trường hợp | |
Vì sao các phương án khác sai
- **A. Simple scaling policy — đây là phương án gần nhất và cũng co giãn động, nhưng simple scaling thêm một lượng cố định rồi chờ hết cooldown mới đánh giá lại; nó không duy trì được một mức mục tiêu, và là cách cũ nhất mà AWS không còn khuyến nghị.
- **B. Scheduled scaling — dùng cho tải đoán trước theo giờ và ngày; đề không nói tới lịch nào, chỉ nói tới một mức CPU cần duy trì.
- **C. Dùng Lambda cập nhật desired capacity — tự viết lại thứ ASG đã làm sẵn, thêm mã phải bảo trì, và phản ứng chậm hơn.
Ghi nhớ
⚠ Bốn chính sách mở rộng — bảng phải thuộc: | Chính sách | Cách hoạt động | |---|---| | Target tracking | duy trì một metric ở mức mục tiêu | | Step scaling | bậc thang theo mức vượt ngưỡng | | Simple scaling | một hành động rồi chờ cooldown — cũ | | Scheduled | theo giờ và ngày định trước | | Predictive | học lịch sử, chuẩn bị trước |
Từ khoá nhận diện:
"keep CPU at X%", "performs best at" → target tracking "specific time each day/month" → scheduled "different response for different severity" → step scaling "recurring pattern, prepare in advance" → predictive
⚠ Nhiều chính sách gắn cùng lúc được:
Target tracking theo CPU 40%
+ target tracking theo request 1000/máy
↓
ASG chọn hành động cho ra NHIỀU máy nhất
→ an toàn theo cả hai chiều
Ba yếu tố quyết định tốc độ phản ứng: | Yếu tố | Ảnh hưởng | |---|---| | Chu kỳ metric | 1 phút (detailed) vs 5 phút | | Instance warm-up | thời gian ứng dụng sẵn sàng | | Thời gian boot | AMI đã cài sẵn thì nhanh hơn |
⚠ default-instance-warmup thay cho cooldown kiểu cũ:
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name asg-ung-dung \
--default-instance-warmup 180
Máy chưa "ấm" không tính vào metric trung bình
→ tránh mở rộng thừa vì máy mới CPU thấp
→ hoặc mở rộng thừa vì máy đang boot CPU cao
Ba lưu ý về metric tuỳ chỉnh: | Lưu ý | Chi tiết | |---|---| | Dùng được metric tự đẩy lên CloudWatch | | | Phải tỷ lệ NGHỊCH với số máy | | | Ví dụ: "tin nhắn mỗi máy" chứ không phải tổng | |
⚠ Đây là điều kiện toán học để target tracking hội tụ:
Tổng số tin nhắn trong hàng đợi
→ thêm máy KHÔNG làm con số đó giảm ngay
→ chính sách cứ thêm mãi
↓
Chia cho số máy đang chạy
→ thêm máy làm giảm ngay → hội tụ
Ba lưu ý về health check: | Lưu ý | Chi tiết | |---|---| | Dùng ELB thay vì EC2 | | | health-check-grace-period đủ dài | | | Quá ngắn tạo vòng lặp giết máy | |
⚠ Health check EC2 không phát hiện ứng dụng chết:
Health check EC2: máy có chạy không
→ ứng dụng treo mà máy vẫn "khoẻ"
↓
Health check ELB: ứng dụng có trả lời không
Ba lưu ý về min và max: | Lưu ý | Chi tiết | |---|---| | min-size ít nhất bằng số AZ | | | max-size là trần chi phí | | | Cảnh báo khi chạm max | |
Ba lưu ý về thu nhỏ: | Lưu ý | Chi tiết | |---|---| | DisableScaleIn nếu muốn chỉ mở rộng | | | Scale-in protection cho máy đang xử lý việc dở | | | Lifecycle hook để hoàn tất việc trước khi tắt | |
aws autoscaling put-lifecycle-hook \
--auto-scaling-group-name asg-ung-dung \
--lifecycle-hook-name cho-hoan-tat \
--lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \
--heartbeat-timeout 300
Ba lưu ý về chính sách kết thúc: | Chính sách | Chọn máy nào để tắt | |---|---| | Default | cân bằng AZ rồi máy cũ nhất | | OldestInstance | | | NewestInstance | hữu ích khi thử nghiệm |
Ba lưu ý về warm pool: | Lưu ý | Chi tiết | |---|---| | Giữ máy đã boot ở trạng thái Stopped | | | Khởi động lại trong vài chục giây | | | Chỉ trả tiền EBS | |
Ba lưu ý về giám sát: | Việc | Cách | |---|---| | Xem lịch sử hoạt động của ASG | | | Theo dõi CPU có hội tụ về mục tiêu không | | | Kiểm tra không có dao động lên xuống liên tục | |
aws autoscaling describe-policies \
--auto-scaling-group-name asg-ung-dung \
--query "ScalingPolicies[].[PolicyName,PolicyType,
TargetTrackingConfiguration.TargetValue]" --output table
Ba lưu ý về chi phí: | Lưu ý | Chi tiết | |---|---| | Mục tiêu thấp = nhiều máy hơn = đắt hơn | | | 40% là mức khá bảo thủ | | | Cân nhắc Spot cho một phần đội máy | |
⚠ Mức mục tiêu là đánh đổi trực tiếp giữa chi phí và biên an toàn:
Mục tiêu 40%: nhiều biên, đắt hơn
Mục tiêu 70%: ít máy hơn, rẻ hơn
nhưng ít chỗ hấp thụ đột biến
↓
Đề đã nói ứng dụng chạy tốt nhất ở 40%
→ chọn theo đề
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy tải giả, xem CPU hội tụ về 40% | | | Kiểm tra alarm do chính sách tạo | | | Xem có dao động không | |
Và một lời khuyên: hãy đặt default-instance-warmup bằng thời gian ứng dụng thật sự sẵn sàng phục vụ. Không có nó, máy đang khởi động sẽ kéo lệch con số CPU trung bình theo cả hai hướng — và chính sách sẽ phản ứng với một hiện thực không tồn tại.
A company is looking for ways to incorporate its current AWS usage expenditure into its operational expense tracking dashboard. A solutions architect has been tasked with proposing a method that enables the company to fetch its current year's cost data and project the costs for the forthcoming 12 months programmatically.
Which approach would fulfill these needs with the MINIMUM operational burden?
-
A
Generate AWS Budgets reports on usage cost data and dispatch the data to the corporation through SMTP.
-
B
Make use of downloadable AWS Cost Explorer report files in the .csv format to access usage cost-related data.
-
C
Set up AWS Budgets actions to transmit usage cost data to the corporation via FTP.
-
D
Leverage the AWS Cost Explorer API to retrieve usage cost-related data, using pagination for larger data sets.
Xem giải thích
Đáp án
D — Dùng AWS Cost Explorer API để lấy dữ liệu chi phí, có phân trang cho tập dữ liệu lớn.
Vì sao đúng
Đề nêu ba yêu cầu, và Cost Explorer API đáp ứng cả ba: | Yêu cầu | Cách đáp ứng | |---|---| | Lấy dữ liệu chi phí BẰNG CHƯƠNG TRÌNH | API trả JSON, gọi từ mã | | Dữ liệu năm hiện tại | GetCostAndUsage | | DỰ BÁO 12 tháng tới | GetCostForecast |
⚠ Vế dự báo là chi tiết loại bỏ mọi phương án khác:
Chỉ Cost Explorer có khả năng DỰ BÁO
→ Budgets đặt ngưỡng, không dự báo cho bạn đọc
→ CUR là dữ liệu THÔ đã phát sinh
↓
`GetCostForecast` là API duy nhất trả về
dự đoán chi phí tương lai
Lấy chi phí năm hiện tại:
aws ce get-cost-and-usage \
--time-period Start=2026-01-01,End=2026-08-31 \
--granularity MONTHLY \
--metrics UnblendedCost AmortizedCost \
--group-by Type=DIMENSION,Key=SERVICE
Dự báo 12 tháng tới:
aws ce get-cost-forecast \
--time-period Start=2026-09-01,End=2027-09-01 \
--metric UNBLENDED_COST \
--granularity MONTHLY \
--prediction-interval-level 80
⚠ Phân trang là bắt buộc với tập dữ liệu lớn:
import boto3
ce = boto3.client('ce')
ket_qua = []
token = None
while True:
tham_so = {
'TimePeriod': {'Start': '2026-01-01', 'End': '2026-08-31'},
'Granularity': 'MONTHLY',
'Metrics': ['UnblendedCost'],
'GroupBy': [{'Type': 'DIMENSION', 'Key': 'SERVICE'}]}
if token:
tham_so['NextPageToken'] = token
phan_hoi = ce.get_cost_and_usage(**tham_so)
ket_qua.extend(phan_hoi['ResultsByTime'])
token = phan_hoi.get('NextPageToken')
if not token:
break
⚠ Không xử lý phân trang là mất dữ liệu trong im lặng:
API trả về một phần kết quả kèm NextPageToken
→ bỏ qua token = chỉ lấy trang đầu
↓
Bảng điều khiển hiện số liệu THIẾU
→ không có lỗi nào báo hiệu
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không dựng hạ tầng phân tích nào | | | Dữ liệu lịch sử sẵn 13 tháng | | | Có dự báo tích hợp | |
⚠ Lưu ý về chi phí của chính API này:
Mỗi lời gọi Cost Explorer API ≈ 0,01 USD
→ script gọi mỗi phút = ~430 USD/tháng
↓
Cache kết quả, gọi mỗi giờ hoặc mỗi ngày
Vì sao các phương án khác sai
- **B. Dùng tệp .csv tải về từ Cost Explorer — đây là phương án gần nhất và cho đúng dữ liệu, nhưng tải tệp là thao tác thủ công, không phải "programmatically"; và không có phần dự báo.
- **A. Tạo báo cáo AWS Budgets rồi gửi qua SMTP — Budgets để cảnh báo khi vượt ngưỡng, không phải để trích xuất dữ liệu; và gửi email không đưa được dữ liệu vào bảng điều khiển.
- **C. Dùng budget action gửi dữ liệu qua FTP — budget action áp IAM policy hoặc dừng tài nguyên; nó không truyền dữ liệu đi đâu cả, càng không qua FTP.
Ghi nhớ
⚠ Bốn công cụ chi phí — bảng phải thuộc: | Công cụ | Việc | |---|---| | Cost Explorer (+ API) | phân tích, trực quan hoá, DỰ BÁO | | AWS Budgets | đặt ngưỡng, cảnh báo, HÀNH ĐỘNG | | Cost and Usage Report (CUR) | dữ liệu THÔ chi tiết nhất | | Compute Optimizer | khuyến nghị đổi cỡ |
Từ khoá nhận diện:
"programmatically fetch costs and forecast" → Cost Explorer API "alert when spending exceeds" → Budgets "most granular data, custom BI" → CUR + Athena/QuickSight "prevent spending" → Budget actions hoặc SCP
⚠ Ba chỉ số chi phí hay nhầm: | Chỉ số | Nghĩa | |---|---| | UnblendedCost | giá thực tế từng tài khoản | | BlendedCost | giá trung bình trong tổ chức | | AmortizedCost | rải đều khoản trả trước của RI/SP |
Có Reserved Instance trả trước
→ UnblendedCost dồn hết vào một tháng
→ đồ thị có một đỉnh vô nghĩa
↓
Dùng AmortizedCost cho bảng điều khiển vận hành
Ba chiều nhóm hay dùng: | Chiều | Trả lời | |---|---| | SERVICE | dịch vụ nào tốn nhất | | LINKED_ACCOUNT | tài khoản nào | | Tag | đội hoặc dự án nào |
⚠ Tag phải được KÍCH HOẠT làm cost allocation tag:
Gắn tag đầy đủ cho tài nguyên
→ nhưng quên kích hoạt trong Billing console
↓
Cost Explorer không nhóm theo tag đó được
→ và KHÔNG hồi tố cho dữ liệu cũ
Ba lưu ý về dự báo: | Lưu ý | Chi tiết | |---|---| | Dựa trên xu hướng lịch sử | | | prediction-interval-level 80 hoặc 95 | | | Không biết trước sự kiện đặc biệt | |
⚠ Khoảng dự đoán quan trọng hơn con số điểm:
Dự báo: 50.000 USD
Khoảng 80%: từ 42.000 tới 58.000
↓
Báo cáo cho lãnh đạo nên có cả khoảng
→ một con số duy nhất tạo cảm giác chắc chắn sai
Ba lưu ý về CUR (khi cần chi tiết hơn): | Lưu ý | Chi tiết | |---|---| | Một dòng cho mỗi giờ mỗi tài nguyên | | | Tệp Parquet trên S3 | | | Cần Athena hoặc QuickSight để đọc | |
aws cur put-report-definition --report-definition '{
"ReportName":"bao-cao-chi-tiet",
"TimeUnit":"HOURLY","Format":"Parquet",
"Compression":"Parquet",
"AdditionalSchemaElements":["RESOURCES"],
"S3Bucket":"kho-cur","S3Prefix":"cur/",
"S3Region":"ap-southeast-1",
"ReportVersioning":"OVERWRITE_REPORT"}'
⚠ AdditionalSchemaElements: RESOURCES cho ID từng tài nguyên — không có nó thì không biết máy nào tốn tiền.
Ba lưu ý về quyền: | Lưu ý | Chi tiết | |---|---| | ce:GetCostAndUsage, ce:GetCostForecast | | | Chỉ management account thấy cả tổ chức | | | Phải bật quyền truy cập cho tài khoản thành viên | |
Ba lưu ý về độ trễ dữ liệu: | Nguồn | Độ trễ | |---|---| | Cost Explorer | tới 24 giờ | | CUR | tới 24 giờ | | Budgets | đánh giá ~3 lần/ngày |
⚠ Không có nguồn chi phí nào thời gian thực:
Chi tiêu hôm nay không xuất hiện ngay
→ mọi bảng điều khiển chi phí đều nhìn về quá khứ
↓
Cần chặn tức thì thì dùng SCP, không dùng số liệu
Ba lưu ý về tối ưu chi phí gọi API: | Lưu ý | Chi tiết | |---|---| | ~0,01 USD mỗi lời gọi | | | Cache kết quả trong DynamoDB hoặc S3 | | | Gọi mỗi ngày là đủ cho hầu hết bảng điều khiển | |
Ba lưu ý về tự động hoá: | Cách | Chi tiết | |---|---| | Lambda + EventBridge chạy hằng ngày | | | Ghi kết quả vào S3 hoặc DynamoDB | | | Bảng điều khiển đọc từ đó | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đối chiếu tổng với hoá đơn thật | | | Kiểm tra phân trang lấy đủ dữ liệu | | | So dự báo với thực tế tháng sau | |
Và một lời khuyên: hãy cache kết quả và gọi API mỗi ngày một lần thay vì mỗi lần mở bảng điều khiển. Cost Explorer API tính phí theo lời gọi và dữ liệu chỉ cập nhật một lần mỗi ngày — nên một bảng điều khiển gọi API mỗi lần có người nhìn vào sẽ tốn tiền cho cùng một câu trả lời hàng trăm lần.
An application makes calls to a REST API running on Amazon EC2 instances behind an Application Load Balancer (ALB). Most API calls complete quickly. However, a single endpoint is making API calls that require much longer to complete and this is introducing overall latency into the system. What steps can a Solutions Architect take to minimize the effects of the long-running API calls?
-
A
Create an Amazon SQS queue and decouple the long-running API calls
-
B
Increase the ALB idle timeout to allow the long-running requests to complete
-
C
Change the EC2 instance to one with enhanced networking to reduce latency
-
D
Change the ALB to a Network Load Balancer (NLB) and use SSL/TLS termination
Xem giải thích
Đáp án
A — Tạo một hàng đợi Amazon SQS và tách rời (decouple) các lời gọi API chạy lâu.
Vì sao đúng
Đề mô tả một endpoint chậm đang kéo độ trễ của cả hệ thống, và cách chữa đúng là đưa nó ra khỏi đường đồng bộ.
⚠ Vì sao một endpoint chậm ảnh hưởng toàn hệ thống:
Yêu cầu chậm giữ kết nối và luồng xử lý
→ luồng đó không phục vụ yêu cầu khác được
↓
Đủ nhiều yêu cầu chậm = cạn pool luồng
→ yêu cầu NHANH cũng phải xếp hàng
↓
Đây là hiện tượng "head-of-line blocking"
Chuyển sang mô hình bất đồng bộ:
Trước: client → API → xử lý 60 giây → trả kết quả
↓
Sau: client → API → đẩy vào SQS → trả 202 + mã việc
↓
worker xử lý riêng
↓
client hỏi trạng thái, hoặc nhận webhook
Endpoint nhận việc:
import boto3, uuid, json
sqs = boto3.client('sqs')
bang = boto3.resource('dynamodb').Table('TrangThaiViec')
def handler(su_kien, ngu_canh):
ma_viec = str(uuid.uuid4())
bang.put_item(Item={'maViec': ma_viec, 'trangThai': 'DANG_CHO'})
sqs.send_message(QueueUrl=URL_HANG_DOI,
MessageBody=json.dumps({'maViec': ma_viec,
'thamSo': su_kien['body']}))
return {'statusCode': 202,
'body': json.dumps({'maViec': ma_viec})}
⚠ Mã 202 Accepted là mã HTTP đúng cho mô hình này:
200 OK: "đã xong, đây là kết quả"
202 Accepted: "đã nhận, sẽ xử lý"
↓
Client biết phải hỏi lại sau
Ba cách trả kết quả về cho client: | Cách | Chi tiết | |---|---| | Polling | client hỏi /viec/{ma} định kỳ | | Webhook | máy chủ gọi ngược lại client | | WebSocket | đẩy kết quả thời gian thực |
Mở rộng worker theo độ sâu hàng đợi:
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/cum/worker \
--policy-name theo-hang-doi \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 10.0,
"CustomizedMetricSpecification": {
"MetricName": "SoTinNhanMoiTask",
"Namespace": "UngDung", "Statistic": "Average"}}'
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Endpoint nhanh không bị ảnh hưởng nữa | | | Việc chậm mở rộng độc lập | | | Việc không mất khi worker lỗi | |
⚠ Vế thứ ba là lợi ích ít người nói tới:
Mô hình đồng bộ: xử lý lỗi giữa chừng = mất việc
↓
SQS: tin nhắn quay lại hàng đợi
→ thử lại, hỏng hẳn thì vào DLQ
Vì sao các phương án khác sai
- **B. Tăng idle timeout của ALB để yêu cầu dài kịp hoàn tất — đây là phương án gần nhất và giúp yêu cầu đó không bị cắt, nhưng nó không giải quyết vấn đề: kết nối vẫn bị giữ lâu, luồng xử lý vẫn bị chiếm, các yêu cầu nhanh vẫn chịu ảnh hưởng.
- **C. Đổi sang instance có enhanced networking — cải thiện thông lượng và độ trễ mạng vài chục micro giây; hoàn toàn không liên quan tới một API mất hàng chục giây vì xử lý.
- **D. Đổi ALB thành NLB với SSL/TLS termination — NLB nhanh hơn ở tầng 4 nhưng không rút ngắn thời gian xử lý; và mất các tính năng tầng 7 mà REST API thường cần.
Ghi nhớ
⚠ Ba cách xử lý tác vụ chạy lâu — bảng phải thuộc: | Cách | Chi tiết | |---|---| | SQS + worker | đơn giản nhất, phổ biến nhất | | Step Functions | quy trình nhiều bước, có trạng thái | | Lambda asynchronous invocation | dưới 15 phút |
Từ khoá nhận diện:
"long-running API call adds latency" → tách rời bằng SQS "multi-step workflow with retries" → Step Functions "fan-out to multiple consumers" → SNS + SQS "real-time result push" → WebSocket API
⚠ Step Functions cho quy trình phức tạp hơn:
{"StartAt": "XuLy",
"States": {
"XuLy": {"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Retry": [{"ErrorEquals":["States.TaskFailed"],
"IntervalSeconds":2,"MaxAttempts":3,
"BackoffRate":2}],
"Next": "Xong"},
"Xong": {"Type": "Succeed"}}}
Có sẵn thử lại, xử lý lỗi, rẽ nhánh, chạy song song
→ không phải tự viết
Ba lưu ý về DLQ: | Lưu ý | Chi tiết | |---|---| | Luôn cấu hình | | | maxReceiveCount 3-5 | | | Cảnh báo khi DLQ có tin | |
Ba lưu ý về visibility timeout: | Lưu ý | Chi tiết | |---|---| | Phải LỚN HƠN thời gian xử lý | | | Khuyến nghị gấp 6 lần timeout của worker | | | Quá ngắn = tin bị xử lý hai lần | |
⚠ Với việc chạy 60 giây, đặt visibility timeout ít nhất 360 giây.
Ba lưu ý về idempotency: | Lưu ý | Chi tiết | |---|---| | SQS chuẩn giao ÍT NHẤT một lần | | | Dùng maViec làm khoá khử trùng | | | ConditionExpression chặn ghi trùng | |
Ba lưu ý về theo dõi tiến độ: | Việc | Cách | |---|---| | Lưu trạng thái vào DynamoDB | | | DANG_CHO → DANG_CHAY → XONG / LOI | | | Đặt TTL xoá bản ghi cũ | |
Ba metric cần theo dõi: | Metric | Ý nghĩa | |---|---| | ApproximateAgeOfOldestMessage | tụt hậu bao lâu | | ApproximateNumberOfMessagesVisible | tồn đọng | | Độ trễ p99 của endpoint nhanh | phải cải thiện |
⚠ Đo lại độ trễ của endpoint nhanh là cách kiểm chứng đúng:
Mục tiêu của thay đổi này là làm endpoint NHANH
nhanh trở lại
↓
Nếu p99 của chúng không giảm
→ vấn đề nằm ở chỗ khác
Ba lưu ý về ALB timeout (nếu vẫn cần): | Lưu ý | Chi tiết | |---|---| | Mặc định 60 giây | | | Tối đa 4000 giây | | | Tăng lên chỉ là băng dán, không phải cách chữa | |
aws elbv2 modify-load-balancer-attributes --load-balancer-arn <arn> \
--attributes Key=idle_timeout.timeout_seconds,Value=300
Ba lưu ý về pool kết nối: | Lưu ý | Chi tiết | |---|---| | Web server có số luồng giới hạn | | | Yêu cầu chậm chiếm luồng lâu | | | Đây là gốc rễ của hiện tượng lan toả | |
⚠ Tách endpoint chậm sang target group riêng cũng là một cách:
ALB định tuyến /bao-cao-nang tới target group riêng
→ đội máy riêng, pool luồng riêng
↓
Endpoint nhanh không bị ảnh hưởng
→ giải pháp trung gian nếu chưa đổi sang
mô hình bất đồng bộ được
Ba lưu ý về chi phí: | Khoản | Chi tiết | |---|---| | SQS ~0,40 USD mỗi triệu request | | | Rẻ hơn nhiều so với thêm máy | | | Worker mở rộng xuống 0 khi rảnh | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo p99 của endpoint nhanh trước và sau | | | Kiểm tra hàng đợi tiêu hết tồn đọng | | | Thử dừng worker, xem việc không mất | |
Và một lời khuyên: hãy đo lại độ trễ của những endpoint NHANH sau khi tách, chứ đừng chỉ đo endpoint chậm. Mục tiêu của thay đổi này không phải làm việc chậm nhanh lên — nó vẫn mất chừng ấy thời gian — mà là ngăn nó kéo theo mọi thứ khác.
A company is in the process of improving its security posture and wants to analyze and rectify a high volume of failed login attempts and unauthorized activities being logged in AWS CloudTrail.
What is the most efficient solution to help the company identify these security events with the LEAST amount of operational effort?
-
A
Implement Amazon Elasticsearch Service with Kibana to visualize the CloudTrail logs and manually search for these events.
-
B
Leverage AWS Lambda to trigger on CloudTrail log updates and use a custom script to scan for failed logins and unauthorized actions.
-
C
Use Amazon Athena to directly query CloudTrail logs for failed logins and unauthorized activities.
-
D
Utilize AWS Data Pipeline to regularly extract CloudTrail logs and use a custom script to identify the required security events.
Xem giải thích
Đáp án
C — Dùng Amazon Athena truy vấn trực tiếp log CloudTrail để tìm các lần đăng nhập thất bại và hành động trái phép.
Vì sao đúng
Đề nêu ba yêu cầu, và Athena đáp ứng cả ba với ít công nhất trong bốn phương án: | Yêu cầu | Cách đáp ứng | |---|---| | Phân tích log CloudTrail | Athena chạy SQL thẳng trên S3 | | Khối lượng lớn | Athena xử lý terabyte | | CÔNG SỨC ÍT NHẤT | không dựng cụm, không viết mã |
⚠ Console CloudTrail có nút tạo bảng Athena sẵn:
CloudTrail → Event history → Create Athena table
→ sinh sẵn câu CREATE TABLE với đúng schema
↓
Vài cú nhấp, không viết dòng nào
Truy vấn tìm đăng nhập thất bại:
SELECT eventtime,
useridentity.username AS nguoi_dung,
sourceipaddress AS ip_nguon,
errormessage
FROM cloudtrail_logs
WHERE eventname = 'ConsoleLogin'
AND responseelements['ConsoleLogin'] = 'Failure'
AND year = '2026' AND month = '08'
ORDER BY eventtime DESC;
Truy vấn tìm hành động trái phép:
SELECT eventtime, useridentity.arn, eventsource,
eventname, errorcode, sourceipaddress
FROM cloudtrail_logs
WHERE errorcode IN ('AccessDenied', 'UnauthorizedOperation',
'Client.UnauthorizedOperation')
AND year = '2026' AND month = '08'
ORDER BY eventtime DESC
LIMIT 100;
⚠ Tổng hợp để tìm mẫu tấn công:
SELECT sourceipaddress, COUNT(*) AS so_lan,
COUNT(DISTINCT useridentity.username) AS so_tai_khoan
FROM cloudtrail_logs
WHERE eventname = 'ConsoleLogin'
AND responseelements['ConsoleLogin'] = 'Failure'
AND year = '2026' AND month = '08'
GROUP BY sourceipaddress
HAVING COUNT(*) > 20
ORDER BY so_lan DESC;
Một IP thử nhiều tài khoản
→ dấu hiệu dò mật khẩu
↓
Đây là loại câu hỏi chỉ SQL trả lời nhanh được
⚠ Luôn lọc theo phân vùng:
Không có điều kiện year/month
→ quét TOÀN BỘ lịch sử log
→ hoá đơn Athena tăng vọt
↓
Athena tính ~5 USD mỗi TB quét
Dùng partition projection để khỏi phải MSCK REPAIR:
TBLPROPERTIES (
'projection.enabled'='true',
'projection.year.type'='integer',
'projection.year.range'='2024,2030',
'projection.month.type'='integer',
'projection.month.range'='1,12',
'projection.month.digits'='2',
'storage.location.template'=
's3://log-cloudtrail/AWSLogs/123456789012/CloudTrail/ap-southeast-1/${year}/${month}/${day}/')
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không có cụm nào để dựng và trả tiền | | | Trả tiền theo dữ liệu quét | | | Dữ liệu ở nguyên chỗ trên S3 | |
Ghi nhớ về chất lượng câu hỏi
⚠ CloudTrail Lake là câu trả lời hiện đại hơn, và nó không có trong bốn phương án.
aws cloudtrail create-event-data-store \
--name kho-su-kien --retention-period 2555
aws cloudtrail start-query --query-statement "
SELECT eventTime, userIdentity.arn, eventName, errorCode
FROM <id-kho>
WHERE errorCode IN ('AccessDenied','UnauthorizedOperation')
ORDER BY eventTime DESC"
| Tiêu chí | Athena | CloudTrail Lake |
|---|---|---|
| Dựng bảng | cần (hoặc dùng nút tạo sẵn) | không cần gì |
| Giữ dữ liệu | theo lifecycle bucket | tới 10 năm |
| Chi phí | rẻ hơn | đắt hơn |
| Truy vấn xuyên tài khoản | phải gom log | sẵn có |
Athena vẫn là câu trả lời đúng trong bốn lựa chọn
→ và rẻ hơn cho khối lượng lớn
↓
Nhưng nếu ưu tiên tuyệt đối là "ít công nhất"
→ CloudTrail Lake còn ít hơn nữa
Và cần cảnh báo THỜI GIAN THỰC thì cả hai đều không phải câu trả lời:
{"source": ["aws.signin"],
"detail-type": ["AWS Console Sign In via CloudTrail"],
"detail": {"responseElements": {"ConsoleLogin": ["Failure"]}}}
EventBridge bắt sự kiện ngay khi xảy ra
→ Athena và Lake là công cụ ĐIỀU TRA sau
Vì sao các phương án khác sai
- **A. Dùng OpenSearch với Kibana rồi tìm thủ công — đây là phương án gần nhất và cho khả năng trực quan hoá mạnh nhất, nhưng phải dựng và trả tiền cho một cụm chạy 24/7, cộng đường ống nạp log; và "tìm thủ công" là công sức lặp lại.
- **B. Dùng Lambda kích hoạt khi có log mới với script tự viết — phải viết và bảo trì mã phân tích, xử lý phân trang, xử lý lỗi; nhiều việc hơn hẳn một câu SQL.
- **D. Dùng AWS Data Pipeline trích xuất log rồi chạy script — Data Pipeline là dịch vụ cũ, AWS đã ngừng nhận khách hàng mới; và vẫn phải viết script.
Ghi nhớ
⚠ Ba cách truy vấn log CloudTrail — bảng phải thuộc: | Cách | Công dựng | Giữ dữ liệu | |---|---|---| | Console Event history | không có gì | chỉ 90 ngày, chỉ management event | | Athena trên bucket log | tạo bảng | theo lifecycle | | CloudTrail Lake | bật một lần | tới 10 năm |
⚠ Event history chỉ 90 ngày — điều tra dài hơn phải có trail ghi ra S3.
Từ khoá nhận diện:
"analyze CloudTrail logs, least effort" → Athena hoặc CloudTrail Lake "real-time alert on an event" → EventBridge "rich dashboards and full-text search" → OpenSearch "aggregate security findings" → Security Hub
Ba mã lỗi cần tìm: | Mã | Nghĩa | |---|---| | AccessDenied | IAM không cho phép | | UnauthorizedOperation | tương tự, thường ở EC2 | | ConsoleLogin = Failure | đăng nhập sai |
⚠ errorMessage thường nói rõ thiếu quyền gì:
"User: arn:... is not authorized to perform: s3:GetObject
... because no identity-based policy allows the action"
↓
Câu cuối phân biệt: thiếu policy,
Deny tường minh, hay SCP chặn
Ba lưu ý về tối ưu chi phí Athena: | Cách | Mức giảm | |---|---| | Lọc theo phân vùng | rất lớn | | Chọn cột cụ thể thay SELECT * | | | Đặt hạn mức byte quét cho workgroup | |
aws athena create-work-group --name dieu-tra \
--configuration 'BytesScannedCutoffPerQuery=10737418240'
Ba lưu ý về bảo vệ log: | Lưu ý | Chi tiết | |---|---| | Bucket log ở TÀI KHOẢN RIÊNG | | | Bật log file validation | | | Object Lock chống xoá | |
⚠ Cảnh báo khi ai đó tắt CloudTrail:
{"source": ["aws.cloudtrail"],
"detail": {"eventName": ["StopLogging","DeleteTrail","UpdateTrail"]}}
Ba công cụ chẩn đoán quyền: | Công cụ | Việc | |---|---| | IAM Policy Simulator | thử trước khi áp | | Access Analyzer policy generation | sinh policy TỪ log | | sts decode-authorization-message | giải mã thông báo |
⚠ Sinh policy từ CloudTrail là cách chữa AccessDenied tốt nhất:
aws accessanalyzer start-policy-generation \
--policy-generation-details 'PrincipalArn=<arn-vai-tro>' \
--cloud-trail-details file://chi-tiet.json
Đọc log 90 ngày, sinh policy chứa ĐÚNG quyền đã dùng
→ vừa sửa lỗi vừa không cấp thừa
Ba loại sự kiện CloudTrail: | Loại | Mặc định | |---|---| | Management | BẬT, miễn phí (một trail) | | Data | TẮT, có phí | | Insights | TẮT, có phí |
Ba lưu ý về phản ứng: | Việc | Chi tiết | |---|---| | Chặn IP dò mật khẩu bằng WAF hoặc NACL | | | Bắt buộc MFA cho mọi người dùng | | | Bật GuardDuty phát hiện tự động | |
⚠ GuardDuty làm phần lớn việc này tự động:
`UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B`
`Discovery:IAMUser/AnomalousBehavior`
↓
GuardDuty phát hiện mẫu bất thường
→ không cần tự viết truy vấn
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Cố tình gây một AccessDenied | | | Tìm nó bằng truy vấn Athena | | | Kiểm tra dữ liệu quét không quá lớn | |
Và một lời khuyên: hãy bật GuardDuty song song với việc dựng truy vấn Athena. Truy vấn cho bạn câu trả lời khi biết cần hỏi gì, còn GuardDuty là thứ nói cho bạn biết rằng có điều gì đó đáng hỏi — và trong bảo mật thì vế thứ hai mới là phần khó.
A solutions architect is optimizing a website for real-time streaming and on-demand videos. The website’s users are located around the world and the solutions architect needs to optimize the performance for both the real-time and on-demand streaming.
Which service should the solutions architect choose?
-
A
Amazon CloudFront
-
B
Amazon Route 53
-
C
AWS Global Accelerator
-
D
Amazon S3 Transfer Acceleration
Xem giải thích
Đáp án
A — Amazon CloudFront.
Vì sao đúng
Đề nêu ba yêu cầu, và CloudFront là dịch vụ duy nhất phục vụ được cả hai loại nội dung: | Yêu cầu | Cách đáp ứng | |---|---| | Video theo yêu cầu (on-demand) | cache tệp ở edge gần người xem | | Phát trực tiếp (real-time streaming) | phân phối segment HLS/DASH ở edge | | Người dùng toàn cầu | hơn 600 điểm hiện diện |
⚠ Phát trực tiếp hiện đại cũng là các tệp nhỏ qua HTTP:
HLS / DASH chia luồng thành segment 2-10 giây
→ mỗi segment là một tệp HTTP
↓
CloudFront cache được chúng như mọi tệp khác
→ hàng nghìn người xem cùng segment
→ chỉ một lần lấy từ origin
Cấu hình cho hai loại nội dung:
{"CacheBehaviors": {"Quantity": 2, "Items": [
{"PathPattern": "/vod/*",
"TargetOriginId": "s3-vod",
"CachePolicyId": "<CachingOptimized>",
"ViewerProtocolPolicy": "redirect-to-https"},
{"PathPattern": "/live/*.m3u8",
"TargetOriginId": "mediapackage",
"CachePolicyId": "<TTL-ngan>",
"ViewerProtocolPolicy": "redirect-to-https"}]}}
⚠ Playlist và segment cần TTL khác nhau: | Tệp | TTL | |---|---| | .m3u8 (playlist) | 2-5 giây — phải luôn mới | | .ts / .m4s (segment) | dài — nội dung bất biến |
Cache playlist quá lâu
→ người xem không thấy segment mới
→ luồng trực tiếp bị "đứng"
↓
Segment thì ngược lại: đặt tên duy nhất,
cache thoải mái
Kiến trúc phát trực tiếp đầy đủ:
Nguồn phát (RTMP)
→ AWS Elemental MediaLive (mã hoá)
→ MediaPackage (đóng gói HLS/DASH)
→ CloudFront (phân phối)
→ người xem
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Giảm tải origin rất mạnh | | | Rẻ hơn truyền thẳng từ S3 | | | Có signed URL/cookie để kiểm soát truy cập | |
⚠ Tỷ lệ trúng cache là chỉ số quyết định:
10.000 người xem cùng một trận đấu
→ không có CDN: origin phục vụ 10.000 luồng
↓
Có CloudFront: origin phục vụ vài chục lần
→ phần còn lại từ edge
Vì sao các phương án khác sai
- **C. AWS Global Accelerator — đây là phương án gần nhất và cũng cải thiện hiệu năng toàn cầu, nhưng nó KHÔNG cache: nó tối ưu đường đi mạng tới origin. Với video, cache mới là thứ tạo ra khác biệt lớn nhất; Global Accelerator hợp với TCP/UDP không cache được (game, VoIP).
- **B. Amazon Route 53 — DNS phân giải tên miền; nó có thể định tuyến người dùng tới endpoint gần nhất nhưng không phân phối nội dung và không cache gì.
- **D. S3 Transfer Acceleration — tăng tốc TẢI LÊN S3 từ xa; không liên quan tới việc phát nội dung xuống người xem.
Ghi nhớ
⚠ CloudFront vs Global Accelerator — bảng phải thuộc: | Tiêu chí | CloudFront | Global Accelerator | |---|---|---| | Cache nội dung | ✅ | ❌ | | Giao thức | HTTP/HTTPS | TCP và UDP | | Địa chỉ IP | thay đổi | hai IP tĩnh anycast | | Dùng cho | web, video, API | game, VoIP, IoT, chuyển vùng nhanh |
⚠ Cách nhớ ngắn nhất:
Nội dung cache được, HTTP → CloudFront
Không cache được, cần IP tĩnh → Global Accelerator
Từ khoá nhận diện:
"streaming video, global users, on-demand and live" → CloudFront "non-HTTP protocol, static IP, fast failover" → Global Accelerator "route users to nearest endpoint (DNS)" → Route 53 latency routing "speed up uploads to S3" → Transfer Acceleration
Ba dịch vụ Elemental cho video: | Dịch vụ | Việc | |---|---| | MediaLive | mã hoá luồng trực tiếp | | MediaPackage | đóng gói và bảo vệ luồng | | MediaConvert | chuyển mã tệp cho VOD | | MediaStore | lưu trữ độ trễ thấp (đang thay bằng S3) |
⚠ Luồng công việc VOD điển hình:
Tải video gốc lên S3
→ S3 event kích hoạt MediaConvert
→ xuất nhiều bitrate (HLS/DASH) trở lại S3
↓
CloudFront phân phối
Ba lưu ý về bảo vệ nội dung: | Cách | Chi tiết | |---|---| | Signed URL | một tệp mỗi URL | | Signed cookie | nhiều tệp — hợp với video nhiều segment | | DRM qua MediaPackage | bảo vệ mạnh nhất |
⚠ Với video, signed COOKIE hợp hơn signed URL:
Một video HLS có hàng trăm segment
→ signed URL phải ký từng cái
↓
Signed cookie: một lần cấp, mở được cả cây
Ba lưu ý về OAC: | Lưu ý | Chi tiết | |---|---| | Chặn truy cập thẳng vào bucket S3 | | | OAC thay thế OAI (đã lỗi thời) | | | OAI không làm việc với SSE-KMS | |
Ba lưu ý về cache policy: | Policy | Dùng cho | |---|---| | CachingOptimized | nội dung tĩnh, VOD | | CachingDisabled | API động | | Tuỳ chỉnh TTL ngắn | playlist trực tiếp |
Ba lưu ý về chi phí: | Khoản | Chi tiết | |---|---| | Truyền dữ liệu ra ~0,085 USD/GB | thay đổi theo Region | | Rẻ hơn truyền thẳng từ S3 | | | Price class giới hạn edge để giảm giá | |
⚠ Price class là công cụ giảm chi phí đáng biết:
PriceClass_All: mọi edge, đắt nhất
PriceClass_200: bỏ Nam Mỹ, Úc, New Zealand
PriceClass_100: chỉ Bắc Mỹ, châu Âu, Israel
↓
Người xem chủ yếu ở châu Á → PriceClass_200 đủ
Ba lưu ý về nén: | Lưu ý | Chi tiết | |---|---| | Bật nén tự động cho manifest và metadata | | | Video đã nén — không nén thêm được | | | Nén giúp playlist tải nhanh hơn | |
Ba lưu ý về giám sát: | Metric | Ý nghĩa | |---|---| | CacheHitRate | thấp = origin chịu tải | | OriginLatency | | | BytesDownloaded | chi phí |
⚠ Bật real-time log cho luồng trực tiếp:
aws cloudfront create-realtime-log-config \
--name log-truc-tiep --sampling-rate 100 \
--end-points 'StreamType=Kinesis,
KinesisStreamConfig={RoleARN=<arn>,StreamARN=<arn-stream>}' \
--fields timestamp c-ip sc-status cs-uri-stem time-taken
Access log thường có độ trễ nhiều phút
→ không đủ để phát hiện sự cố luồng trực tiếp
↓
Real-time log tới trong vài giây
Ba lưu ý về invalidation: | Lưu ý | Chi tiết | |---|---| | 1.000 đường dẫn đầu mỗi tháng miễn phí | | | Đặt tên tệp có version thay vì invalidate | | | Invalidation mất vài phút lan ra edge | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo thời gian bắt đầu phát từ nhiều nơi | | | Theo dõi CacheHitRate | | | Kiểm tra playlist luôn mới | |
Và một lời khuyên: hãy đặt TTL riêng cho tệp playlist của luồng trực tiếp. Cache mọi thứ như nhau là cách nhanh nhất để một buổi phát trực tiếp trông như bị treo — người xem tải lại playlist cũ và không bao giờ thấy segment mới.
A company has some statistical data stored in an Amazon RDS database. The company want to allow users to access this information using an API. A solutions architect must create a solution that allows sporadic access to the data, ranging from no requests to large bursts of traffic.
Which solution should the solutions architect suggest?
-
A
Set up an Amazon API Gateway and use AWS Lambda functions
-
B
Set up an Amazon API Gateway and use Amazon ECS
-
C
Set up an Amazon API Gateway and use Amazon EC2 with Auto Scaling
-
D
Set up an Amazon API Gateway and use AWS Elastic Beanstalk
Xem giải thích
Đáp án
A — Dựng Amazon API Gateway và dùng AWS Lambda.
Vì sao đúng
Đề cho một mô tả tải rất cụ thể, và nó chỉ thẳng vào serverless: | Dữ kiện | Ý nghĩa | |---|---| | Truy cập THƯA THỚT | phần lớn thời gian không có request | | Từ KHÔNG request tới đợt tăng vọt lớn | cần mở rộng tức thì từ 0 | | Dữ liệu nằm trong RDS | Lambda kết nối được |
⚠ "Từ không có request nào" là từ khoá quyết định:
ECS, EC2, Elastic Beanstalk:
→ luôn có ít nhất một máy chạy
→ trả tiền cả lúc không ai gọi
↓
Lambda: 0 request = 0 USD tính toán
→ và mở rộng lên hàng nghìn trong vài giây
Dựng bằng SAM:
Resources:
HamApi:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
Handler: app.handler
MemorySize: 512
Timeout: 29
VpcConfig:
SubnetIds: [subnet-a, subnet-b]
SecurityGroupIds: [sg-lambda]
Events:
Api:
Type: HttpApi
Properties:
Path: /thong-ke
Method: GET
⚠ Vấn đề lớn nhất của Lambda + RDS: cạn kết nối:
Lambda mở rộng lên 1.000 thực thi đồng thời
→ mỗi thực thi mở một kết nối tới RDS
↓
RDS chạm `max_connections` và từ chối
→ đợt tăng vọt đánh sập CSDL
Cách chữa — RDS Proxy:
aws rds create-db-proxy --db-proxy-name proxy-thong-ke \
--engine-family POSTGRESQL \
--auth '[{"AuthScheme":"SECRETS","SecretArn":"<arn-secret>"}]' \
--role-arn <arn-role> \
--vpc-subnet-ids subnet-a subnet-b \
--vpc-security-group-ids sg-proxy --require-tls
Và giới hạn đồng thời:
aws lambda put-function-concurrency \
--function-name ham-api --reserved-concurrent-executions 50
⚠ Hai biện pháp này giải hai phần khác nhau:
RDS Proxy: gộp kết nối, tái dùng
Reserved concurrency: giới hạn số Lambda chạy cùng lúc
↓
Dùng CẢ HAI cho tải bùng nổ trên CSDL quan hệ
Tái dùng kết nối giữa các lần gọi:
import psycopg2, os
ket_noi = None
def lay_ket_noi():
global ket_noi
if ket_noi is None or ket_noi.closed:
ket_noi = psycopg2.connect(
host=os.environ['DB_HOST'], dbname='thongke',
user=os.environ['DB_USER'], password=lay_bi_mat(),
connect_timeout=5)
return ket_noi
def handler(su_kien, ngu_canh):
with lay_ket_noi().cursor() as con_tro:
con_tro.execute("SELECT ... ")
return {'statusCode': 200, 'body': ...}
⚠ Khai báo kết nối NGOÀI handler:
Lambda tái dùng môi trường thực thi
→ kết nối tồn tại giữa các lần gọi
↓
Tạo kết nối bên trong handler
→ mở kết nối mới mỗi request → cạn nhanh hơn
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không trả tiền lúc không có request | | | Mở rộng tức thì cho đợt tăng vọt | | | Không quản lý máy chủ nào | |
Vì sao các phương án khác sai
- **C. API Gateway + EC2 với Auto Scaling — đây là phương án gần nhất và cũng co giãn được, nhưng ASG mở rộng theo phút (chờ boot, chờ health check), quá chậm cho đợt tăng vọt đột ngột; và luôn phải giữ ít nhất một máy chạy.
- **B. API Gateway + Amazon ECS — Fargate task khởi động mất vài chục giây và service luôn giữ task tối thiểu; vẫn trả tiền khi rảnh.
- **D. API Gateway + Elastic Beanstalk — nền tảng chạy ứng dụng thường trực trên EC2; đắt nhất khi rảnh và chậm nhất khi mở rộng.
Ghi nhớ
⚠ Ba lựa chọn theo mẫu tải — bảng phải thuộc: | Mẫu tải | Lựa chọn | |---|---| | Thưa thớt, có lúc bằng 0, bùng nổ | Lambda | | Liên tục nhưng biến động | Fargate với auto scaling | | Liên tục và ổn định | EC2 với Savings Plans |
Từ khoá nhận diện:
"sporadic, from no requests to large bursts" → API Gateway + Lambda "steady traffic" → ECS/EC2 "long-running > 15 minutes" → Fargate "connection exhaustion with Lambda" → RDS Proxy
⚠ Ba tốc độ mở rộng: | Dịch vụ | Thời gian có năng lực mới | |---|---| | Lambda | mili giây tới giây | | Fargate | chục giây | | EC2 ASG | phút |
Ba lưu ý về Lambda trong VPC: | Lưu ý | Chi tiết | |---|---| | Cần để tới RDS trong subnet riêng tư | | | Không còn chậm như trước (ENI dùng chung) | | | Cần NAT hoặc VPC endpoint để gọi dịch vụ AWS | |
⚠ Lambda trong VPC mất đường ra Internet:
Gắn vào subnet riêng tư
→ không gọi được API bên ngoài
→ không gọi được Secrets Manager
↓
Thêm VPC endpoint, hoặc NAT gateway
Ba lưu ý về khởi động nguội: | Lưu ý | Chi tiết | |---|---| | Tải thưa = thường xuyên khởi động nguội | | | Chấp nhận được cho API thống kê | | | Provisioned concurrency phá lợi thế chi phí | |
Ba lưu ý về API Gateway: | Lưu ý | Chi tiết | |---|---| | HTTP API rẻ hơn REST API ~70% | | | Timeout 29 giây | | | Đặt throttling bảo vệ CSDL | |
aws apigatewayv2 update-stage --api-id abc --stage-name '$default' \
--default-route-settings 'ThrottlingRateLimit=500,
ThrottlingBurstLimit=1000'
⚠ Throttling ở API Gateway là hàng rào đầu tiên:
Không giới hạn: đợt tăng vọt truyền thẳng xuống Lambda
→ rồi xuống RDS
↓
Chặn ở tầng ngoài cùng rẻ hơn nhiều
Ba lưu ý về cache của API Gateway: | Lưu ý | Chi tiết | |---|---| | REST API có cache tích hợp | | | Dữ liệu thống kê thường cache được | | | Giảm mạnh số lời gọi xuống CSDL | |
⚠ Với API thống kê, cache là cải thiện lớn nhất:
Dữ liệu thống kê đổi mỗi giờ
→ cache 5 phút
↓
Đợt tăng vọt 10.000 request
→ chỉ vài chục lần chạm CSDL
Ba lưu ý về credential CSDL: | Cách | Chi tiết | |---|---| | Secrets Manager + tự xoay | | | IAM database authentication | không có mật khẩu tĩnh | | RDS Proxy giữ credential | |
Ba lưu ý về Aurora Serverless v2: | Lưu ý | Chi tiết | |---|---| | Hợp với tải thất thường ở tầng CSDL | | | Data API bỏ hẳn vấn đề kết nối | | | Tự thu về mức tối thiểu khi rảnh | |
⚠ Data API là cặp đôi lý tưởng với Lambda:
aws rds-data execute-statement \
--resource-arn <arn-cum> --secret-arn <arn-secret> \
--database thongke --sql "SELECT ..."
Gọi SQL qua HTTPS, không mở kết nối
→ không có gì để cạn
→ không cần RDS Proxy
Ba lưu ý về giám sát: | Metric | Ý nghĩa | |---|---| | Lambda Throttles | chạm giới hạn đồng thời | | RDS DatabaseConnections | gần max_connections chưa | | API Gateway Latency | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy tải giả mức đỉnh dự kiến | | | Theo dõi kết nối RDS trong lúc đó | | | Kiểm tra chi phí trong tuần không có request | |
Và một lời khuyên: hãy đặt reserved concurrency cho Lambda trước khi mở API ra ngoài. Lambda mở rộng nhanh hơn nhiều so với khả năng nhận kết nối của RDS, nên nếu không giới hạn thì đợt truy cập đầu tiên sẽ không làm chậm API — nó sẽ đánh sập cơ sở dữ liệu.
An application uses a MySQL database running on an Amazon EC2 instance. The application generates high I/O and constant writes to a single table on the database. Which Amazon EBS volume type will provide the MOST consistent performance and low latency?
-
A
Cold HDD (sc1)
-
B
Throughput Optimized HDD (st1)
-
C
Provisioned IOPS SSD (io1)
-
D
General Purpose SSD (gp2)
Xem giải thích
Đáp án
C — Provisioned IOPS SSD (io1).
Vì sao đúng
Đề cho ba dữ kiện, và cả ba đều chỉ vào io1: | Dữ kiện | Ý nghĩa | |---|---| | CSDL MySQL với I/O cao | cần IOPS lớn và ổn định | | Ghi LIÊN TỤC vào một bảng | I/O ngẫu nhiên → phải là SSD | | Hiệu năng NHẤT QUÁN, độ trễ thấp | io1 cấp phát IOPS cố định |
⚠ Từ "nhất quán" là chỗ phân biệt io1 với gp2:
gp2: dựa vào I/O credit
→ cạn credit thì tụt về mức cơ sở (3 IOPS mỗi GB)
→ hiệu năng KHÔNG dự đoán được dưới tải liên tục
↓
io1: IOPS bạn cấp phát là IOPS bạn luôn có
→ độ lệch dưới 10% trong 99,9% thời gian
Tạo volume:
aws ec2 create-volume --availability-zone ap-southeast-1a \
--size 500 --volume-type io1 --iops 20000 --encrypted
⚠ Tỷ lệ IOPS trên dung lượng có giới hạn: | Loại | Tỷ lệ tối đa | |---|---| | io1 | 50 IOPS mỗi GiB | | io2 | 500 IOPS mỗi GiB |
io1 muốn 20.000 IOPS → cần ít nhất 400 GiB
io2 muốn 20.000 IOPS → chỉ cần 40 GiB
↓
io2 thường rẻ hơn cho cùng mức IOPS
Ba lợi ích của io1/io2 cho CSDL: | Lợi ích | Chi tiết | |---|---| | IOPS cấp phát, không phụ thuộc credit | | | Độ trễ dưới một mili giây | | | Hỗ trợ Multi-Attach (io1/io2) | |
⚠ Ghi liên tục vào MỘT bảng cũng có thể là nút thắt ở tầng CSDL:
Mọi ghi vào cùng một bảng
→ tranh chấp khoá, tranh chấp trang index
↓
Đĩa nhanh giúp, nhưng cũng nên xem lại
thiết kế bảng và index
Vì sao các phương án khác sai
- **D. General Purpose SSD (gp2) — đây là phương án gần nhất và cũng là SSD, nhưng hiệu năng dựa trên credit: dưới tải ghi liên tục, credit cạn và IOPS tụt xuống mức cơ sở. Không đáp ứng "MOST consistent".
- **B. Throughput Optimized HDD (st1) — HDD chỉ đạt ~500 IOPS và tối ưu cho đọc/ghi tuần tự; CSDL là I/O ngẫu nhiên.
- **A. Cold HDD (sc1) — chỉ ~250 IOPS, dành cho dữ liệu hiếm khi truy cập; tệ nhất cho tình huống này.
Ghi nhớ về chất lượng câu hỏi
⚠ Ngày nay câu trả lời là io2 Block Express, không phải io1.
| Tiêu chí | io1 | io2 Block Express |
|---|---|---|
| IOPS tối đa mỗi volume | 64.000 | 256.000 |
| Tỷ lệ IOPS/GiB | 50 | 500 |
| Độ bền | 99,8-99,9% | 99,999% |
| Giá mỗi IOPS | như nhau | như nhau |
io2 tốt hơn io1 ở MỌI mặt với CÙNG mức giá
→ AWS khuyến nghị dùng io2 cho thiết kế mới
↓
io1 chỉ còn tồn tại vì tương thích ngược
Và cần cân nhắc thêm: gp3 có thể đủ và rẻ hơn nhiều:
gp3: 3.000 IOPS cơ bản MIỄN PHÍ, tăng tới 16.000
→ KHÔNG có khái niệm credit
→ hiệu năng cũng nhất quán
↓
Cần dưới 16.000 IOPS → gp3 rẻ hơn io2 đáng kể
Cần trên 16.000 IOPS → io2
Ghi nhớ
⚠ Năm loại EBS — bảng phải thuộc: | Loại | IOPS tối đa | Nhất quán | Dùng cho | |---|---|---|---| | gp3 | 16.000 | ✅ không credit | mặc định hiện nay | | gp2 | 16.000 | ❌ có credit | cũ | | io2 Block Express | 256.000 | ✅ | CSDL đòi IOPS cao nhất | | st1 | ~500 | — | tuần tự, thường dùng | | sc1 | ~250 | — | tuần tự, hiếm dùng |
Từ khoá nhận diện:
"consistent performance, low latency, database" → io1/io2 "general purpose, cost-effective" → gp3 "sequential, big data, logs" → st1 "rarely accessed, cheapest" → sc1 "highest IOPS, need shared volume" → io2 Multi-Attach
Ba lưu ý về nút thắt ở instance: | Lưu ý | Chi tiết | |---|---| | Instance có trần băng thông EBS riêng | | | Volume nhanh mà máy nhỏ vẫn nghẽn | | | Bật EBS-optimized | mặc định trên máy đời mới |
⚠ Kiểm tra thông số EBS của loại instance trước:
aws ec2 describe-instance-types --instance-types r6i.2xlarge \
--query "InstanceTypes[0].EbsInfo.EbsOptimizedInfo"
Ba lưu ý về đo hiệu năng: | Metric | Ý nghĩa | |---|---| | VolumeQueueLength | cao là đang nghẽn | | VolumeReadOps / VolumeWriteOps | IOPS thật | | BurstBalance | chỉ có ở gp2 |
Ba lưu ý về chi phí: | Khoản | Chi tiết | |---|---| | io1/io2 tính theo GB + theo IOPS cấp phát | | | 20.000 IOPS là khoản đáng kể mỗi tháng | | | gp3 tính IOPS phụ trội rẻ hơn nhiều | |
Ba lựa chọn thay thế cho CSDL tự quản lý: | Lựa chọn | Lợi ích | |---|---| | RDS MySQL | AWS lo vá, sao lưu, Multi-AZ | | Aurora MySQL | nhanh hơn ~5 lần, lưu trữ tự mở rộng | | Aurora I/O-Optimized | I/O miễn phí khi I/O nặng |
⚠ Với CSDL I/O cao, Aurora thường là câu trả lời tốt hơn EBS:
Aurora tách tính toán và lưu trữ
→ tầng lưu trữ phân tán, 6 bản sao
→ không có volume EBS nào để chọn loại
↓
Và Aurora I/O-Optimized bỏ hẳn phí I/O
Ba lưu ý về đổi loại volume: | Lưu ý | Chi tiết | |---|---| | Đổi được khi volume đang chạy | | | Không cần dừng máy | | | Chờ tối thiểu 6 giờ giữa hai lần | |
aws ec2 modify-volume --volume-id vol-abc \
--volume-type io2 --iops 20000
Ba lưu ý về snapshot: | Lưu ý | Chi tiết | |---|---| | Snapshot CSDL đang chạy có thể không nhất quán | | | Đóng băng I/O hoặc dừng dịch vụ trước | | | Hoặc dùng snapshot của RDS | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo IOPS thật bằng fio hoặc CloudWatch | | | Theo dõi VolumeQueueLength | | | So chi phí io2 và gp3 | |
Và một lời khuyên: hãy tính xem tải thật cần bao nhiêu IOPS trước khi chọn io1. gp3 cho 16.000 IOPS nhất quán với giá thấp hơn nhiều, nên nếu con số thật nằm dưới ngưỡng đó thì Provisioned IOPS chỉ là một khoản chi thêm cho hiệu năng bạn không dùng tới.