Amazon Aurora MySQL Bài 26: Sử dụng AWS RDS Proxy để bảo vệ Aurora MySQL khỏi hiện tượng sốc kết nối (Connection Storm)
Ở Bài 25, chúng ta đã tìm hiểu về khái niệm Connection Pooling và sự khác biệt giữa Client-side với Proxy-based pooling. Trong bài viết này, chúng ta sẽ đi sâu vào thực chiến cách sử dụng AWS RDS Proxy – một dịch vụ quản lý kết nối chuyên dụng được AWS thiết kế để bảo vệ cụm Aurora MySQL khỏi thảm họa Connection Storm (Sốc kết nối).
1. Hiện tượng "Connection Storm" là gì và nó đáng sợ thế nào?
Hãy tưởng tượng hệ thống backend của bạn chạy trên AWS Lambda hoặc Amazon ECS Fargate.
-
Đột nhiên, một sự kiện lớn diễn ra (ví dụ: chiến dịch Flash Sale bắt đầu đúng 0h00 tại Hasaki), hàng chục ngàn container hoặc hàm Lambda cùng một lúc được kích hoạt tự động (auto-scaling) để xử lý lượng request khổng lồ từ người dùng.
-
Mỗi container/lambda khi khởi động sẽ lập tức mở một loạt kết nối mới (
New Connections) vào cơ sở dữ liệu Aurora. -
Hậu quả: Hàng ngàn kết nối đổ ập vào cùng một khoảnh khắc tạo ra hiện tượng Connection Storm. CPU của database bị ngốn sạch chỉ để xử lý việc bắt tay TCP, cấp phát luồng (
thread allocation) và xác thực mật khẩu, thay vì chạy câu lệnh SQL. Kết quả là cơ sở dữ liệu sập nguồn vì cạn kiệt tài nguyên (Out of MemoryhoặcToo many connections), mặc dù dữ liệu và câu lệnh SQL hoàn toàn bình thường.
2. AWS RDS Proxy hoạt động như thế nào để giải cứu hệ thống?
AWS RDS Proxy là một lớp trung gian được quản lý hoàn toàn (Fully Managed Proxy) nằm giữa ứng dụng backend và cụm Aurora MySQL của bạn.
-
Cơ chế Multiplexing (Dồn kênh kết nối):
-
Ứng dụng backend không còn kết nối trực tiếp vào Aurora nữa, mà kết nối vào RDS Proxy Endpoint.
-
RDS Proxy duy trì một tập hợp các kết nối bền vững sẵn sàng (
pre-established connection pool) với Aurora MySQL ở bên dưới. -
Khi hàng chục ngàn request từ Lambda/ECS đổ vào proxy cùng lúc, proxy sẽ giữ lại các request đó trong hàng đợi thông minh, sử dụng lại các kết nối đã mở sẵn với database để thực hiện query luân phiên, triệt tiêu hoàn toàn gánh nặng tạo mới kết nối trên Aurora.
-
-
Cải thiện tốc độ phản hồi (Session Pinning & Query Efficiency): Proxy nhận biết các transaction rõ ràng (ví dụ trong một khối
BEGIN...COMMIT) để ghim kết nối cho đến khi transaction kết thúc, sau đó tái sử dụng kết nối đó cho các transaction tiếp theo cực kỳ linh hoạt.
3. Vị cứu tinh trong các tình huống Failover (Zero-Downtime Failover cho App)
Bên cạnh việc chống sốc kết nối, RDS Proxy còn đóng vai trò cực kỳ quan trọng trong việc che giấu sự cố Failover của Aurora:
-
Khi Aurora thực hiện đổi Writer (như đã học ở Bài 17), thông thường ứng dụng backend sẽ nhận lỗi mất kết nối và cần thời gian để thử lại.
-
Khi đứng sau RDS Proxy, khi xảy ra Failover, proxy sẽ tự động giữ lại các câu lệnh SQL đang chờ trong hàng đợi, ngầm định hướng chúng sang Writer mới vừa được bầu chọn mà không trả về bất kỳ lỗi mất kết nối nào cho ứng dụng. Ứng dụng backend cảm thấy hệ thống chạy mượt mà liên tục như không có chuyện gì xảy ra.
4. Cách cấu hình AWS RDS Proxy cho Aurora MySQL
Trong môi trường thực tế, RDS Proxy được dựng nhanh chóng qua AWS Console hoặc qua Terraform. Dưới đây là đoạn script Terraform mẫu:
Terraform
# 1. Tạo IAM Role cho RDS Proxy để truy cập AWS Secrets Manager lấy mật khẩu DB
resource "aws_iam_role" "rds_proxy_role" {
name - "hieu-rds-proxy-role"
assume_role_policy = jsonencode({
Version - "2012-10-17"
Statement = [{
Action - "sts:AssumeRole"
Effect - "Allow"
Principal = { Service = "rds.amazonaws.com" }
}]
})
}
# 2. Khởi tạo AWS RDS Proxy trỏ vào Aurora Cluster
resource "aws_db_proxy" "aurora_proxy" {
name - "hieu-aurora-mysql-proxy"
debug_logging - false
engine_family - "MYSQL"
idle_client_timeout - 1800
require_tls - true
role_arn - aws_iam_role.rds_proxy_role.arn
vpc_subnet_ids - [aws_subnet.subnet_az1.id, aws_subnet.subnet_az2.id]
vpc_security_group_ids - [aws_security_group.db_sg.id]
auth {
auth_scheme - "SECRETS"
description - "Use Secrets Manager for database credentials"
iam_auth - "DISABLED"
secret_arn - aws_secretsmanager_secret.db_secret.arn
}
depends_on = [aws_secretsmanager_secret_version.secret_val]
}
# 3. Gắn Proxy vào Aurora Cluster Target Group
resource "aws_db_proxy_default_target_group" "proxy_target" {
db_proxy_name = aws_db_proxy.aurora_proxy.name
connection_pool_config {
connection_borrow_timeout = 120
max_connections_percent = 100
max_idle_connections_percent = 50
}
}
resource "aws_db_proxy_target" "cluster_target" {
db_cluster_identifier - aws_rds_cluster.aurora_cluster.id
db_proxy_name - aws_db_proxy.aurora_proxy.name
target_group_name - aws_db_proxy_default_target_group.proxy_target.name
}
5. Góc nhìn vận hành cho Backend Engineer
-
Khi nào nên dùng RDS Proxy? Nếu backend của bạn là hệ thống Serverless (AWS Lambda) hoặc các cụm container scale cực nhanh chịu tải cao, việc đặt RDS Proxy trước Aurora MySQL là tiêu chuẩn vàng (
Best Practice). -
Lưu ý về chi phí: RDS Proxy tính phí dựa trên số lượng vCPU của instance cơ sở dữ liệu mà nó bảo vệ (tính theo giờ). Hãy cân nhắc chi phí này so với thiệt hại tiềm tàng khi hệ thống bị sập do sốc kết nối trong các đợt cao điểm.
All rights reserved