Nói về sự nhất quán dữ liệu giữa cache và database (1)

Nội dung bài viết

Video học lập trình mỗi ngày

Đầu tiên tôi muốn có một số điều muốn nhắn gửi đến cho những nhà phát triển (DEV) mà đang theo dõi page Tips Javascript, việc chúng ta sử dụng kiến trúc cache-database đang là muỗi so với mô hình thật của nó. Tôi đã có nhiều bài viết về sử dụng cache trong nodejs, nhưng từng đó là chưa đủ để giải thích về kiến trúc của một sàn thương mại điện tử lớn đang đối mặt hằng ngày. Và bài viết này tôi sẽ đi sâu hơn và mong rằng những bạn muốn bước chân vào vị trí back-end của dự án nhỏ hay lớn cũng nên một lần đọc qua. Bởi vì nó liên quan đến một hệ thống nhanh hay chậm, chết hay sống...

Bài viết thuộc series - Con đường trở thành kiến trúc sư

Vì sao nên có thời gian hết hạn cho cache?

Nếu bạn nào đã đọc 2 bài viết trước về sự sụp đổ của cache thì cũng đã hiểu nếu chúng ta đặt hết hạn cho cache một cách cẩu thả thì bạn cũng đừng mong bạn có cơ hội làm việc tại đó nữa. Tương tự có một số bạn sẽ hỏi rằng:

Tại sao lại đặt thời gian hết hạn cho cache, set thời gian hết hạn của bộ nhớ cache có thật sự cần thiết hay không?

Tôi sẽ trả lời là . Và nó rất cần thiết, vậy nó cần thiết như thế nào, xin mời đọc tiếp.

Trước hết nếu như không có thời gian Redis Cache expiration thì xem như một cache sẽ sống mãi ngoại trừ chúng ta phải xoá nó đi. Vì sao? Vì nếu một mục hay một bài viết lâu lâu mới có truy vấn tới thì chúng ta để cache làm gì cho lãng phí bộ nhớ. Chúng ta thật sự hiệu quả là khi có tỷ lệ truy cập của nó càng cao thì hiệu suất cache càng ngày càng phát huy. Chính vì vậy, khi hết hạn cache thì giải thoát cho những cache dư thừa.

Điều thứ hai đó chính là khi một bộ nhớ cache thường xuyên bị tấn công bởi thế lực nào đó thì chúng ta cũng có thể đối phó với việc làm thời thời gian hết hạn của nó, điều này luôn đảm bảo rằng bộ nhớ đó luôn tồn tại và luôn được update. Qua đó đảm bảo tốc độ truy cập của bộ nhớ cache và cải thiện hiệu suất của hệ thống. Cho mày tấn công thoải mái, đừng có và vào database của anh là được, như sự cố Cache breakdown mà chúng ta đã nói tới.

Thứ ba và cũng là một ưu điểm khác của việc đặt thời gian hết hạn là khi cơ sở dữ liệu và bộ nhớ cache có sự mâu thuẫn về dữ liệu hay còn gọi là khác nhau về dữ liệu, điều này có thể được sử dụng như một phương sách cuối cùng. Nói cách khác, khi dữ liệu xuất hiện không nhất quán, thời gian hết hạn có thể đảm bảo rằng cơ sở dữ liệu và dữ liệu được lưu trong bộ nhớ cache chỉ không nhất quán từ thời điểm bộ cache chưa hết hạn mà thôi. Chứ hết hạn rồi, thì tự động cập nhật lại rồi thì lại OK. Có thể nhiều bạn không hiểu điều này. Đừng lo, tôi sẽ giải thích kỹ hơn ở phần dưới.

Điều quan trọng là phần quan trọng nhất của bài viết này là nằm ở dưới đây, tiếc cho những ai leave sớm...

Cache aside pattern

Có thể nói mô hình Cache aside pattern là một mô hình chuẩn và đã có từ lâu, hầu như ai cũng đồng ý và sử dụng, nhưng cũng có phản đối nhiều hay xem dưới đây.

Thực tế hình này không sao siêu chút nào nhưng phải tôn trọng những người đi đầu về công nghệ, về cơ bản thì chúng ta sử dụng nó lúc bình thường nhưng không nhất thiết phải biết tên. Sau đây là phần giới thiệu ngắn gọn về ý tưởng của chương trình này:

  • 1 - No cache: Có nghĩa là user xem chi tiết một sản phẩm, nhưng hiện tại trong cache không có thông tin, chính vì thế lục lọi database để lấy thông tin, và khi có rồi thì thông tin này sẽ được cập nhật vào bộ nhớ cache sau đó đẩy lên cho user.
  • 2 - Có cache: Tương tự User đọc dữ liệu từ bộ nhớ cache đầu tiên nếu nó có và nếu nó truy cập, nó sẽ trả về trực tiếp không cần xuống database nữa.
  • 3 - Cập nhật: Chương trình cập nhật cơ sở dữ liệu trước và xóa bộ nhớ cache

Hầu như ai điều 1điều 2 chúng ta sẽ không bàn tới, vì có thể đó là điều đương nhiên rồi. Vậy còn điều thứ 3thì sao? Có rất nhiều sự tranh cãi cho vấn đề này, và tôi cũng có ý kiến riêng của tôi. Vì vấn đề này chính là phần quan trọng nhất của bài viết này, như tiêu đề bài viết, nó liên quan đến sự nhất quán dữ liệu trong bộ nhớ cache và database.

Đảm bảo sự nhất quán dữ liệu cache và SQL

Câu hỏi quan trọng nằm ở điểm thứ ba như tôi nói ở trên, đó là quá trình cập nhật dữ liệu và tại sao chúng ta cần cập nhật cơ sở dữ liệu trước? Tại sao tôi nên xóa bộ nhớ cache thay vì cập nhật nó sau đó? Đó là vấn đề mà một back-end giỏi cần phải hiếu để hệ thống chạy trơn tru hơn có thể.

Tình huống đơn giản nhất là bạn có muốn cache dữ liệu một đằng mà database lại dữ liệu một nẻo không? Ý tôi ở đây là dữ liệu nó không giống nhau, có nghĩa là tính nhất quán về dữ liệu không tuân thủ trong việc lập trình dữ liệu.

Thực tế khi giải quyết bài toán trên thì có 4 cách như sau nhưng tất cả đều có vấn đề, đương nhiên không thể xoá database rồi:

  • Cập nhật bộ nhớ cache trước, sau đó cập nhật cơ sở dữ liệu
  • Cập nhật cơ sở dữ liệu trước, sau đó cập nhật bộ nhớ cache
  • Xóa bộ nhớ cache trước, sau đó cập nhật cơ sở dữ liệu
  • Cập nhật cơ sở dữ liệu trước, sau đó xóa bộ nhớ cache

Nếu là bạn thì bạn chọn cách nào cho mọi việc được êm xuối. Tiếp theo, chúng ta sẽ thảo luận từng tình huống một. Hay để điều này cho bài viết tiếo theo của tôi. ...

Có thể bạn đã bị missing