Container Design Pattern cho hệ thống phân tán: Ambassador [Kỳ 2]
Ở kỳ trước, mình đã giới thiệu về sidecar pattern , là pattern dùng một container gắn vào một container hiện có để củng cố chức năng. Ở kỳ này, mình sẽ giới thiệu về ambassador pattern, nơi mà dùng dùng một ambassador container như một phần trung gian giúp tương tác giữa container ứng dụng và phần còn lại của thế giới internet.
1. Ambassador pattern là gì
Như các single-node pattern khác, ambassador pattern cũng gồm 2 container được liên kết chặt chẽ với nhau như là một cặp container cộng sinh, và chúng cùng được schedule trên cùng một máy.
Dưới đây là sơ đồ mô tả patter này:
Sử dụng ambassador pattern mang lại các lợi ích sau.
- Đầu tiên như các single node pattern khác, ambassador pattern cũng giúp tạo dựng nên những container có tính module, tính tái sử dụng. Sự phân chia vai trò giúp cho các container dễ dãng hơn cho việc build và bảo trì.
- Tương tự như vậy, các ambassador container có thể được tại sử dụng cho nhiều trường hợp ở các ứng dụng khác nhau. Sự tái sử dụng này giúp tăng tốc quá trình phát triển ứng dụng bởi vì các logic code của container có thể được tái sử dụng ở nhiều nơi. Ngoài ra, triển khai pattern này giúp nhất quán và chất lượng cao hơn bởi ambassador container được build một lần và sử dụng cho nhiều trường hợp, hoàn cảnh khác nhau.
Ambassador pattern chỉ đơn giản có vậy thôi. Dưới đây mình sẽ trình bày các use-case phổ biến của pattern này để mọi người có cái nhìn tổng quan hơn về việc sử dụng nó trong thực tế.
2. Sử dụng Ambassador để sharding một service
Nhiều khi, dữ liệu chúng ta muốn lưu tại một lớp storage lại quá lớn để một máy đơn lẻ có thể chứa được. Vào trường hợp đó, ta sẽ nghĩ đến nên sharding cái lớp storage này. Sharding sẽ giúp phân chia một lớp thành nhiều mảnh rời rạc, mỗi mảnh được lưu tại một máy riêng lẽ.
Lưu ý rằng mình sẽ chỉ tập trung vào mô tả cách sử dụng pattern này để chuyển đổi một service hiện có sang một sharded service khác cũng hiện có ở đâu đó chẳng hạn. Mình sẽ không mô tả cách để triển khai một sharded service, phần đó sẽ được miêu tả chi tiết ở một kỳ design pattern sau.
Một dạng tổng quát của một sharded service như sau:
Khi deploy một sharded service, một câu hỏi sẽ nảy ra đó là làm sao để tích hợp nó với frontend hoặc middleware code. Rõ ràng chúng cần có logic để định tuyến một request cụ thể đến một shard cụ thể, tuy nhiên thường thì khó để chuyển đổi, trang bị một sharded client đến những dòng code hiện có vì những dòng code này ban đầu vẫn chỉ được lập trình để kết nối đến chỉ một storage backend đơn lẻ. Ngoài ra, sharded service khiến khó có thể chia sẻ các config giữa các môi trường phát triển (ví dụ như ở môi trường develop thường chỉ có 1 hoặc 2 shard storage, còn ở môi trường product lại có rất nhiều shard storage).
Một hướng tiếp cận đó là build tất cả các logic sharding vào một sharded service. Ở hướng tiếp cận này, sharded service cũng có một stateless load balancer sẽ chuyển hướng trafic đến shard thích hợp. Thực thế thì, load balancer này chính là một ambassador phân tán (distributed ambassador as a service). Điều này khiến một client-side ambassador không cần thiết phải mở rộng phần deployment phức tạp cho một sharded service.
Còn một cách khác nữa là tích hợp một single-node ambassador trên client side để chuyển hướng traffic đến shard thích hợp. Tuy nhiên điều này sẽ khiến deploy phần client sẽ phức tạp một chút nhưng lại đơn giản hóa phần deploy sharded service. Nói chung tùy vào ứng dụng cụ thể mà chúng ta quyết định nên sử dụng phương án vào.
3. Sử dụng Ambassador cho Service Brokering
Khi ta deploy một portable application khắp các môi trường ( public cloud, physical datacenter, private cloud, ...), một trong những thách thức đầu tiên đó là service discovery và các config. Để hiểu điều này là gì, tưởng tượng một frontend mà dựa trên một MySQL để lưu trữ data. Ở public cloud, MySQL service có thể được cung cấp dưới dạng software-as-a-service (SaaS), trong khi đó ở private cloud thì cần thiết phải tự động schedule để tạo một VM mới hoặc một container chạy MySQL.
Hậu quả là, việc build một portable application đòi hỏi ứng dụng đó phải biết làm thế nào để điều tra, truy xuất thông tin của môi trường và tìm đúng MySQL service để kết nối đến. Quá trình này gọi là service discovery, và hệ thống thực hiện việc discovery và kết nối thì gọi chung là service broker. Như ở các use-case trên, ambassador pattern giúp phân chia các logic của container ứng dụng từ logic của service broker ambassador. Ứng dụng đơn giản luôn luôn kết nối đến một đối tượng của một service (ví dụ: MySQL) chạy ở localhost. Trách nhiệm của service broker ambassador là điều tra, truy xuất thông tin môi trường và môi giới, trung gian cho các kết nối thích hợp.
Quá trình này được mô tả trong hình sau: