Tiếp tục bài hôm trước về các thuật ngữ cực kì quan trọng cho một backend developer.
Bài hôm nay chúng ta sẽ cùng nhau thảo luận về một số thuật ngữ quan trọng khác.
Availability
Đây là một tính chất trong hệ thống. Ví dụ các bạn hay đi mua các dịch vụ hosting, VPS, ... Thấy người ta hay nói rằng: "Chúng tôi luôn đảm bảo rằng thời uptime của server luôn đạt 99.9%".
Và một thống nếu lượng user tăng, lượng request tăng mà vẫn có thể đáp ứng được nhu cầu của users thì chúng ta gọi đó là một hệ thống high availibility. Các bạn có thể quay lại phần một để xem các pattern triển khai database như replication, sharding. Mục tiêu của các pattern này đều hướng đến high availability.
Quay lại mình có một câu hỏi. Hệ thống 99.9% uptime có được xem là high availability không?
Các bạn tự đánh giá câu trả lời theo bảng bên dưới nha (người ta hay dùng mấy con số 9 bên dưới để nói chuyện với nhau).
Mình đi tiếp tới thuật ngữ tiếp theo thôi.
Consistency - Nhất quán
Consistency là một khái niệm cực kì quan trọng trong một hệ thống lớn. Và đặc biệt là trong các hệ thống distributed database.
Mình sẽ giải thích consistency trong phạm vi distributed database.
Rõ ràng trong database distributed, chúng ta sẽ có nhiều node database. Ví dụ trong replication pattern, khi bạn thực hiện một lệnh ghi dữ liệu ở node 1 (write), thì liệu rằng dữ liệu này nó sẽ sync qua các node khác như thế nào? Rồi có mất dữ liệu không (cá mập cắn cáp chẳng hạn)? Rồi nó sync qua mất thời gian bao lâu? Vân vân và mây mây.
Ví dụ bạn có một hệ thống replication gồm 3 node. Liệu rằng dữ liệu trên 3 node đó có hoàn toàn giống nhau không? Có rủi ro gì bị mất dữ liệu hay không? Để trả lời tất cả những vấn đề này, chúng ta cùng đi tiếp.
Nếu bạn trả lời được câu hỏi này thì chứng tỏ bạn...cũng không phải dạng vừa đâu. Hơi rộng đó nha =)).
Khi làm việc với các thể loại distributed database. Đây là một trong những vấn đề lớn nhất mà các bạn phải giải quyết. Vì nó ảnh hưởng trực tiếp business của chính bạn.
Và đây chính là vấn đề consistency dữ liệu giữa các node database với nhau.
Mình tạm chia consistency có 2 loại thôi ha, và mình sẽ đi giải thích từng loại. Và bạn sẽ thẩm thấu ngay thôi:
- Eventual consistency
- Strong consistency
Thật ra còn week consistency (tính nhất quán yếu) nữa. Trường hợp này thường xuất hiện trong các ứng dụng real-time (thời gian thực) như livestream, video call. Lúc này có bị mất tính hiệu một lúc thì người xem sẽ không thể xem dữ liệu bị mất nữa. Mất rồi thì thôi. Mình không đi sâu vào pattern này, các bạn có thể tự search thêm google nha.
Strong consistency
Trước tiên nhìn hình một chút.
Tí nữa mình sẽ vẽ sequence diagram các bạn sẽ thấy rõ hơn. Mình giải thích sơ một chút.
Khi một ông user A nào đó thực hiện ghi dữ liệu (trên hình là ghi X=100
vào node 1). Và ông A này thấy lệnh ghi dữ liệu thành công (ví dụ response 200 OK
). Thì ngay lập tức có 2 ông B và C đọc dữ liệu X ngay ở node 2 và node 3. Và họ thấy X=100
luôn. Đây chính là strong consistency. Dữ liệu được sync đồng bộ qua các node. Không có chuyện là ông A ghi thành công rồi, và ông C get X ra thì not found.
Bây giờ mình xem chi tiết vào sequence diagram.
Nhìn vào diagram cho cụ thể hơn. X được ghi vào node 1, xong nó sẽ được ghi đồng bộ vào các node 2, node 3. Sau khi complete thì lệnh ghi của client mới được xem là thành công.
Eventual consistency
Strong consistency thì các bạn đã hiểu rồi. Và giờ theo bạn eventual consistency là gì?
Quay lại bài toán ghi X=100
vào node 1 trên nhưng với bối cảnh khác chút.
Trong bối cảnh mới này, X=100
đã được ghi thành công ở node 1. Sau đó được sync ngay qua node 2 và node 3. Và lúc này ông B đọc node 2 thì thấy kết quả 100
. Nhưng ông C đọc node 3 thì not found. Và ông B thấy lạ liền gọi điện chửi ông A, chú lưu dữ liệu chưa sao anh không tìm thấy? Ông A nói, ủa anh em mới lưu xong rồi đó, anh check lại dùm em. Thế là ông B lay hoay refresh lại thì thấy kết quả 100
.
Bây giờ nhìn diagram của ông eventual consistency nha.
Bạn cũng thấy đó, X=100
khi xong ở node 1 là coi như lệnh ghi đã success. Và sau khi lệnh ghi success thì node 1 mới bắt đầu sync dữ liệu qua node 2 và node 3. Và mình hay gọi là một lúc nữa thì data mới consistency. Đơn giản phải không nào.
Qua 2 ví dụ trên. Bạn đã biết thế nào là strong consistency, thế nào là eventual consistency rồi.
Bây giờ mình sẽ hỏi các bạn 2 câu sau =))
Trong ví dụ đầu strong consistency. Nếu có một node thất bại trong quá trình sync data (ví dụ node 3 thất bại đi), thì chuyện gì xảy ra?
Và trong eventual consistency. Cũng tương tự, nếu một node ghi thất bại thì chuyện gì xảy ra?
Bạn hãy ngưng một chút và tự trả lời xem nào. Trước khi xem câu trả lời của mình.
Ok xong rồi đúng không! Trong trường hợp 1, khi một node thất bại thì lệnh ghi của chúng ta sẽ có status cuối cùng là thất bại. Nhưng trong trường hợp 2, khi sync qua một node thất bại, thì lệnh ghi của chúng ta vẫn coi thành công (vì đã response trước đó rồi). Dẫn đến dữ liệu trên node thất bại (ở đây đang là node 3) sẽ bị miss. Dẫn tới data sẽ bị inconsistency giữa các node. Và làm thế nào để giải quyết được bài toán này. Hẹn gặp các bạn ở một bài khác nha.
Trade-off - đánh đổi
Trong thế giới distributed database, mọi thứ không bao giờ là hoàn hảo. Bản thân các bạn là software engineer. Và nhiệm vụ của các bạn là phân tích nghiệp vụ của sản phẩm mình đang phát triển và giải quyết các bài toán trade-off này.
Trong phần này, mình sẽ cùng bạn đi giải quyết bài toán đánh đổi giữa availability và consistency.
Có bạn sẽ thắc mắc! Thế tại sao chúng ta không chọn cả 2 ông availability và consistency luôn? Mà phải đắn đo suy nghĩ để lựa chọn một trong hai?
Cùng quay lại bài toán strong consistency hồi nảy xíu!
Nhìn vào sequence diagram, bạn sẽ thấy, lệnh write để thành công được đòi hỏi tất cả các node phải thành công. Nghĩa là client lúc này phải chờ để write 3 node. Lúc này latency (thời gian response) của request write X sẽ cao hơn rất nhiều. Vậy thì nếu nhiều request hàng loạt ập tới, khả năng các node sẽ tạch cao hơn rất nhiều. Và kết quả dẫn tới low availability.
Chốt lại là. Muốn strong consistency thì phải đánh đổi bởi availability.
Tiếp tục với bài toán eventual consistency. Latency của request write X lúc này rất nhỏ. Vì chỉ cần ghi thành công node 1 là coi như request thành công. Có thể hiểu đơn giản latency lúc nảy giảm tối thiểu gấp 3 lần so với trường hợp strong consistency. Latency nhỏ dẫn tới các node sẽ chịu tải được nhiều hơn (high availability). Nhưng lúc này đánh đổi bởi consistency. Data sẽ được sync qua các node tốn một thời gian nhất định. Cho nên đôi khi client read X sẽ chỉ thấy được data cũ. Và đôi khi không sync được data qua các node dẫn tới tình trạng inconsistency.
Chốt lại là. Muốn high availability thì phải đánh đổi với consistency.
Đây cũng chính CAP theorem huyền thoại mà chúng ta hay nghe thấy.
Vậy thì, đối với từng business cụ thể, chúng ta sẽ phải suy nghĩ và lựa chọn trade-off ở đây.
Mình lấy ví dụ, một trang social hay báo điện tử (như 24h chẳng hạn). Có thể chọn high availability thay vì chọn strong consistency. Những business liên quan tới tiền bạc thì có thể chọn strong consistency. Túm lại là tùy thuộc vào business của từng application cụ thể. Bạn và team bạn sẽ phải planning và lựa chọn.