Tiết kiệm chi phí, tối ưu với Lambda và CloudWatch AWS
Vấn đề:
Dự án Precog là một dự án big data dùng để lấy dữ liệu và tính toán định kỳ hàng tuần. Những dữ liệu tinh chỉnh này được cung cấp trực tiếp cho khách hàng. Hiện tại, chi phí cho việc duy trì server 24/7 để tính toán đang rất cao, mà hiệu suất đem lại vẫn chưa thực sự tối ưu. Vì thế, dự án quyết định áp dụng tính chất elastic của cloud để tối ưu hiệu suất và chi phí. Ở đây, chúng tôi sử dụng Lambda và CloudWatch:
I. Lambda:
AWS Lambda là một dịch vụ được cung cấp bởi Amazon nơi mà có thể write/upload code và trả về một HTTP request. AWS Lambda sử dụng tài nguyên của AWS để chạy các đoạn code(function). Với Lambda ta có thể chạy gần như toàn bộ các loại ứng dụng hay dịch vụ backend – tất cả đều không cần quản trị. Lambda có thể được kích hoạt trực tiếp bởi các dịch vụ AWS như S3, DynamoDB, Kinesis, SNS và CloudWatch hoặc có thể được sắp xếp thành quy trình bằng các AWS Step Function. Điều này cho phép Dev xây dựng nhiều hệ thống xử lý dữ liệu real-time serverless.
Lambda hỗ chợ các ngôn ngữ sau:
- NodeJs v10.15 và v8.10
- Java 8
- Python 3.7, 3.6 và 2.7
- .NET Core : 1.0.1 và 2.1
- Go 1.x
- Ruby 2.5
- Rust
Mỗi function chạy trong một container Amazon Linux AMI 64 bit. Và môi trường thực thi có:
- Memory: 128MB – 3008MB, in 64 MB increments
- Ephemeral disk space: 512MB
- Max execution duration: 900 seconds
- Compressed package size: 50MB
- Uncompressed package size: 250MB
Mô hình tài nguyên linh hoạt: Bạn chỉ cần chọn lượng bộ nhớ muốn phân bổ cho function, AWS Lambda sẽ phân phối công suất CPU, băng thông mạng và I/O ổ đĩa theo tỷ lệ tương ứng.
Chi phí: Với lambda ta chỉ cần trả phí khi ta sử dụng. Chi phí được tính dựa trên số lượng requets cho function và thời lượng thời gian cần thiết để hoàn thành function đó.
Thời gian được tính từ khi function bắt đầu thực thi cho đến khi nó trả về hoặc kết thúc, thời gian được làm tròn đến 100ms gần nhất. Trước khi function kết thúc các Lambda function được AWS đặt trong container và AWS thì không tính phí cho việc này. Lambda cung cấp miễn phí 1M requests mỗi tháng và 400.000 GB giây tính toán mỗi tháng. Trước đây, nó có giá $0,20 cho mỗi 1 triệu requests và $0,00001667 cho mỗi GB giây.
Vậy ta có thể thấy thay vì phải trả phí all_time thì ta chỉ cần trả phí khi nào ta sử dụng -> tiết kiệm chi phí, hơn nữa chi phí cơ sở hạ tầng bỏ ra cho Lambda là rất ít.
Các bước tạo một lambda: Chúng ta bắt đầu tạo một serverless “Hello, World” với AWS Lambda.
Chọn lambda trong Compute:
- Create function
- Chọn Use a blueprint; trong Blueprint chọn Hello-world-python → Configure để bắt đầu tạo một Lambda function
3. Nhập các thông tin cơ bản cho Lambda function
Function name: nhập tên của function
Execution role: chọn một IAM role (trong VD này tôi chọn một role đã tạo của dự án)
Existing role: chọn tên role hiện có.
Click Create function
4. Test function bằng cách click vào Test, ta có thể chọn mã code tại Runtime, chỉ định function/method tại Handler
5. Nhập Event name
→ kết quả test trả về HTTP requests như sau:
II. CloudWatch:
Amazon CloudWatch là một dịch vụ theo dõi và quan sát được xây dựng cho các DevOps, Developers,… nó cung cấp dữ liệu và thông tin chuyên sâu để ta theo dõi ứng dụng, ứng phó với các thay đổi hiệu suất trên toàn hệ thống, tối ưu hóa việc sử dụng tài nguyên và có cái nhìn thống nhất về tình trạng vận hành. Sử dụng Amazon CloudWatch để có cái nhìn trên toàn hệ thống về việc sử dụng tài nguyên, hiệu suất ứng dụng và tình trạng hoạt động; Sử dụng những hiểu biết này để theo dõi và giữ cho ứng dụng của bạn chạy trơn tru.
Bảo mật: Amazon CloudWatch được tích hợp với AWS Identity and Access Management (IAM) nên bạn có thể kiểm soát người dùng và tài nguyên nào được phép truy cập vào dữ liệu của bạn và cách thức họ truy cập.
Các bước lập lịch với CloudWatch:
Tạo một CloudWatch:
+ Mở CloudWatch.
+ Chọn Events → Rules → Create rule
+ Với Event Source:
- 1. Chọn Event Pattern để tạo một cloudwatch event lập lịch các event được cung cấp bởi AWS.
2. Service Name: chọn service tạo ra event để bắt đầu lập lịch
3. Event Type: chọn một event xác định, nếu chỉ có sự lựa chọn duy nhất là AWS API Call via CloudTrail thì service được chọn sẽ không tạo ra các event, ta chỉ có các rules cơ bản trên các lệnh gọi API cho service này
4. Tuỳ vào các service tạo ra event sẽ có các tuỳ chọn Any hoặc Specific. Chọn Any để kích hoạt event trên bất kỳ loại event được chọn, chọn Specific để chọn một hoặc nhiều event cụ thể.
5. Với Targets: chọn Add Target và chọn AWS service để thực thi khi phát hiện một event của loại đã chọn
6. Nhập các thông tin cụ thể của các mục khác cho Target đã chọn nếu cần
7. Đối với nhiều loại target, cloudwatch cần có quyền để gửi các event. Lúc này CloudWatch Events có thể tạo IAM role cần thiết cho event để run:
Để tự động tạo IAM role, chọn Create a new role for this specific resource
Để sử dụng IAM role đã tạo, chọn Use existing role
8. Lặp lại các bước 5-7 với các target khác
9. Chọn Configure details, với Rule definition nhập tên và mô tả cho rule. Tên rule phải là duy nhất trong Region.
10. Create rule.
- Chọn Schedule để lập lịch các sự kiện theo quy tắc:
- Chọn Fixed rate of và điền thời gian xác định để lập lịch, hoặc chọn Cron expression để lập lịch theo biểu thức (phần tiếp theo).
- Với Target, chọn Add target và chọn AWS service(VD: Lambda function)
- Nhập các thông tin cụ thể khác nếu cần(VD: chọn function cần lập lịch)
- Đối với nhiều loại target, cloudwatch cần có quyền để gửi các event. Lúc này CloudWatch Events có thể tạo IAM role cần thiết cho event để run
Để tự động tạo IAM role, chọn Create a new role for this specific resource
Để sử dụng IAM role đã tạo, chọn Use existing role
5. Lặp lại các bước 2-4 với các target được thêm khác
6. Chọn Configure details, với Rule definition nhập tên và mô tả cho rule. Tên rule phải là duy nhất trong Region.
7. Create rule
Biểu thức lập lịch:
Có hai cách lập lịch trong Cloudwatch Event là biểu thức cron hoặc rate
- Cron:
BIểu thức gồm 6 trường bắt buộc được phân tách bằng khoảng trắng. 6 trường lần lượt gồm “phút giờ ngày tháng tuần năm” các trường, giá trị tương ứng của trường và các ký tự đại diện được thể hiện qua bảng sau:
Trường | Giá trị tương ứng | Ký tự đại diện |
---|---|---|
Phút | 0 – 59 | , – * / |
Giờ | 0 – 23 | , – * / |
Ngày trong tháng | 1 – 31 | , – * ? / L W |
Tháng | 1 – 12 hoặc JAN – DEC | , – * / |
Ngày trong tuần | 1 – 7 hoặc SUN -SAT | , – * ? L # |
Năm | 1970 – 2199 | , – * / |
Ký tự đại diện:
” , ” thể hiện giá trị bổ sung. VD: MON,FRI trong trường Ngày trong tuần thể hiện ngày được chọn trong tuần là thứ 2 và thứ 6
” – ” thể hiện phạm vị được chọn. VD: 1-10 trong trường ngày trong tháng thể hiện các ngày được chọn trong tháng bao gồm từ ngày 1 đến ngày 10
” * ” thể hiện rằng tất cả các ngày trong phạm vị giá trị đều được chọn. Chú ý: Hai trường Ngày trong tháng và Ngày trong tuần không thể đồng thời sử dụng *, nếu một trường sử dụng * thì trường còn lại phải dùng ?
” ? ” đại diện cho trường được chỉ định. VD: khi nhập 7 vào trường Ngày trong tháng và không cần quan tâm là ngày nào trong tuần thì điền ? vào trường Ngày trong tuần.
” L ” đại diện cho ngày cuối cùng trong tuần hoặc tháng
” / ” thể hiện cho gia số được chỉ định. VD: trong trường phút ta nhập 1/10 để thể hiện rằng cứ 10 phút thời gian lại được chỉ định, bắt đầu từ phút đầu tiên của giờ (phút tiếp theo là 11, 21, 31).
” W ” trong trường ngày trong tháng đại diện cho một ngày trong tuần. Trong trường ngày trong tháng 3W thể hiện ngày trong tuần gần nhất với ngày thứ 3 của tháng.
” # ” trong trường ngày trong tuần, chỉ định một trường hợp nhất định của ngày được chỉ định trong tuần trong vòng một tháng.
Chú ý: vì khoảng trắng cũng được coi là ký tự nên biểu thức không được sử dụng quá số khoảng trắng quy định. Múi giờ trong cloudwatch luôn chỉ định là múi giờ GMT nên cần xác định chính xác để phù hợp với múi giờ VN (giờ VN – 7h)
Hạn chế:
Không thể chỉ định trường ngày và tháng trong cùng một biểu thức lập lịch, nếu sử dụng * trong một trường thì trường còn lại phải sử dụng ?
Với chu kỳ trong lập lịch < 1 phút thì biểu thức cron không hỗ trợ.
Ví dụ:
Phút | Giờ | Ngày(trong tháng) | Tháng | Ngày(trong tuần) | Năm | Ý nghĩa |
---|---|---|---|---|---|---|
0 | 10 | * | * | ? | * | Chạy lúc 10h am (múi giờ UTC) mỗi ngày |
15 | 12 | * | * | ? | * | Chạy lúc 12:15 pm (UTC) mỗi ngày |
0 | 18 | ? | * | MON-FRI | * | Chạy lúc 6h pm (UTC) mỗi ngày từ thứ 2 đến thứ 6 |
0 | 8 | 1 | * | ? | * | Chạy lúc 8h am (UTC) mỗi ngày mùng 1 của tháng |
0/15 | * | * | * | ? | * | Chạy mỗi 15 phút một lần |
0/10 | * | ? | * | MON-FRI | * | Chạy mỗi 10 phút một lần mỗi ngày từ thứ 2 đến thứ 6 |
0/5 | 8-17 | ? | * | MON-FRI | * | Chạy mỗi 5 phút một lần trong khoảng thời gian từ 8:00 am → 5:55 pm (UTC) trong khoảng từ thứ 2 đến thứ 6 |
- Thời gian lập lịch chạy sẽ được hiển thị bên dưới để bạn dễ dàng quan sát như sau:
- Rate:
Biểu thức rate bắt đầu tính thời gian khi bạn nhấn create rule và sau đó chạy theo lịch biểu được xác định. Rate có 2 trường bắt buộc là giá trị(value) và đơn vị(phút, giờ, ngày)
Nếu = 1 thì đơn vị phải là số ít (hour), > 1 thì đơn vị phải là số nhiều (hours).
Tổng Kết
Việc áp dụng Lambda và CloudWatch giúp nâng cao hiệu suất và tiết kiệm chi phí hơn rất nhiều.
Chúng tôi đã áp dụng và giảm thiểu được rất nhiều gia công trong việc quản lý server.
Tôi hy vọng bài viết sẽ giúp ích cho các bạn đọc trong những dự án khác nói chung và bigdata nói riêng.