👋 Hi! Bạn cần tư vấn gì về dịch vụ AWS?

Khi một hệ thống mã hóa tạo ra hàng triệu lệnh gọi API trùng lặp mỗi giờ, chi phí sẽ tăng vọt và hiệu năng suy giảm. Đây chính là thách thức mà NICE Actimize, nhà cung cấp giải pháp chống tội phạm tài chính, đã đối mặt khi vận hành nền tảng quy mô toàn cầu trên Amazon Web Services (AWS). Bằng cách tối ưu hóa chiến lược cache (bộ đệm) khóa mã hóa, họ đã giảm 77% chi phí AWS Key Management Service (AWS KMS) mà vẫn đảm bảo an ninh nghiêm ngặt và phân tách mã hóa cho từng khách hàng (tenant).

Bài viết này phân tích vấn đề cache stampede (hiện tượng các luồng cùng lúc truy cập tài nguyên) phát sinh trong các kiến trúc đa luồng, đa tenant sử dụng mã hóa bao thư (envelope encryption). Đồng thời, bài viết cũng trình bày hai giải pháp: một theo khuyến nghị của AWS và một giải pháp tùy chỉnh mà NICE Actimize đã xây dựng, mang lại giá trị tham khảo cho các doanh nghiệp SaaS và hệ thống thông lượng cao.

Tại sao mã hóa cho từng tenant lại quan trọng?

Các hệ thống dịch vụ tài chính phải tuân thủ các quy định nghiêm ngặt, yêu cầu dữ liệu phải được mã hóa cả khi lưu trữ và khi truyền tải. Đối với các nhà cung cấp SaaS đa tenant, yêu cầu này còn cao hơn: dữ liệu của mỗi tenant phải được mã hóa bằng các khóa riêng biệt để đảm bảo cách ly hoàn toàn về mặt mật mã. Nếu khóa của một tenant bị xâm phạm, dữ liệu của các tenant khác vẫn an toàn.

Trong một môi trường SaaS doanh nghiệp xây dựng trên kiến trúc hướng sự kiện, sử dụng các dịch vụ như Amazon MSK và Amazon SQS, hàng triệu tin nhắn được trao đổi liên tục. Mỗi tin nhắn phải được mã hóa bằng khóa dành riêng cho tenant tương ứng. Ở quy mô lớn, điều này tạo ra một khối lượng khổng lồ các hoạt động mã hóa và giải mã.

Để xử lý hiệu quả, phương pháp tiêu chuẩn là envelope encryption: một mô hình hai lớp nơi khóa từ AWS KMS được dùng để mã hóa các khóa dữ liệu (data key) ngắn hạn, và các data key này sẽ mã hóa dữ liệu thực tế. Điều này giúp ứng dụng không cần gọi AWS KMS cho mọi thao tác, giảm độ trễ và chi phí.

“Cache Stampede”: Khi chi phí API tăng vọt

Envelope encryption làm giảm số lượng lệnh gọi đến AWS KMS, nhưng không loại bỏ hoàn toàn. Mỗi thao tác mã hóa vẫn cần một data key, và mỗi thao tác giải mã phải gọi API Decrypt của KMS. Trong các hệ thống thông lượng cao, các lệnh gọi này cộng lại rất nhanh.

AWS Encryption SDK cung cấp một giải pháp tích hợp là CachingCryptoMaterialsManager để cache các data key cục bộ, cho phép tái sử dụng chúng mà không cần gọi AWS KMS mỗi lần. Tuy nhiên, khi hệ thống mở rộng đến hàng trăm luồng xử lý song song, một vấn đề nghiêm trọng xuất hiện: cache stampede, hay còn gọi là thundering herd.

Hiện tượng này xảy ra khi một data key trong cache hết hạn. Nhiều luồng xử lý cho cùng một tenant sẽ đồng thời phát hiện cache hết hạn và cùng lúc gọi API GenerateDataKey tới AWS KMS. Thay vì một luồng tạo khóa mới và các luồng khác chờ đợi, N luồng sẽ tạo ra N data key riêng biệt. Điều này dẫn đến một loạt hệ quả:

  • Bùng nổ data key khi mã hóa: Số lượng data key tăng đột biến một cách không cần thiết.
  • Lệnh giải mã dư thừa: Các data key khác nhau này lan truyền xuống hạ nguồn. Khi các luồng consumer đọc dữ liệu, chúng gặp phải các khóa chưa từng được cache và lại đồng loạt gọi API Decrypt đến KMS, gây ra các lệnh gọi trùng lặp.

Hiệu ứngทบต้น này làm tăng chi phí và giảm hiệu quả của cache. Trong trường hợp của NICE Actimize, gần một phần ba số bản ghi trong DynamoDB được mã hóa bằng các data key khác nhau, tạo ra hàng triệu lệnh gọi KMS dư thừa mỗi giờ.

Sơ đồ minh họa hiện tượng cache stampede trong môi trường đa luồng

Hai hướng giải quyết vấn đề

AWS và NICE Actimize đã đánh giá hai phương pháp để giải quyết vấn đề cache stampede, mỗi phương pháp phù hợp với các yêu cầu kiến trúc và quy định khác nhau.

Lựa chọn A: Mẫu hình Hierarchical Keyring (khuyến nghị từ AWS)

