Statefull'less app'k8s
Để hiểu sự khác biệt giữa Stateful và Stateless trong ngữ cảnh ứng dụng và trường hợp sử dụng bộ nhớ đệm (cache), chúng ta cần phân tích cách hai mô hình này xử lý trạng thái (state) và tác động của chúng đến kiến trúc ứng dụng.
NNgữ cảnh app¶
1. Stateful (Ứng dụng có trạng thái)¶
Ứng dụng Stateful lưu giữ trạng thái người dùng hoặc thông tin phiên làm việc (session) trực tiếp trên máy chủ ứng dụng. Điều này có nghĩa là trạng thái của người dùng phụ thuộc vào máy chủ mà họ đã kết nối.
Cách hoạt động:¶
- Khi người dùng gửi yêu cầu đến một máy chủ, máy chủ đó lưu trạng thái phiên làm việc hoặc dữ liệu liên quan của người dùng.
- Các yêu cầu tiếp theo từ cùng người dùng phải được gửi đến đúng máy chủ để trạng thái của họ được duy trì.
Ví dụ cụ thể:¶
- Ứng dụng thương mại điện tử Stateful:
- Khi bạn thêm sản phẩm vào giỏ hàng, trạng thái giỏ hàng của bạn được lưu trực tiếp trên một máy chủ cụ thể (server A).
-
Nếu yêu cầu tiếp theo của bạn (như thanh toán) được chuyển đến một máy chủ khác (server B), trạng thái giỏ hàng không tồn tại ở server B, dẫn đến lỗi hoặc mất dữ liệu.
-
Ứng dụng web cũ với session trên máy chủ:
- Khi người dùng đăng nhập, trạng thái "đã đăng nhập" được lưu trong bộ nhớ máy chủ.
- Yêu cầu tiếp theo phải luôn quay lại đúng máy chủ đó để xác thực người dùng.
Hạn chế của Stateful:¶
- Không dễ mở rộng (Scaling khó khăn):
- Vì trạng thái gắn liền với từng máy chủ, việc mở rộng hệ thống đòi hỏi quản lý phức tạp, như sử dụng các kỹ thuật cân bằng tải (load balancing) dựa trên "sticky sessions" (duy trì kết nối tới cùng một máy chủ).
- Phụ thuộc máy chủ:
- Nếu một máy chủ bị lỗi, trạng thái của người dùng trên máy chủ đó có thể bị mất.
- Khó quản lý khi số lượng người dùng lớn:
- Với nhiều người dùng đồng thời, lưu trữ trạng thái trên máy chủ trở thành gánh nặng lớn về bộ nhớ.
2. Stateless (Ứng dụng không trạng thái)¶
Ứng dụng Stateless không lưu trạng thái trên máy chủ. Thay vào đó, tất cả trạng thái liên quan đến người dùng hoặc phiên làm việc được lưu trữ ở nơi khác (ví dụ: token trong trình duyệt, cơ sở dữ liệu, hoặc bộ nhớ đệm như Redis).
Cách hoạt động:¶
- Máy chủ không lưu giữ trạng thái. Mỗi yêu cầu từ người dùng là độc lập và mang theo thông tin trạng thái (nếu cần) dưới dạng dữ liệu được lưu trữ bên ngoài.
- Điều này giúp các yêu cầu của người dùng có thể được xử lý bởi bất kỳ máy chủ nào trong hệ thống.
Ví dụ cụ thể:¶
- Ứng dụng thương mại điện tử Stateless:
- Khi bạn thêm sản phẩm vào giỏ hàng, trạng thái giỏ hàng được lưu trong Redis.
-
Bất kỳ yêu cầu nào từ bạn (thanh toán, xem giỏ hàng) đều có thể được xử lý bởi bất kỳ máy chủ nào, vì tất cả máy chủ đều truy cập Redis để lấy thông tin giỏ hàng.
-
Ứng dụng web hiện đại với JWT (JSON Web Token):
- Khi người dùng đăng nhập, một JWT chứa thông tin xác thực được gửi đến trình duyệt người dùng.
- Yêu cầu tiếp theo từ người dùng sẽ gửi kèm JWT này để xác thực, thay vì máy chủ phải lưu trạng thái "đã đăng nhập".
Ưu điểm của Stateless:¶
- Dễ mở rộng (Scalable):
- Bất kỳ máy chủ nào cũng có thể xử lý yêu cầu, vì trạng thái không gắn liền với từng máy chủ.
- Tăng độ tin cậy:
- Nếu một máy chủ bị lỗi, yêu cầu vẫn có thể được xử lý bởi các máy chủ khác mà không ảnh hưởng đến trạng thái người dùng.
- Dễ quản lý:
- Trạng thái được lưu ở nơi tập trung (Redis, database), giảm gánh nặng trên máy chủ.
So sánh Stateful vs Stateless trong trường hợp ứng dụng sử dụng bộ nhớ đệm¶
Tiêu chí | Stateful | Stateless |
---|---|---|
Lưu trạng thái | Trên máy chủ ứng dụng | Bên ngoài máy chủ (Redis, database, JWT, v.v.) |
Cách truy cập bộ nhớ đệm | Không cần thiết, trạng thái nằm trên từng máy chủ | Trạng thái lưu trên Redis (hoặc nơi khác) |
Tính độc lập của yêu cầu | Yêu cầu phụ thuộc vào máy chủ cụ thể | Yêu cầu có thể được xử lý bởi bất kỳ máy chủ nào |
Quản lý trạng thái người dùng | Lưu session trực tiếp trên máy chủ | Lưu session trên Redis hoặc trong token |
Khả năng mở rộng | Khó mở rộng do phụ thuộc từng máy chủ | Dễ mở rộng nhờ tính độc lập giữa máy chủ |
Khả năng chịu lỗi | Phụ thuộc vào độ ổn định của máy chủ cụ thể | Không bị ảnh hưởng bởi sự cố của một máy chủ |
Kết luận:¶
- Stateful:
- Phù hợp với ứng dụng nhỏ, nơi số lượng người dùng ít và không yêu cầu mở rộng nhiều.
-
Dễ gặp vấn đề khi mở rộng hoặc khi máy chủ gặp sự cố.
-
Stateless:
- Phù hợp với ứng dụng lớn, cần mở rộng linh hoạt và đảm bảo độ tin cậy cao.
- Sử dụng bộ nhớ đệm (Redis, Memcached) để lưu trạng thái hoặc tăng tốc độ.
Ngữ cảnh k8s¶
Khái niệm Stateful và Stateless là chung trong ngành công nghệ phần mềm và không chỉ áp dụng cho ứng dụng thông thường mà còn phù hợp với các hệ thống khác như Kubernetes (K8s). Tuy nhiên, trong bối cảnh của Kubernetes, những khái niệm này được hiểu và áp dụng với một số đặc điểm riêng liên quan đến cách K8s quản lý trạng thái ứng dụng và cơ sở hạ tầng.
Dưới đây là sự so sánh và một số khác biệt chính khi nói về Stateful và Stateless trong Kubernetes:
1. Khái niệm Stateful và Stateless trong K8s¶
Stateless trong K8s¶
- Đặc điểm chung:
- Stateless Pods không lưu trạng thái cục bộ và mỗi Pod có thể bị xóa, thay thế hoặc khởi động lại mà không gây ảnh hưởng lớn.
- Dữ liệu cần thiết cho ứng dụng thường được lưu trữ ngoài Pods, ví dụ như trong các dịch vụ như Redis, S3, hoặc các cơ sở dữ liệu khác.
-
Stateless Pods thường được quản lý bởi Deployments, giúp dễ dàng mở rộng (scaling) và cân bằng tải (load balancing).
-
Ví dụ:
- Một ứng dụng web chỉ xử lý yêu cầu HTTP và không cần lưu trữ trạng thái lâu dài của người dùng trên Pods.
- Các dịch vụ frontend, API gateway, hoặc dịch vụ xử lý giao dịch ngắn hạn.
Stateful trong K8s¶
- Đặc điểm chung:
- Stateful Pods yêu cầu lưu trữ trạng thái dài hạn và cần giữ được thông tin liên quan đến trạng thái giữa các phiên làm việc.
- Kubernetes hỗ trợ Stateful qua các StatefulSets, giúp duy trì danh tính (identity) và dữ liệu gắn liền với từng Pod cụ thể.
-
StatefulSets thường được kết hợp với Persistent Volume Claims (PVCs) để đảm bảo mỗi Pod có không gian lưu trữ riêng.
-
Ví dụ:
- Các ứng dụng cơ sở dữ liệu (MySQL, PostgreSQL).
- Các dịch vụ phân tán như Kafka, Cassandra, hoặc ứng dụng cần duy trì phiên người dùng lâu dài.
2. Sự khác biệt chính giữa Stateful và Stateless trong Kubernetes¶
Tiêu chí | Stateless | Stateful |
---|---|---|
Lưu trạng thái | Không lưu trạng thái lâu dài trong Pods. | Lưu trạng thái trong Pods hoặc trên các PVCs được liên kết. |
Quản lý Pods | Sử dụng Deployments, các Pods có thể thay thế tự do. | Sử dụng StatefulSets, mỗi Pod có danh tính cố định. |
Mở rộng (Scaling) | Dễ dàng mở rộng bằng cách tạo thêm nhiều Pods giống nhau. | Khó mở rộng hơn vì cần giữ trạng thái riêng cho từng Pod. |
Cách xử lý khi Pod bị xóa | Dữ liệu không bị ảnh hưởng do không phụ thuộc vào Pod. | Dữ liệu phải được duy trì hoặc khôi phục từ PVCs. |
Ứng dụng điển hình | Frontend, API, dịch vụ xử lý tạm thời. | Cơ sở dữ liệu, dịch vụ phân tán yêu cầu trạng thái ổn định. |
3. Một số điểm riêng biệt của Stateful và Stateless trong K8s¶
Stateful trong Kubernetes:¶
- StatefulSets:
- Được thiết kế để triển khai và quản lý các ứng dụng yêu cầu lưu trữ trạng thái lâu dài.
-
Pods trong StatefulSets có danh tính duy nhất (ví dụ:
web-0
,web-1
,web-2
), thứ tự khởi tạo và tắt máy cũng được duy trì. -
Persistent Volume (PV) và Persistent Volume Claims (PVC):
- Stateful Pods thường sử dụng PVC để lưu dữ liệu dài hạn.
-
Mỗi Pod có một PVC riêng, đảm bảo không có xung đột dữ liệu giữa các Pod.
-
Cân bằng tải (Load Balancing):
- Pods Stateful thường không được load balancer phân phối đồng đều như Pods Stateless.
- Thay vào đó, mỗi Pod có thể được định danh qua hostname hoặc IP cố định.
Stateless trong Kubernetes:¶
- Deployments:
- Stateless Pods được triển khai và quản lý bằng Deployments.
-
K8s tự động xử lý việc tạo, thay thế và cân bằng tải giữa các Pods.
-
Scaling dễ dàng:
-
Vì không phụ thuộc trạng thái, các Pods Stateless có thể được scale up hoặc scale down mà không cần quan tâm đến dữ liệu hay thứ tự Pods.
-
Khôi phục nhanh:
- Stateless Pods có thể khởi động lại nhanh chóng và không yêu cầu dữ liệu lịch sử để tiếp tục hoạt động.
4. Khi nào sử dụng Stateful hoặc Stateless trong Kubernetes?¶
Sử dụng Stateless:¶
- Ứng dụng không cần lưu trạng thái lâu dài hoặc trạng thái được lưu trữ bên ngoài (Redis, database).
- Dịch vụ frontend, API gateway, ứng dụng xử lý tạm thời hoặc chỉ phục vụ HTTP request.
Sử dụng Stateful:¶
- Khi ứng dụng cần lưu trữ dữ liệu lâu dài hoặc duy trì trạng thái cụ thể trên mỗi phiên làm việc.
- Các ứng dụng cơ sở dữ liệu (MySQL, Cassandra), dịch vụ message queue (Kafka), hoặc dịch vụ cần duy trì thứ tự xử lý.
Kết luận¶
Khái niệm Stateful và Stateless là chung, nhưng cách áp dụng chúng có sự khác biệt rõ ràng trong Kubernetes.
- Với Kubernetes, Stateless chủ yếu được triển khai qua Deployments để dễ mở rộng và cân bằng tải.
- Trong khi đó, StatefulSets và Persistent Volumes là nền tảng cho các ứng dụng Stateful cần lưu trữ trạng thái ổn định.