Hành trình xây dựng Kiến trúc Cloud-Native: Bài #2 – Tối đa hoá thông lượng hệ thống

Trong bài trước chúng ta đã tìm hiểu về ứng dụng tăng trưởng tốc độ cao cùng các thử thách về mặt kỹ thuật. Hệ thống chúng ta sẽ thảo luận trong chuỗi bài này là một hệ thống thương mại điện tử chạy với kiến trúc phần mềm monolith trên Amazon EC2. Ứng dụng này kết nối đến CSDL là Amazon RDS PostgreSQL.

Công ty gặp phải thử thách về sự tăng trưởng lưu lượng người theo cấp số mũ (10 lần) trong vài ngày. Trong thời gian này, đội ngũ kỹ thuật nhận thấy sự giảm sút về hiệu năng hệ thống vào giờ cao điểm. Ở bài này chúng ta sẽ bàn về việc cải thiện hiệu năng thông qua tối đa thông lượng hệ thống ở tầng ứng dụng và CSDL.

Tối đa thông lượng hệ thống (System throughput)

Trong phần này chúng ta sẽ bàn về làm sao để tối đa thông lượng hệ thống và có được hiệu năng một cách bền bỉ ổn định.

Cấu hình synchronized transaction timeout (thời gian hết hạn phiên giao dịch đồng bộ)

Một phiên giao dịch hết hạn giữa ứng dụng, CSDL và mạng bởi các lý do sau đây:

Chúng ta cấu hình tăng thời gian timeout để đảm bảo phiên được hoàn thành từ backend đến front-end. Ví dụ: chúng ta tăng thời gian timeout của CSDL từ 03 giây lên đến 10 giây để đáp ứng các câu truy vấn phức tạp.

Sử dụng Connection Pooling 

Chúng ta nhận dạng các kết nối rảnh (idle) mà tiêu tốn tài nguyên hệ thống như CPU và bộ nhớ thông qua bài viết Resources Consumed by Idle PostgreSQL Connect Blog Post. Bài viết này giải thích việc làm sao để có nhiều kết nối mà không cần thiết tăng thông lượng và có thể tạo ra nhiều kết nối idle. Nó có ảnh hưởng ngược lại với hiệu năng (được diễn giải trong bài viết Performance Impact of Idle PostgreSQL Connection Blog Post)

Giải pháp là chúng ta triển khai Connection Pooling thông qua Amazon RDS Proxy để nâng cao hiệu năng hệ thống và giảm thiểu việc lãng phí các tài nguyên không cần thiết. Tính năng này giúp ứng dụng tái sử dụng các kết nối đến CSDL đảm bảo tính mở rộng và ổn định.

Sử dụng Read Replicas 

Để đáp ứng các nhu cầu về đọc trong cụm CSDL, chúng ta triển khai nhiều read-replicas để mở rộng khả năng về đọc. Những Read Replicas này xử lý các xử lý một lần để lấy dữ liệu. Kiểu thiết này này còn được gọi là Chia trách nhiệm truy vấn (Command Query Responsibility Segregation)

Chúng ta cập nhật mã nguồn ứng dụng để xác định các yêu cầu đọc/ghi dựa trên API Call. Dựa vào nhu cầu truy xuất dữ liệu, ứng dụng sẽ sử dụng các endpoints khác nhau để chạy các câu truy vấn. Với kiến trúc này chúng ta có thể giảm thiết lưu lượng đọc đến CSDL chính thông qua việc xử lý ở các Read Replicas, giúp tăng thông lượng ghi vào CSDL chính.

Sử dụng bộ đệm (Caching)

Chúng ta sử dụng bộ đệm để nâng cao hiệu năng và giảm thời gian chờ từ phía người dùng. Mặc dù sử dụng Read Replicas chúng ta có thể phân tán lưu lượng đọc và ghi đến những máy chủ CSDL khác nhau nhưng các câu truy vấn vẫn chạy trên các CSDL này khiến tiêu tốn tài nguyên. Chúng ta cần giải pháp bộ nhớ đệm (in-memory caching) cho phép độ trễ tính theo submillisecond. Bạn có thể tham khảo thêm tài liệu Hiệu năng tại quy mô lớn với Amazon ElastiCache để có thể lựa chọn giải pháp bộ đệm cho những tình huống khác nhau.