AWS đề xuất giải pháp hierarchical keyring (chuỗi khóa phân cấp), bổ sung một lớp khóa trung gian để giảm đáng kể tần suất xảy ra cache stampede. Trong kiến trúc này, các “branch key” (khóa nhánh) được lưu trữ trong một bảng DynamoDB, hoạt động như một lớp cache chia sẻ, điều phối giữa các máy chủ trong hệ thống phân tán.

Điểm cốt lõi là cache này có khả năng nhận biết các luồng (thread-aware). Khi cache sắp hết hạn, chỉ một luồng duy nhất được chỉ định để làm mới cache từ branch key, trong khi các luồng khác tiếp tục phục vụ yêu cầu bằng dữ liệu cache cũ nhưng vẫn hợp lệ. Bảng DynamoDB đóng vai trò là điểm điều phối trung tâm, ngăn chặn các lệnh gọi trùng lặp đến AWS KMS.

Giải pháp này tích hợp sẵn với AWS Encryption SDK và chỉ yêu cầu thay đổi mã nguồn ở mức tối thiểu. Đối với các kiến trúc hướng sự kiện, phương pháp này có thể giảm khối lượng lệnh gọi KMS xuống nhiều bậc độ lớn.

Kiến trúc hierarchical keyring sử dụng DynamoDB và AWS KMS

Lựa chọn B: Caching tùy chỉnh tại lớp API (giải pháp của NICE Actimize)

Một cách tiếp cận khác là loại bỏ cache stampede ngay tại nguồn bằng cách cache trực tiếp các phản hồi từ API của KMS. Đây là con đường mà NICE Actimize đã chọn.

Họ đã tạo ra một CachedKmsClient – một trình trang trí (decorator) bao bọc KmsClient tiêu chuẩn của AWS SDK. Lớp này sử dụng hai bộ cache LoadingCache từ thư viện Caffeine để chặn các lệnh gọi giữa ứng dụng và AWS KMS.

Cả hai cache đều được cấu hình với refreshAfterWrite, đảm bảo rằng khi một mục cache hết hạn, chỉ duy nhất một luồng thực thi lệnh gọi API tới KMS, trong khi tất cả các luồng đồng thời khác sẽ chờ kết quả duy nhất đó. Đặc tính nguyên tử, “single-flight” này đã loại bỏ hoàn toàn hiện tượng stampede.

Tại sao NICE Actimize chọn giải pháp tùy chỉnh?

NICE Actimize đã chọn phương pháp caching tùy chỉnh (Lựa chọn B) vì một lý do thực tế: tránh đưa thêm một phụ thuộc hạ tầng mới (DynamoDB) vào luồng xử lý mã hóa trọng yếu. Việc thêm một bảng DynamoDB sẽ kéo theo trách nhiệm vận hành bổ sung: cấp phép, giám sát, sao lưu, kiểm soát truy cập và đảm bảo tính sẵn sàng cao.

Trong môi trường dịch vụ tài chính được quản lý chặt chẽ, mỗi thành phần có trạng thái (stateful) mới trong chuỗi bảo mật đều đòi hỏi kế hoạch phục hồi, phân tích lỗi và đánh giá tuân thủ riêng. Ngược lại, cache Caffeine được sử dụng trong Lựa chọn B là một thư viện trong tiến trình (in-process), không trạng thái, không yêu cầu gọi mạng, không cần cấp phép và không có chi phí vận hành. Nó là một phụ thuộc nhẹ hơn nhiều so với một tài nguyên đám mây được quản lý trong luồng xử lý quan trọng.

Kết quả kinh doanh ấn tượng

Bằng cách triển khai chính sách xoay vòng khóa với phương pháp caching được tối ưu hóa, NICE Actimize đã đạt được những kết quả sau:

  • Giảm 77% chi phí AWS KMS: Loại bỏ hàng triệu lệnh gọi API dư thừa đã chuyển thành tiết kiệm chi phí đáng kể.
  • Duy trì phân tách nghiêm ngặt cho từng tenant: Việc cô lập mã hóa cho từng tenant vẫn được giữ nguyên vẹn, không ảnh hưởng đến lập trường bảo mật.
  • Cải thiện hiệu năng hệ thống: Loại bỏ các lệnh gọi KMS trùng lặp giúp giảm độ trễ và giải phóng tài nguyên hệ thống cho các xử lý cốt lõi.
  • Đơn giản hóa vận hành: Một lớp caching phối hợp đã thay thế cho việc caching phân mảnh trên từng luồng, giảm độ phức tạp trong vận hành.

Kết luận

Vấn đề cache stampede có thể gây ra chi phí lớn trong các hệ thống mã hóa đa tenant. Mẫu hình hierarchical keyring do AWS khuyến nghị là một giải pháp sẵn sàng cho sản xuất. Tuy nhiên, đối với các môi trường được quản lý chặt chẽ yêu cầu kiểm soát bổ sung, một phương pháp caching tùy chỉnh như của NICE Actimize có thể mang lại kết quả tương tự với ít phụ thuộc hạ tầng hơn. Các doanh nghiệp vận hành nền tảng SaaS hoặc hệ thống thông lượng cao nên xem xét các mẫu hình này để tối ưu hóa chi phí và hiệu năng mã hóa.