Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
A gaming company is building an application to track the scores for their games using an Amazon DynamoDB table. Each item in the table is identified by a partition key
(user_id) and a sort key (game_name). The table also includes the attribute “TopScore”. The table design is shown below:

A Developer has been asked to write a leaderboard application to display the highest achieved scores for each game (game_name), based on the score identified in the “TopScore” attribute.
What process will allow the Developer to extract results MOST efficiently from the DynamoDB table?
-
A
Create a global secondary index with a partition key of “game_name” and a sort key of “TopScore” and get the results based on the score attribute
-
B
Use a DynamoDB scan operation to retrieve the scores for “game_name” using the “TopScore” attribute, and order the results based on the score attribute
-
C
Create a local secondary index with a partition key of “game_name” and a sort key of “TopScore” and get the results based on the score attribute
-
D
Create a global secondary index with a partition key of “user_id” and a sort key of “game_name” and get the results based on the “TopScore” attribute
Xem giải thích
Đáp án
A — Tạo Global Secondary Index với partition key là game_name và sort key là TopScore.
Vì sao đúng
Bảng gốc có khoá chính là user_id (partition) + game_name (sort). Cấu trúc đó trả lời tốt câu hỏi "người dùng X có những điểm nào?", nhưng bảng xếp hạng cần câu hỏi ngược lại: "trò chơi Y có những điểm cao nhất nào?".
Với khoá hiện tại, muốn trả lời câu đó thì phải quét toàn bộ bảng — vì game_name là sort key, và không thể truy vấn theo sort key mà không nêu partition key.
GSI đảo ngược cấu trúc khoá để phục vụ đúng mẫu truy vấn mới:
Bảng gốc: user_id (PK) + game_name (SK)
GSI: game_name (PK) + TopScore (SK) ← đảo lại
Từ đó bảng xếp hạng chỉ là một Query đơn giản:
table.query(
IndexName='LeaderboardIndex',
KeyConditionExpression=Key('game_name').eq('Cờ vua'),
ScanIndexForward=False, # điểm cao nhất trước
Limit=10 # top 10
)
ScanIndexForward=False cho thứ tự giảm dần — DynamoDB tự sắp xếp theo sort key, nên bảng xếp hạng gần như miễn phí về mặt tính toán.
Vì sao các phương án khác sai
- C. Tạo Local Secondary Index với PK
game_namevà SKTopScore— không làm được về mặt kỹ thuật: LSI bắt buộc phải dùng CÙNG partition key với bảng gốc (user_id), chỉ được đổi sort key. Không có cách nào tạo LSI với partition key khác. Đây là điểm loại tuyệt đối, và cũng là khác biệt quan trọng nhất giữa LSI và GSI. - D. GSI với PK
user_idvà SKgame_name— trùng y hệt khoá của bảng gốc, nên không giải quyết được gì mới. Vẫn không truy vấn được theogame_namemột mình. - B. Dùng
Scanrồi sắp xếp kết quả — cho ra đáp án đúng nhưng cực kỳ kém hiệu quả: đọc toàn bộ bảng ở mỗi lần hiển thị bảng xếp hạng, tốn RCU tỷ lệ với kích thước bảng và chậm dần theo thời gian. Đề hỏi cách "MOST efficiently".
Ghi nhớ
Khác biệt cốt lõi giữa hai loại index: | | LSI | GSI | |---|---|---| | Partition key | PHẢI giống bảng gốc | tự do chọn | | Sort key | bắt buộc, khác bảng gốc | tuỳ chọn | | Tạo lúc nào | CHỈ khi tạo bảng | bất cứ lúc nào | | Xoá được | ❌ | ✅ | | Số lượng | 5 | 20 | | Strongly consistent read | ✅ | ❌ không bao giờ | | Capacity | dùng chung với bảng | RIÊNG | | Giới hạn kích thước | 10 GB mỗi partition key | không |
Hai dòng in đậm là chỗ hay bị hỏi nhất. Và cách chọn rất gọn:
- Đổi partition key ⇒ bắt buộc GSI
- Giữ partition key, chỉ đổi cách sắp xếp ⇒ LSI được (nhưng phải nghĩ tới từ lúc tạo bảng)
Ba lưu ý khi dùng GSI:
- Cấp WCU riêng cho GSI — thiếu sẽ throttle cả bảng gốc, dù bảng gốc còn dư capacity.
- GSI luôn eventually consistent — bảng xếp hạng có thể trễ vài trăm mili giây, hoàn toàn chấp nhận được với nghiệp vụ này.
- Dùng
ProjectionTypehợp lý: chỉ chiếu các thuộc tính cần hiển thị (KEYS_ONLYhoặcINCLUDE) để GSI nhỏ và rẻ hơn — chiếuALLlà nhân đôi chi phí lưu trữ.
A developer is planning the deployment of a new version of an application to AWS Elastic Beanstalk. The new version of the application should be deployed only to new EC2 instances.
Which deployment methods will meet these requirements? (Select TWO.)
-
A
All at once
-
B
Rolling
-
C
Rolling with additional batch
-
D
Immutable
-
E
Blue/green
Xem giải thích
Đáp án
D và E.
- D — Immutable
- E — Blue/green
Vì sao đúng
Yêu cầu rất cụ thể: phiên bản mới chỉ được triển khai lên các EC2 instance MỚI — tức là không đụng vào instance đang chạy.
Chỉ hai cách làm được điều đó:
D — Immutable. Beanstalk tạo một Auto Scaling group tạm thời với toàn bộ instance mới:
[cũ][cũ][cũ][cũ] + ASG tạm: [mới][mới][mới][mới]
↓ sau khi mới qua health check
chuyển sang ASG gốc, huỷ instance cũ
Không instance cũ nào bị cập nhật tại chỗ.
E — Blue/green. Dựng hẳn một môi trường Beanstalk mới, triển khai vào đó, rồi hoán đổi CNAME:
eb create moi-truong-xanh --version v2
# kiểm thử kỹ trên môi trường xanh
eb swap moi-truong-lam --destination-name moi-truong-xanh
Cũng hoàn toàn là instance mới, và rollback chỉ là hoán đổi CNAME ngược lại — nhanh nhất trong tất cả các cách.
Vì sao các phương án khác sai
- A. All at once — cập nhật TẠI CHỖ trên chính các instance đang chạy, và gây downtime hoàn toàn trong lúc đó.
- B. Rolling — cũng cập nhật tại chỗ, theo từng lô. Không có instance mới nào được tạo, và năng lực bị giảm trong quá trình.
- C. Rolling with additional batch — đây là phương án gây nhầm nhất, vì nó CÓ tạo thêm instance mới. Nhưng lô thêm đó chỉ để giữ đủ năng lực; các instance cũ vẫn được cập nhật tại chỗ theo từng lô. Nên nó không thoả yêu cầu "chỉ triển khai lên instance mới".
Ghi nhớ
Bảng phân loại theo tiêu chí "có đụng vào instance cũ không": | Chính sách | Cập nhật tại chỗ | Instance mới | |---|---|---| | All at once | ✅ tất cả cùng lúc | ❌ | | Rolling | ✅ từng lô | ❌ | | Rolling with additional batch | ✅ từng lô | thêm lô tạm | | Immutable | ❌ | ✅ toàn bộ | | Blue/green | ❌ | ✅ môi trường mới |
So sánh hai phương án đúng: | | Immutable | Blue/green | |---|---|---| | Phạm vi | trong cùng một môi trường | hai môi trường riêng | | Chuyển đổi | Beanstalk tự làm | hoán đổi CNAME thủ công | | Rollback | huỷ ASG tạm | hoán đổi CNAME ngược — nhanh nhất | | Kiểm thử trước | qua health check | kiểm thử đầy đủ trên URL riêng | | Chi phí | gấp đôi tạm thời | gấp đôi lâu hơn |
(Một chi tiết đáng biết: blue/green không phải một "deployment policy" trong danh sách của Beanstalk — nó là kỹ thuật vận hành dựa trên tính năng hoán đổi CNAME. Còn immutable thì đúng là một policy chọn được trong cấu hình môi trường. Cả hai vẫn là đáp án đúng cho câu hỏi này vì đề hỏi "deployment methods", không hỏi "deployment policies".)
Lưu ý về DNS khi dùng blue/green: sau khi hoán đổi CNAME, các client đang cache DNS cũ vẫn tới môi trường cũ trong khoảng TTL. Đừng huỷ môi trường cũ ngay — hãy chờ ít nhất vài lần TTL.
A website is running on a single Amazon EC2 instance. A Developer wants to publish the website on the Internet and is creating an A record on Amazon Route 53 for the website’s public DNS name.
What type of IP address MUST be assigned to the EC2 instance and used in the A record to ensure ongoing connectivity?
-
A
Dynamic IP address
-
B
Private IP address
-
C
Elastic IP address
-
D
Public IP address
Xem giải thích
Đáp án
C — Elastic IP address.
Vì sao đúng
Điểm mấu chốt nằm ở hai chữ trong đề: "ongoing connectivity" — kết nối phải duy trì được lâu dài.
Public IP thông thường của EC2 KHÔNG cố định. Nó bị thu hồi và cấp lại trong nhiều tình huống:
| Tình huống | Public IP thường | Elastic IP |
|---|---|---|
| Dừng rồi khởi động lại instance | ĐỔI | giữ nguyên |
| Instance bị thay thế | mất | gán lại được |
| Khởi động lại (reboot) | giữ | giữ |
Với bản ghi A trong Route 53, bạn phải nhập một địa chỉ IP cụ thể. Nếu IP đó đổi sau mỗi lần dừng máy, bản ghi DNS trỏ vào một địa chỉ không còn thuộc về bạn — website sập, và tệ hơn là IP đó có thể đã được cấp cho khách hàng khác của AWS.
Elastic IP là địa chỉ IPv4 công khai tĩnh, thuộc về tài khoản bạn cho tới khi bạn tự giải phóng:
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-1234567890abcdef0 --allocation-id eipalloc-abc123
Và khi instance hỏng, bạn gán chính EIP đó sang máy mới — bản ghi DNS không cần đụng tới.
Vì sao các phương án khác sai
- D. Public IP address (thường) — đây là bẫy chính. Nó hoạt động ngay lúc cấu hình, nên dễ tưởng là đúng, nhưng sẽ đổi sau lần stop/start đầu tiên — vi phạm yêu cầu "ongoing".
- B. Private IP address — chỉ định tuyến được bên trong VPC. Người dùng Internet không thể tới được, nên website không công khai được.
- A. "Dynamic IP address" — không phải một loại địa chỉ chính thức của EC2, và bản thân tính "động" chính là vấn đề cần tránh.
Ghi nhớ
Ba loại địa chỉ IP của EC2: | Loại | Phạm vi | Cố định | |---|---|---| | Private IP | trong VPC | ✅ suốt vòng đời instance | | Public IP | Internet | ❌ đổi khi stop/start | | Elastic IP | Internet | ✅ tới khi bạn giải phóng |
Vài đặc điểm của Elastic IP:
- Miễn phí khi đang gắn vào instance đang chạy; có phí khi để không — cơ chế để AWS khuyến khích trả lại địa chỉ không dùng. (Từ tháng 2/2024, AWS tính phí cho mọi địa chỉ IPv4 công khai, kể cả đang dùng.)
- Giới hạn mặc định 5 EIP mỗi Region (xin tăng được).
- Gán lại sang instance khác trong vài giây — rất hữu ích cho kịch bản failover thủ công.
Nhưng với kiến trúc thật, thường có lựa chọn tốt hơn Elastic IP: | Kiến trúc | Cách trỏ DNS | |---|---| | Một instance duy nhất | Elastic IP + bản ghi A | | Sau load balancer | bản ghi ALIAS trỏ tới DNS của ALB | | Qua CloudFront | bản ghi ALIAS trỏ tới distribution |
Bản ghi ALIAS của Route 53 đáng nhớ: nó trỏ tới tên DNS của tài nguyên AWS thay vì một IP cố định, nên tự động theo kịp khi hạ tầng bên dưới thay đổi. Và nó miễn phí truy vấn với đích là tài nguyên AWS, khác với CNAME.
Đề này nói rõ một EC2 instance duy nhất, nên Elastic IP là câu trả lời đúng — nhưng nếu website quan trọng, đặt ALB phía trước sẽ là thiết kế tốt hơn nhiều.
A company is deploying a new serverless application with an AWS Lambda function. A developer ran some test invocations using the AWS CLI. The function is invoking correctly and returning a success message, but not log data is being generated in Amazon CloudWatch Logs. The developer waited for 15 minutes but the log data is not showing up.
What is the most likely explanation for this issue?
-
A
A log group and log stream has not been configured for the function in CloudWatch Logs.
-
B
The function configuration does not have CloudWatch Logs configured as a success destination.
-
C
The Lambda function does not have any explicit log statements for the log data to send it to CloudWatch Logs.
-
D
The function execution role does not have permission to write log data to CloudWatch Logs.
Xem giải thích
Đáp án
D — Execution role của hàm không có quyền ghi log vào CloudWatch Logs.
Vì sao đúng
Triệu chứng rất đặc trưng: hàm chạy thành công, trả về kết quả đúng, nhưng không có log nào. Đó gần như luôn là vấn đề quyền.
Lambda ghi log bằng chính execution role của hàm. Nếu role đó thiếu quyền, việc ghi log thất bại — nhưng thất bại âm thầm: nó không làm hàm lỗi, không có thông báo nào, và bạn chỉ thấy CloudWatch trống rỗng.
Quyền tối thiểu cần có:
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
Cách sửa nhanh nhất là gắn managed policy có sẵn:
aws iam attach-role-policy --role-name RoleHamCuaToi \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
AWSLambdaBasicExecutionRole chính là policy chứa đúng ba quyền trên — và nó được gắn tự động khi bạn tạo hàm qua Console. Vấn đề này thường xuất hiện khi hàm được tạo bằng CloudFormation, CDK hay Terraform với role tự khai mà quên phần log.
Vì sao các phương án khác sai
- A. Chưa cấu hình log group và log stream — Lambda TỰ TẠO chúng ở lần chạy đầu tiên (log group tên
/aws/lambda/<ten-ham>) — với điều kiện role có quyềnCreateLogGroup. Nên nếu thiếu, nguyên nhân gốc vẫn quay về quyền. - B. Chưa cấu hình CloudWatch Logs làm "success destination" — nhầm hai cơ chế: destination dùng để gửi KẾT QUẢ của lần gọi bất đồng bộ tới SQS, SNS, Lambda hoặc EventBridge. Nó không liên quan tới việc ghi log thông thường, và CloudWatch Logs không phải một loại destination hợp lệ.
- C. Hàm không có câu lệnh log tường minh nào — đây là phương án đáng cân nhắc, nhưng nó không giải thích được toàn bộ triệu chứng: kể cả khi mã không hề gọi
printhaylogger, Lambda vẫn luôn ghi ba dòng hệ thống cho mỗi lần chạy:
Đề nói không có dữ liệu log nào cả — nên ngay cả ba dòng này cũng không tới được, và đó chỉ có thể là vấn đề quyền.START RequestId: abc-123 Version: $LATEST END RequestId: abc-123 REPORT RequestId: abc-123 Duration: 12.34 ms Billed Duration: 13 ms ...
Ghi nhớ
Ba dòng log hệ thống ở trên là manh mối chẩn đoán rất hữu ích: | Quan sát | Kết luận | |---|---| | Không có dòng nào | thiếu quyền ghi log | | Có START/END/REPORT nhưng thiếu log của bạn | mã không ghi log, hoặc sai mức log | | Có log nhưng thiếu vài lần gọi | có thể bị throttle ở CloudWatch Logs |
Danh sách kiểm khi Lambda không có log:
- Execution role có
AWSLambdaBasicExecutionRolechưa? ← nguyên nhân phổ biến nhất - Có resource policy hoặc SCP nào chặn
logs:*không? - Log group có bị đặt retention quá ngắn (1 ngày) khiến log đã bị xoá?
- Đang xem đúng Region chứ?
Các managed policy hay dùng cho Lambda: | Policy | Thêm quyền | |---|---| | AWSLambdaBasicExecutionRole | log CloudWatch | | AWSLambdaVPCAccessExecutionRole | log + tạo/xoá ENI trong VPC | | AWSLambdaDynamoDBExecutionRole | log + đọc DynamoDB Streams | | AWSLambdaSQSQueueExecutionRole | log + đọc SQS |
Ba policy cuối đã bao gồm quyền log — nên gắn một trong số chúng là đủ, không cần gắn thêm BasicExecutionRole.
An application writes items to an Amazon DynamoDB table. As the application scales to thousands of instances, calls to the DynamoDB API generate occasional ThrottlingException errors. The application is coded in a language incompatible with the AWS SDK.
How should the error be handled?
-
A
Pass API calls through Amazon API Gateway
-
B
Add exponential backoff to the application logic
-
C
Send the items to DynamoDB through Amazon Kinesis Data Firehose
-
D
Use Amazon SQS as an API message bus
Xem giải thích
Đáp án
B — Thêm exponential backoff vào logic của ứng dụng.
Vì sao đúng
Chi tiết quyết định nằm ở câu cuối của đề: ứng dụng viết bằng ngôn ngữ không tương thích với AWS SDK.
Điều đó quan trọng vì AWS SDK vốn đã có sẵn cơ chế thử lại với exponential backoff cho các lỗi như ThrottlingException. Ứng dụng không dùng được SDK nghĩa là nó không có cơ chế đó, và phải tự cài đặt.
Cách cài đặt, bằng bất kỳ ngôn ngữ nào:
lan_thu = 0
lặp:
goi_api_dynamodb()
nếu thành công: dừng
nếu lỗi là ThrottlingException:
cho = (2 ^ lan_thu) * 100ms + ngẫu_nhiên(0..100ms)
ngủ(cho)
lan_thu += 1
ngược lại: ném lỗi
Các khoảng chờ tăng theo cấp số nhân: 100ms → 200ms → 400ms → 800ms → 1,6s, cho DynamoDB thời gian phân bổ lại năng lực.
Thành phần ngẫu nhiên (jitter) không phải trang trí. Đề nói ứng dụng đã mở rộng tới hàng nghìn instance — nếu tất cả cùng bị throttle và cùng thử lại đúng một thời điểm, chúng tạo ra đỉnh mới ngay lập tức. Hiện tượng này gọi là thundering herd, và jitter là cách chuẩn để rải các lần thử ra.
ThrottlingException là lỗi tạm thời — thử lại sau một chút thường thành công, nhất là khi DynamoDB có burst capacity tích luỹ từ 300 giây trước đó.
Vì sao các phương án khác sai
- D. Dùng SQS làm bus tin nhắn cho API — có tác dụng san phẳng đỉnh và là kiến trúc hợp lý trong một số trường hợp, nhưng nó thay đổi hẳn mô hình ứng dụng: ghi trở thành bất đồng bộ, phải viết consumer, phải xử lý thứ tự và trùng lặp. Quá nặng cho vấn đề mà backoff giải quyết được bằng vài chục dòng.
- C. Gửi item qua Kinesis Data Firehose — Firehose không hỗ trợ DynamoDB làm đích. Đích của nó là S3, Redshift, OpenSearch, Splunk và HTTP endpoint. Phương án này không chạy được.
- A. Cho lời gọi API đi qua API Gateway — thêm một tầng mà không giải quyết gì: DynamoDB vẫn throttle như cũ. API Gateway có throttling riêng nhưng đó là để bảo vệ chính nó, không phải để hấp thụ throttle của DynamoDB.
Ghi nhớ
Các lỗi nên và không nên thử lại: | Lỗi | Thử lại? | |---|---| | ThrottlingException, ProvisionedThroughputExceededException | ✅ với backoff + jitter | | RequestLimitExceeded | ✅ | | 5xx (lỗi máy chủ) | ✅ | | ValidationException, AccessDenied | ❌ thử lại vô ích | | ConditionalCheckFailedException | ❌ (phải đọc lại rồi mới thử) |
Ngoài backoff, các cách giảm throttle cho DynamoDB: | Cách | Chi tiết | |---|---| | On-demand mode | không bao giờ throttle, đắt hơn khi tải đều | | Auto Scaling cho provisioned | tự tăng WCU, phản ứng chậm vài phút | | Sửa partition key | nếu nguyên nhân là hot partition | | Giảm kích thước item | ít WCU hơn cho mỗi lần ghi |
Dòng thứ ba đáng kiểm tra trước tiên: nếu throttle tập trung vào một partition key (ví dụ mọi bản ghi cùng có ngay = hôm nay), thì không lượng WCU nào cứu được — phải thiết kế lại khoá, chẳng hạn thêm hậu tố ngẫu nhiên để rải đều.
Với ứng dụng không dùng SDK, hãy xem CloudWatch metric ThrottledRequests và ConsumedWriteCapacityUnits để biết vấn đề là thiếu capacity toàn cục hay chỉ nóng ở một phân vùng.
An application is being migrated into the cloud. The application is stateless and will run on a fleet of Amazon EC2 instances. The application should scale elastically. How can a Developer ensure that the number of instances available is sufficient for current demand?
-
A
Create a launch configuration and use Amazon EC2 Auto Scaling
-
B
Create a launch configuration and use Amazon CodeDeploy
-
C
Create a task definition and use an Amazon ECS cluster
-
D
Create a task definition and use an AWS Fargate cluster
Xem giải thích
Đáp án
A — Tạo launch configuration và dùng Amazon EC2 Auto Scaling.
Vì sao đúng
Đề nêu ba dữ kiện, và chúng cùng chỉ về Auto Scaling:
- Ứng dụng chạy trên fleet EC2 instance
- Ứng dụng phi trạng thái — điều kiện tiên quyết để co giãn được
- Cần đảm bảo số instance đủ cho nhu cầu hiện tại
EC2 Auto Scaling làm đúng việc đó: nó liên tục so số instance đang chạy với nhu cầu và tự thêm hoặc bớt:
Tải tăng → CloudWatch alarm → ASG thêm instance
Tải giảm → CloudWatch alarm → ASG bớt instance
Instance hỏng → ASG thay thế bằng máy mới
Cấu hình gồm hai phần: launch template (hoặc launch configuration) mô tả instance trông như thế nào, và Auto Scaling group mô tả bao nhiêu và ở đâu:
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name nhom-ung-dung \
--launch-template LaunchTemplateName=mau-ung-dung \
--min-size 2 --max-size 20 --desired-capacity 4 \
--vpc-zone-identifier "subnet-a,subnet-c" \
--health-check-type ELB --health-check-grace-period 300
Và chính sách co giãn theo mục tiêu là cách đơn giản nhất:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name nhom-ung-dung \
--policy-name giu-cpu-50 --policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {"PredefinedMetricType": "ASGAverageCPUUtilization"},
"TargetValue": 50.0}'
Vì sao các phương án khác sai
- B. Launch configuration + CodeDeploy — CodeDeploy triển khai MÃ, nó không quản lý số lượng instance. Nó là công cụ của bước phát hành, không phải bước co giãn.
- C. Task definition + ECS cluster và D. Task definition + Fargate — task definition là khái niệm của container, không phải EC2. Đề nói rõ ứng dụng chạy trên fleet EC2 instance; chuyển sang container đòi đóng gói lại ứng dụng và thay đổi kiến trúc — vượt quá điều đề hỏi.
Ghi nhớ
Ba trụ cột của kiến trúc web co giãn: | Thành phần | Việc | |---|---| | Auto Scaling group | giữ đúng số instance theo nhu cầu | | Load balancer | phân phối traffic | | Kho trạng thái ngoài | ElastiCache, DynamoDB — để instance phi trạng thái |
Các loại chính sách co giãn: | Loại | Đặc điểm | |---|---| | Target tracking | giữ một metric ở mức mục tiêu — đơn giản nhất | | Step scaling | thêm/bớt theo bậc tuỳ mức vượt ngưỡng | | Simple scaling | một hành động, có cooldown | | Scheduled | theo lịch — biết trước giờ cao điểm | | Predictive | học mẫu tải rồi chuẩn bị trước |
Một lưu ý quan trọng về phương án đúng: đề dùng chữ launch configuration, nhưng trong thực tế hãy dùng launch template. AWS đã ngừng phát triển launch configuration, và chỉ launch template mới hỗ trợ mixed instances policy (trộn On-Demand với Spot), nhiều instance type, và phiên bản hoá.
Và đừng quên đặt HealthCheckType: ELB — với mặc định EC2, ASG chỉ kiểm tra máy còn chạy không, nên ứng dụng chết mà máy vẫn bật sẽ không được thay thế.
A Developer has created an Amazon Cognito user pool and configured a domain for it. The Developer wants to add sign-up and sign-in pages to an app with a company logo.
What should the Developer do to meet these requirements?
-
A
Customize the Amazon Cognito hosted web UI and add the company logo.
-
B
Create a REST API using Amazon API Gateway and add a Cognito authorizer. Upload the company logo to a stage in the API.
-
C
Upload the company logo to an Amazon S3 bucket. Specify the S3 object path in the app client settings in Amazon Cognito.
-
D
Create a custom login page that includes the company logo and upload it to Amazon Cognito. Specify the login page in the app client settings.
Xem giải thích
Đáp án
A — Tuỳ chỉnh giao diện hosted UI của Cognito và thêm logo công ty.
Vì sao đúng
Cognito user pool cung cấp sẵn hosted UI — bộ trang đăng ký, đăng nhập, quên mật khẩu, xác nhận MFA đã dựng sẵn và tuỳ biến được về hình ảnh.
Đề đã nói lập trình viên đã cấu hình domain cho user pool — đó chính là bước bật hosted UI, nên phần còn lại chỉ là tuỳ chỉnh:
aws cognito-idp set-ui-customization \
--user-pool-id ap-southeast-1_xxx \
--client-id abc123 \
--image-file fileb://logo-cong-ty.png \
--css ".banner-customizable { background: #1a3a5c; }
.submitButton-customizable { background-color: #f39c12; }"
Bạn tuỳ chỉnh được: | Thành phần | Cách | |---|---| | Logo | tải tệp ảnh lên (PNG/JPG, tối đa 100 KB) | | Màu sắc, phông, bố cục | CSS với các lớp *-customizable | | Phạm vi | cho cả user pool, hoặc riêng từng app client |
Vì sao đây là cách đúng: hosted UI lo trọn phần khó — luồng OAuth 2.0, xác thực email/SMS, MFA, quên mật khẩu, liên kết với Google/Facebook/SAML. Bạn chỉ thêm nhận diện thương hiệu, không phải viết một dòng mã xác thực nào.
Vì sao các phương án khác sai
- D. Tạo trang đăng nhập tuỳ chỉnh rồi tải lên Cognito — Cognito không nhận trang HTML do bạn tải lên. Bạn chỉ tuỳ chỉnh được logo và CSS của hosted UI. (Muốn kiểm soát hoàn toàn giao diện thì phải tự dựng trang và gọi Cognito API/SDK — nhưng đó là bỏ hosted UI, không phải "tải trang lên Cognito".)
- C. Tải logo lên S3 rồi khai đường dẫn object trong app client settings — app client settings không có trường nào cho logo. Logo được tải trực tiếp qua
set-ui-customization, không phải tham chiếu tới S3. - B. Tạo REST API với Cognito authorizer rồi tải logo lên một stage — nhầm lẫn nhiều tầng: API Gateway stage không chứa tài nguyên giao diện, và Cognito authorizer dùng để bảo vệ API, hoàn toàn không liên quan tới giao diện đăng nhập.
Ghi nhớ
Hai cách dựng giao diện xác thực với Cognito: | | Hosted UI | Tự dựng giao diện | |---|---|---| | Công sức | thấp — chỉ CSS và logo | cao — tự cài đặt mọi luồng | | Tuỳ biến | giới hạn | hoàn toàn | | Luồng OAuth, MFA, social login | có sẵn | tự viết | | Dùng khi | cần nhanh, chấp nhận giao diện chuẩn | thiết kế riêng biệt |
(Ghi chú thời sự: Cognito hiện có managed login — bản hosted UI thế hệ mới với branding designer trực quan, cho phép tuỳ chỉnh sâu hơn nhiều so với chỉ logo và CSS, kể cả logo tối/sáng, phông chữ và bố cục. Bản hosted UI cũ vẫn hoạt động.)
Vài giới hạn cần biết khi tuỳ chỉnh:
- Logo tối đa 100 KB, định dạng JPG, PNG hoặc GIF.
- CSS chỉ áp được cho các lớp
-customizablemà Cognito khai sẵn — không sửa được cấu trúc HTML. - Muốn tên miền riêng (
dang-nhap.congty.comthay vìxxx.auth.region.amazoncognito.com) thì cần chứng chỉ ACM ởus-east-1, giống như CloudFront.
Và nếu cần thêm logic vào luồng đăng nhập (kiểm tra bổ sung, ghi log, thêm claim), dùng Lambda trigger của Cognito (PreSignUp, PostConfirmation, PreTokenGeneration) — vẫn giữ được hosted UI.
An eCommerce application uses an Amazon RDS database with Amazon ElastiCache in front. Stock volume data is updated dynamically in listings as sales are made. Customers have complained that occasionally the stock volume data is incorrect, and they end up purchasing items that are out of stock. A Developer has checked the front end and indeed some items display the incorrect stock count.
What could be causing this issue?
-
A
The Amazon RDS database has insufficient IOPS provisioned for its EBS volumes.
-
B
The stock volume data is being retrieved using a write-through ElastiCache cluster.
-
C
The Amazon RDS database is deployed as Multi-AZ and the standby is inconsistent.
-
D
The cache is not being invalidated when the stock volume data is changed.
Xem giải thích
Đáp án
D — Cache không được làm mất hiệu lực khi dữ liệu tồn kho thay đổi.
Vì sao đúng
Triệu chứng: hệ thống hiển thị số lượng tồn kho sai, và khách mua phải hàng đã hết.
Đó là biểu hiện kinh điển của stale cache: ElastiCache đang phục vụ giá trị cũ trong khi RDS đã có giá trị mới.
10:00 Tồn kho = 5 → ghi vào RDS, ghi vào cache
10:05 Bán 5 sản phẩm → RDS cập nhật = 0
↑ CACHE VẪN LÀ 5
10:06 Khách xem trang → đọc từ cache → thấy "Còn 5 sản phẩm" ✗
Nguyên nhân gốc: ứng dụng đang dùng lazy loading (cache-aside) với TTL, nhưng không xoá hoặc cập nhật cache khi ghi. Cache chỉ tự làm mới khi TTL hết hạn — và trong khoảng đó, dữ liệu sai vẫn được phục vụ.
Hai cách chữa:
Cách 1 — xoá cache khi ghi (cache invalidation):
def cap_nhat_ton_kho(san_pham_id, so_luong):
csdl.update(san_pham_id, so_luong)
cache.delete(f'ton_kho:{san_pham_id}') # ← lần đọc sau sẽ nạp lại từ CSDL
Cách 2 — cập nhật cache khi ghi (write-through):
def cap_nhat_ton_kho(san_pham_id, so_luong):
csdl.update(san_pham_id, so_luong)
cache.setex(f'ton_kho:{san_pham_id}', 300, so_luong)
Với dữ liệu tồn kho thay đổi liên tục, cách 2 thường tốt hơn vì tránh được cú miss ngay sau mỗi lần bán.
Vì sao các phương án khác sai
- B. "Dữ liệu tồn kho được lấy qua cụm ElastiCache write-through" — nói ngược: write-through chính là một trong hai giải pháp, không phải nguyên nhân. Nếu đang dùng write-through thì cache luôn khớp với CSDL và vấn đề này không xảy ra.
- A. RDS thiếu IOPS cho EBS volume — thiếu IOPS gây chậm, không gây sai dữ liệu. Triệu chứng sẽ là truy vấn lâu hoặc timeout, không phải hiển thị con số cũ.
- C. RDS Multi-AZ và bản standby không nhất quán — bản standby của Multi-AZ không phục vụ truy vấn nào cả (khác với read replica), nên nó không thể là nguồn của dữ liệu sai. Ngoài ra nhân bản Multi-AZ là đồng bộ.
Ghi nhớ
Ba chiến lược cache và vấn đề dữ liệu cũ: | Chiến lược | Ghi vào cache khi | Dữ liệu cũ | |---|---|---| | Lazy loading | sau một lần đọc miss | CÓ — tới khi TTL hết | | Write-through | mỗi lần ghi CSDL | không | | Cache invalidation | xoá mục khi ghi | không |
Cách chọn theo tính chất dữ liệu: | Dữ liệu | Chiến lược | |---|---| | Thay đổi liên tục, sai là có hậu quả (tồn kho, giá, số dư) | write-through hoặc invalidation, TTL ngắn | | Ít thay đổi (danh mục, mô tả sản phẩm) | lazy loading, TTL dài | | Chỉ đọc (nội dung tĩnh) | TTL rất dài |
Ba lưu ý thực dụng cho hệ thống thương mại điện tử:
- Luôn đặt TTL, kể cả khi đã có invalidation — nó là lưới an toàn cho các đường ghi bị bỏ sót (job batch, sửa tay trên CSDL).
- Kiểm tra lại tồn kho ở bước thanh toán, đọc trực tiếp từ CSDL — không bao giờ chốt đơn dựa trên số liệu từ cache.
- Với tồn kho, cân nhắc atomic counter hoặc conditional write ở tầng CSDL để chính việc bán hàng không bị đặt quá số lượng.
Điểm thứ hai đáng nhấn mạnh: cache là để hiển thị nhanh, không phải để ra quyết định nghiệp vụ.
An application will use AWS Lambda and an Amazon RDS database. The Developer needs to secure the database connection string and enable automatic rotation every 30 days. What is the SIMPLEST way to achieve this requirement?
-
A
Store a SecureString in Systems Manager Parameter Store and enable automatic rotation every 30 days
-
B
Store a secret in AWS Secrets Manager and enable automatic rotation every 30 days
-
C
Store the connection string as an encrypted environment variable in Lambda and create a separate function that rotates the connection string every 30 days
-
D
Store the connection string in an encrypted Amazon S3 bucket and use a scheduled CloudWatch Event to update the connection string every 30 days
Xem giải thích
Đáp án
B — Lưu bí mật trong AWS Secrets Manager và bật xoay vòng tự động mỗi 30 ngày.
Vì sao đúng
Đề hỏi cách ĐƠN GIẢN NHẤT để vừa bảo vệ chuỗi kết nối vừa xoay vòng tự động mỗi 30 ngày — và Secrets Manager có sẵn cả hai, chỉ bằng cấu hình:
aws secretsmanager rotate-secret \
--secret-id prod/csdl/chuoi-ket-noi \
--rotation-lambda-arn arn:aws:lambda:...:function:SecretsManagerRDSPostgreSQLRotation \
--rotation-rules '{"ScheduleExpression": "rate(30 days)"}'
AWS cung cấp sẵn Lambda xoay vòng cho RDS (MySQL, PostgreSQL, Oracle, SQL Server, MariaDB) — không phải viết một dòng mã nào. Hàm đó thực hiện bốn bước: sinh mật khẩu mới, đổi trong CSDL, thử kết nối, rồi chuyển nhãn AWSCURRENT.
Lambda của ứng dụng chỉ cần đọc bí mật:
import boto3, json
sm = boto3.client('secretsmanager')
bi_mat = json.loads(sm.get_secret_value(SecretId='prod/csdl/chuoi-ket-noi')['SecretString'])
conn = psycopg2.connect(host=bi_mat['host'], user=bi_mat['username'],
password=bi_mat['password'], dbname=bi_mat['dbname'])
Execution role cần secretsmanager:GetSecretValue trên đúng bí mật đó — và không có mật khẩu nào nằm trong mã hay biến môi trường.
Vì sao các phương án khác sai
- A. SSM Parameter Store
SecureStringvới "bật xoay vòng tự động" — đây là phương án gần nhất, và điểm loại rất dứt khoát: Parameter Store KHÔNG có tính năng xoay vòng. Nó mã hoá tốt và miễn phí ở gói standard, nhưng muốn xoay vòng thì phải tự viết Lambda và tự lên lịch. - C. Lưu chuỗi kết nối làm biến môi trường mã hoá của Lambda, viết hàm riêng để xoay vòng — chạy được nhưng nhiều việc nhất: tự viết hàm xoay vòng, tự lên lịch, tự cập nhật biến môi trường của hàm kia (và mỗi lần cập nhật là một lần triển khai). Ngoài ra biến môi trường của Lambda hiện nguyên văn trong Console cho ai có quyền
GetFunctionConfiguration. - D. Lưu trong S3 mã hoá và dùng CloudWatch Event định kỳ cập nhật — cũng là tự dựng lại một dịch vụ đã có, kém hơn ở mọi mặt: không có quy trình xoay vòng bốn bước an toàn, không có phiên bản
AWSPENDING/AWSCURRENT, không có vết kiểm toán riêng cho việc đọc bí mật.
Ghi nhớ
| Secrets Manager | Parameter Store | |
|---|---|---|
| Xoay vòng tự động | ✅ Lambda dựng sẵn cho RDS | ❌ |
| Mã hoá | luôn có (KMS) | tuỳ chọn (SecureString) |
| Chi phí | ~0,40 USD/secret/tháng | standard miễn phí |
| Kích thước | 64 KB | 4 KB / 8 KB |
| Sao chép sang Region khác | ✅ | ❌ |
| Tạo credential cho RDS | ✅ | ❌ |
Quy tắc chọn: cần xoay vòng ⇒ Secrets Manager. Chỉ là cấu hình không nhạy cảm ⇒ Parameter Store.
Ba lưu ý khi dùng với Lambda:
- Cache bí mật trong biến toàn cục, đừng gọi
get_secret_valueở mỗi lần chạy — vừa tốn phí API vừa thêm độ trễ. AWS có sẵn Parameters and Secrets Lambda Extension làm việc này bằng cấu hình. - Nếu Lambda và CSDL nằm trong VPC, cần VPC endpoint cho Secrets Manager (hoặc NAT) để hàm gọi được.
- Cân nhắc
ManageMasterUserPassword: truekhi tạo RDS — RDS tự tạo secret và tự lo xoay vòng, gọn hơn cả việc tự khai.
An application reads data from Amazon S3 and makes 55,000 read requests per second. A Developer must design the storage solution to ensure the performance requirements are met cost-effectively.
How can the storage be optimized to meet these requirements?
-
A
Move the files to Amazon DynamoDB. Index the files with S3 metadata.
-
B
Move the files to Amazon EFS. Index the files with S3 metadata.
-
C
Create at least 10 prefixes and split the files across the prefixes.
-
D
Create at least 10 S3 buckets and split the files across the buckets.
Xem giải thích
Đáp án
C — Tạo ít nhất 10 prefix và chia tệp ra các prefix đó.
Vì sao đúng
S3 có hạn mức hiệu năng tính theo prefix, không phải theo bucket:
| Thao tác | Hạn mức mỗi prefix |
|---|---|
GET / HEAD |
5.500 request/giây |
PUT / POST / DELETE |
3.500 request/giây |
Đề cần 55.000 request đọc mỗi giây. Phép tính rất thẳng:
55.000 ÷ 5.500 = 10 prefix
Nên chia dữ liệu ra ít nhất 10 prefix là đủ đáp ứng:
s3://kho-du-lieu/phan-01/tep.dat
s3://kho-du-lieu/phan-02/tep.dat
...
s3://kho-du-lieu/phan-10/tep.dat
Điểm quan trọng: prefix là bất kỳ chuỗi nào đứng trước tên tệp trong khoá object — nó không phải "thư mục" thật (S3 không có thư mục), mà chỉ là cách S3 phân vùng chỉ mục bên trong.
Và hạn mức này không có trần: bạn tạo bao nhiêu prefix cũng được, nên S3 mở rộng đọc gần như không giới hạn. Nó cũng không tốn thêm chi phí — chỉ là cách đặt tên khoá.
Cách rải phổ biến là băm một phần của định danh để phân bố đều:
import hashlib
def khoa_s3(ma_tep):
tien_to = hashlib.md5(ma_tep.encode()).hexdigest()[:2]
return f'{tien_to}/{ma_tep}'
Vì sao các phương án khác sai
- D. Tạo ít nhất 10 bucket và chia tệp ra các bucket — giải quyết được vấn đề nhưng thừa và phiền: hạn mức áp theo prefix, không phải bucket, nên nhiều prefix trong một bucket đã đủ. Nhiều bucket còn kéo theo nhân bản policy, cấu hình mã hoá, lifecycle rule, và giới hạn mặc định 100 bucket mỗi tài khoản.
- A. Chuyển tệp sang DynamoDB, lập chỉ mục bằng metadata của S3 — DynamoDB giới hạn item 400 KB, không phải nơi lưu tệp. Và di trú toàn bộ dữ liệu để tránh một vấn đề giải được bằng cách đổi tên khoá là hoàn toàn không tương xứng.
- B. Chuyển sang EFS — đắt hơn S3 nhiều lần cho cùng dung lượng, và EFS có mô hình hiệu năng riêng (throughput mode) cũng cần điều chỉnh. Trái yêu cầu "cost-effectively".
Ghi nhớ
Hiệu năng của S3: | Điểm | Chi tiết | |---|---| | Hạn mức theo PREFIX | 5.500 GET / 3.500 PUT mỗi giây | | Số prefix | không giới hạn | | Tự động mở rộng | S3 tự chia phân vùng theo thời gian, nhưng cần vài phút tới vài giờ | | Chi phí | rải prefix không tốn thêm đồng nào |
Cách đặt tên khoá để rải đều:
✅ Tốt (rải đều):
a1/2026-08-05/du-lieu.json
7f/2026-08-05/du-lieu.json
❌ Kém (dồn vào một prefix, dễ nóng):
2026-08-05/00001.json
2026-08-05/00002.json
(Ghi chú lịch sử: trước 2018, S3 khuyến nghị đặt ký tự ngẫu nhiên ở ĐẦU khoá vì phân vùng dựa trên tiền tố chung. Từ khi S3 tự mở rộng theo prefix, khuyến nghị đó không còn bắt buộc — nhưng rải prefix vẫn hữu ích khi cần thông lượng rất cao ngay lập tức, vì việc tự mở rộng cần thời gian làm nóng.)
Ba cách khác để tăng hiệu năng đọc từ S3: | Cách | Khi nào | |---|---| | CloudFront | nhiều người đọc cùng nội dung — giảm hẳn request tới S3 | | Byte-range fetch | tệp lớn, đọc song song nhiều phần | | S3 Transfer Acceleration | tải lên từ xa (không giúp cho đọc) |
Với 55.000 request/giây trên nội dung lặp lại, CloudFront thường là giải pháp rẻ hơn nữa — nhưng đề chỉ hỏi cách tối ưu chính kho lưu trữ.