Chúng ta đã triển khai Amazon ElastiCache for Redis theo kiểu mẫu thiết kế lazy-loading được đề cập trong tài liệu Chiến lược bộ đệm CSDL sử dụng Redis. Bộ đệm không chỉ nâng cao quy mô và hiệu năng mà còn giúp tiết kiệm chi phí sử dụng CSDL.

Làm sạch và lưu trữ dữ liệu (Purge & Archiving) 

Bảng Orders là một trong những bảng có tần suất đọc / ghi lớn nhất trong CSDL. Tuy nhiên, chúng ta không có nhu cầu cho việc lưu trữ các thông tin lịch sử đối với các đơn hàng đã hoàn thành. Vì thế, chúng tôi đã làm việc với đội ngũ nội bộ để định nghĩa chính sách lưu trữ dữ liệu. Chúng tôi đã tạo các bảng được phân vùng theo ngày, điều này cho phép chúng tôi phân tích những phân vùng với những mẫu tin (records) đã được làm sạch hay lưu trữ dựa theo chính sách lưu trữ mà công ty đề ra.

Kích thước của bảng giảm 60% dựa vào kỹ thuật này. Chúng tôi cũng tạo các công việc tự động làm sạch các phân vùng cũ và triển khai sao lưu dữ liệu. Thêm nữa, chúng tôi đã thích ứng chuyển đổi các dữ liệu cũ đến Aurora Serverless Postgres để giảm thiểu các câu truy vấn không thường xuyên từ CSDL chính giúp tiết kiệm chi phí. CSDL này hỗ trợ người dùng muốn xem những đơn hàng cũ không thường xuyên (Ghi chú: Xem thêm Aurora Serverless V2 in Preview)

Tối ưu hoá truy vấn 

Chúng tôi đã sử dụng Amazon RDS Performance để tìm các câu truy vấn SQL gây thắt cổ chai trong hệ thống. Chúng tôi sử dụng các chỉ số như “read time per call” (thời gian đọc mỗi lần gọi) và “write time per call” (thời gian viết mỗi lần gọi) để biết được các câu truy vấn mất nhiều thời gian đọc và ghi. Khi phân tích sâu hơn, chúng tôi phát hiện một số câu truy vấn sử dụng bởi quy trình OLAP (Online Analytics Process). Trước khi phân tích xa hơn, chúng tôi đã chuyển những câu truy vấn SELECT đến các Read Replicas riêng biệt để giảm thiểu tải trên CSDL chính.

Sử dụng Database Sharding 

Bởi vì chúng ta đã sử dụng một trong những máy chủ lớn nhất cho CSDL, nên ta cần tìm cách mở rộng CSDL theo chiều ngang.  “Sharding” cho phép chúng ta có nhiều điểm ghi (Writer Node). Có một vài cơ chế Sharding CSDL với các ưu nhược điểm tương ứng, bạn có thể tham khảo thêm qua bài viết: Sharding with Amazon RDS 

Trong trường hợp kiến trúc của chúng ta, bảng đơn hàng Order với lượng dữ liệu lớn cần ứng dụng kỹ thuật Sharding. Ta sử dụng “customer_id” như khoá phân vùng (partition key) và phân chia dữ liệu vào các shard khác nhau. Chúng ta cũng cần phát triển một proxy để thực hiện việc ánh xạ giữa khách hàng và shard đã được phân chia.

Hình 1 – Kiến trúc hiện tại với việc nâng cao tính đàn hồi

Kết luận 

Trong bài viết này, chúng ta đã bàn về các kiểu mẫu thiết kế mà bạn có thể nhận dạng những thử thách mở rộng hệ thống trong lúc siêu tăng trưởng. Bài viết trước đã nói về tăng trưởng nhanh, và nhưng thử thách về mặt kỹ thuật mà công ty gặp phải. Những kiểu mẫu thiết kế này không chỉ giúp tối đa hoá thông lượng hệ thống mà còn chuẩn bị ứng dụng có thể thay đổi cải tiến từng chút một để xây dựng kiến trúc sẵn sàng mở rộng và tin cậy. Trong bài tiếp theo, chúng ta sẽ bàn về Nâng cao khả năng giám sát tiêu chuẩn và khả năng thích ứng của hệ thống, chúng tôi sẽ cung cấp nhiều kiểu mẫu thiết kế hơn để giúp bạn trong hành trình tương thích với kiến trúc cloud-native.


Bài được dịch từ bài viết trên AWS Blogs, bạn có thể xem bài viết gốc tại đây.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: