How to choose between cache-aside, read-through, write-through, client-side, and distributed caching strategies Như đã đề cập trong những ngày gần đây bài viết, chúng tôi rất vui mừng rằng Pekka Enberg đã quyết định viết Và chúng tôi tự hào được tài trợ 3 chương từ nó. Tại sao lưu trữ dữ liệu? Toàn bộ sách về Latency Get the Latency book trích đoạn PDF Get the Latency book trích đoạn PDF Get the Latency book trích đoạn PDF Ngoài ra, Pekka vừa chia sẻ những đoạn trích quan trọng từ cuốn sách đó trong một (Bây giờ có sẵn theo yêu cầu) Masterclass về xây dựng các ứng dụng chậm trễ thấp Hãy tiếp tục chúng tôi cuốn sách trích xuất với nhiều hơn từ chương bộ nhớ cache của Pekka. Nó được in lại ở đây với sự cho phép của nhà xuất bản. Latency * Đánh giá Khi thêm bộ nhớ đệm vào ứng dụng của bạn, trước tiên bạn phải xem xét chiến lược bộ nhớ đệm của bạn, xác định cách đọc và viết xảy ra từ bộ nhớ đệm và lưu trữ sao lưu cơ bản, chẳng hạn như cơ sở dữ liệu hoặc dịch vụ. Nói cách khác, khi ứng dụng của bạn tìm kiếm một giá trị từ bộ nhớ cache, nhưng giá trị không có hoặc đã hết hạn, chiến lược bộ nhớ cache yêu cầu cho dù đó là ứng dụng của bạn hoặc bộ nhớ cache lấy giá trị từ cửa hàng sao lưu. Ứng dụng Cache-Aside Caching Cache-side caching có lẽ là chiến lược bộ nhớ đệm điển hình nhất mà bạn sẽ gặp phải.Khi có một hit bộ nhớ đệm, độ trễ truy cập dữ liệu được chi phối bởi độ trễ truyền thông, thường là nhỏ, vì bạn có thể có được một bộ nhớ đệm gần trên một máy chủ bộ nhớ đệm hoặc thậm chí trong không gian bộ nhớ ứng dụng của bạn. Tuy nhiên, khi có sự thiếu hụt bộ nhớ cache, với bộ nhớ cache bên cạnh, bộ nhớ cache là một cửa hàng thụ động được cập nhật bởi ứng dụng. nghĩa là, bộ nhớ cache chỉ báo cáo một sự thiếu hụt và ứng dụng chịu trách nhiệm lấy dữ liệu từ cửa hàng sao lưu và cập nhật bộ nhớ cache. Hình 1 cho thấy một ví dụ về cache-aside caching trong hành động. một ứng dụng xem xét một giá trị từ một bộ nhớ cache bằng một khóa bộ nhớ cache, xác định dữ liệu mà ứng dụng quan tâm. Nếu khóa tồn tại trong bộ nhớ cache, bộ nhớ cache trả về giá trị liên quan đến khóa, mà ứng dụng có thể sử dụng. Tuy nhiên, nếu khóa không tồn tại hoặc hết hạn trong bộ nhớ cache, chúng tôi có một bộ nhớ cache bị mất, mà ứng dụng phải xử lý. Giả sử bạn đang lưu trữ thông tin người dùng và sử dụng ID người dùng làm khóa tìm kiếm. Trong trường hợp đó, ứng dụng thực hiện truy vấn bởi ID người dùng để đọc thông tin người dùng từ cơ sở dữ liệu. Thông tin người dùng được trả về từ cơ sở dữ liệu sau đó được chuyển đổi thành một định dạng bạn có thể lưu trữ trong bộ nhớ cache. Sau đó, bộ nhớ cache được cập nhật với ID người dùng là khóa bộ nhớ cache và thông tin là giá trị. Ví dụ, một cách điển hình để thực hiện loại bộ nhớ cache này là chuyển đổi thông tin người dùng được trả về từ cơ sở dữ liệu sang JSON và lưu trữ nó trong bộ nhớ cache. Cache-aside caching là phổ biến bởi vì nó là dễ dàng để thiết lập một máy chủ bộ nhớ cache như Redis và sử dụng nó để bộ nhớ cache truy vấn cơ sở dữ liệu và các câu trả lời dịch vụ. Với bộ nhớ cache-aside caching, máy chủ bộ nhớ cache là thụ động và không cần phải biết cơ sở dữ liệu bạn sử dụng hoặc làm thế nào kết quả được lập bản đồ vào bộ nhớ cache. Trong nhiều trường hợp, bộ nhớ cache là một cách đơn giản và hiệu quả để giảm độ trễ ứng dụng.Bạn có thể ẩn độ trễ truy cập cơ sở dữ liệu bằng cách có thông tin có liên quan nhất trong một máy chủ bộ nhớ cache gần ứng dụng của bạn. Ví dụ, nếu bạn có nhiều trình đọc đồng thời đang tìm kiếm một khóa trong bộ nhớ cache, bạn cần phối hợp trong ứng dụng của mình cách bạn xử lý các lỗ hổng bộ nhớ cache đồng thời; nếu không, bạn có thể kết thúc với nhiều truy cập cơ sở dữ liệu và cập nhật bộ nhớ cache, có thể dẫn đến các tìm kiếm bộ nhớ cache tiếp theo trả về các giá trị khác nhau. Tuy nhiên, với bộ nhớ cache bên lề, bạn mất hỗ trợ giao dịch vì bộ nhớ cache và cơ sở dữ liệu không biết nhau, và đó là trách nhiệm của ứng dụng để phối hợp các bản cập nhật cho dữ liệu. Cuối cùng, bộ nhớ cache bên lề có thể có độ trễ đuôi đáng kể bởi vì một số tìm kiếm bộ nhớ cache trải nghiệm độ trễ đọc cơ sở dữ liệu trên một cache miss. đó là, mặc dù trong trường hợp của một cache hit, độ trễ truy cập là nhanh bởi vì nó đến từ một máy chủ cache gần đó; tìm kiếm bộ nhớ cache mà trải nghiệm một cache miss chỉ nhanh như truy cập cơ sở dữ liệu. đó là lý do tại sao độ trễ địa lý cho cơ sở dữ liệu của bạn vẫn có thể quan trọng rất nhiều ngay cả khi bạn đang lưu trữ bộ nhớ cache vì độ trễ đuôi Đọc qua Caching Đọc qua bộ nhớ cache là một chiến lược trong đó, không giống như bộ nhớ cache bên cạnh, bộ nhớ cache là một thành phần hoạt động khi có một bộ nhớ cache bị thiếu. Khi có một bộ nhớ cache bị thiếu, bộ nhớ cache đọc qua cố gắng đọc một giá trị cho khóa từ cửa hàng sao lưu tự động. Sự chậm trễ tương tự như bộ nhớ cache bên cạnh, mặc dù thời gian chậm trễ truy xuất của cửa hàng sao lưu là từ bộ nhớ cache đến cửa hàng sao lưu, không phải từ ứng dụng đến cửa hàng sao lưu, có thể nhỏ hơn, tùy thuộc vào kiến trúc triển khai của bạn. Hình 2 cho thấy một ví dụ về một bộ nhớ cache đọc qua trong hành động. Ứng dụng thực hiện một tìm kiếm bộ nhớ cache trên một phím, và nếu có một bộ nhớ cache bỏ lỡ, bộ nhớ cache thực hiện một đọc đến cơ sở dữ liệu để có được giá trị cho phím. bộ nhớ cache sau đó tự cập nhật và trả về giá trị cho ứng dụng. Từ quan điểm của ứng dụng, một bộ nhớ cache bỏ lỡ là minh bạch bởi vì bộ nhớ cache luôn trả về một phím nếu có, bất kể có một bộ nhớ cache bỏ lỡ hay không. Đọc qua bộ nhớ cache phức tạp hơn để thực hiện bởi vì một bộ nhớ cache cần phải có thể đọc lưu trữ sao lưu, nhưng nó cũng cần phải chuyển đổi kết quả cơ sở dữ liệu thành một định dạng cho bộ nhớ cache. Ví dụ, nếu lưu trữ sao lưu là một máy chủ cơ sở dữ liệu SQL, bạn cần chuyển đổi kết quả truy vấn thành JSON hoặc định dạng tương tự để lưu trữ kết quả trong bộ nhớ cache. Tuy nhiên, bởi vì bộ nhớ cache phối hợp các bản cập nhật và cơ sở dữ liệu đọc bằng cách đọc qua bộ nhớ cache, nó có thể cung cấp các bảo đảm giao dịch cho ứng dụng và đảm bảo tính nhất quán trên các lỗ hổng bộ nhớ cache đồng thời. Tất nhiên, cảnh báo tương tự về độ trễ đuôi áp dụng cho bộ nhớ cache đọc qua như chúng áp dụng cho bộ nhớ cache bên cạnh. Một ngoại lệ: là các thành phần hoạt động, bộ nhớ cache đọc qua có thể che giấu độ trễ tốt hơn với, ví dụ, bộ nhớ cache làm mới trước. Ở đây, bộ nhớ cache cập nhật không đồng bộ bộ bộ nhớ cache trước khi các giá trị hết hạn – do đó che giấu độ trễ truy cập cơ sở dữ liệu khỏi các ứng dụng hoàn toàn khi một giá trị nằm trong bộ nhớ cache. Viết qua caching Cache-side và read-through caching là các chiến lược xung quanh cache đọc, nhưng đôi khi, bạn cũng muốn bộ nhớ cache để hỗ trợ viết. Trong những trường hợp như vậy, bộ nhớ cache cung cấp một giao diện để cập nhật giá trị của một khóa mà ứng dụng có thể kêu gọi. Trong trường hợp bộ nhớ cache-side, ứng dụng là người duy nhất giao tiếp với các cửa hàng lưu trữ và do đó cập nhật bộ nhớ cache. Tuy nhiên, với đọc-through caching, có hai lựa chọn để đối phó với viết: viết-through và viết-back caching. Cache ghi qua là một chiến lược trong đó một bản cập nhật cho bộ nhớ cache truyền ngay lập tức đến cửa hàng lưu trữ. Bất cứ khi nào một bộ nhớ cache được cập nhật, bộ nhớ cache sẽ đồng bộ cập nhật bộ nhớ cache với giá trị lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu trữ lưu Cache-through caching nhằm mục đích giữ cho bộ nhớ cache và lưu trữ sao lưu đồng bộ. Tuy nhiên, đối với bộ nhớ cache không giao dịch, bộ nhớ cache và lưu trữ sao lưu có thể không đồng bộ trong sự hiện diện của lỗi. Ví dụ, nếu viết để bộ nhớ cache thành công, nhưng việc viết để lưu trữ sao lưu thất bại, cả hai sẽ không đồng bộ. Tất nhiên, một bộ nhớ cache viết qua có thể cung cấp bảo đảm giao dịch bằng cách giao dịch một số độ trễ để đảm bảo rằng bộ nhớ cache và cơ sở dữ liệu đều được cập nhật hoặc không có cả hai. Giống như với bộ nhớ cache đọc qua, bộ nhớ cache viết qua giả định rằng bộ nhớ cache có thể kết nối với cơ sở dữ liệu và chuyển đổi giá trị bộ nhớ cache thành truy vấn cơ sở dữ liệu. Ví dụ, nếu bạn đang lưu trữ dữ liệu người dùng trong đó ID người dùng đóng vai trò là khóa và tài liệu JSON đại diện cho giá trị, bộ nhớ cache phải có khả năng chuyển đổi trình bày JSON của thông tin người dùng thành bản cập nhật cơ sở dữ liệu. Với viết qua bộ nhớ đệm, giải pháp đơn giản nhất thường là lưu trữ JSON trong cơ sở dữ liệu. Nhược điểm chính của viết qua bộ nhớ đệm là độ trễ liên quan đến cập nhật bộ nhớ đệm, về cơ bản tương đương với độ trễ cam kết cơ sở dữ liệu. Viết đằng sau caching Chiến lược ghi đè phía sau ghi đè cập nhật bộ nhớ cache ngay lập tức, không giống như ghi đè qua ghi đè, trong đó loại bỏ các bản cập nhật cơ sở dữ liệu.Nói cách khác, với ghi đè phía sau ghi đè, bộ nhớ cache có thể chấp nhận nhiều bản cập nhật trước khi cập nhật lưu trữ sao lưu, như được hiển thị trong Hình 4, nơi bộ nhớ cache chấp nhận ba bản cập nhật bộ nhớ cache trước khi cập nhật cơ sở dữ liệu. Độ trễ viết của bộ nhớ cache ghi đè phía sau là thấp hơn so với bộ nhớ cache ghi đè phía sau vì cửa hàng sao lưu được cập nhật không đồng bộ. Đó là, bộ nhớ cache có thể nhận ra việc viết ngay lập tức cho ứng dụng, dẫn đến việc viết chậm trễ thấp, và sau đó thực hiện cập nhật cửa hàng sao lưu trong nền. Tuy nhiên, nhược điểm của bộ nhớ cache ghi đè phía sau là bạn mất hỗ trợ giao dịch vì bộ nhớ cache không còn có thể đảm bảo rằng bộ nhớ cache và cơ sở dữ liệu được đồng bộ. Hơn nữa, bộ nhớ cache ghi đè phía sau có thể làm giảm độ bền, đó là sự đảm bảo rằng bạn không mất dữ liệu. Khách hàng Caching Một chiến lược bộ nhớ cache bên cạnh khách hàng có nghĩa là có bộ nhớ cache ở lớp khách hàng trong ứng dụng của bạn.Mặc dù các máy chủ bộ nhớ cache như Redis sử dụng bộ nhớ cache trong bộ nhớ, ứng dụng phải giao tiếp qua mạng để truy cập bộ nhớ cache thông qua giao thức Redis. Nếu ứng dụng là một dịch vụ chạy trong một trung tâm dữ liệu, một máy chủ bộ nhớ cache là tuyệt vời cho bộ nhớ cache bởi vì chuyến đi vòng quanh mạng trong một trung tâm dữ liệu là nhanh chóng, và sự phức tạp của bộ nhớ cache là trong bộ nhớ cache. Tuy nhiên, độ trễ dặm cuối cùng vẫn có thể là một yếu tố quan trọng trong trải nghiệm người dùng trên một thiết bị, đó là lý do tại sao bộ nhớ cache phía khách hàng là rất có lợi nhuận. Với bộ nhớ đệm phía khách hàng, sự kết hợp của bộ nhớ đệm đọc qua và ghi đệm phía sau là tối ưu từ quan điểm độ trễ vì cả đọc và viết đều nhanh. Tất nhiên, khách hàng của bạn thường sẽ không thể kết nối trực tiếp với cơ sở dữ liệu, nhưng thay vào đó truy cập cơ sở dữ liệu gián tiếp thông qua proxy hoặc máy chủ API. bộ nhớ đệm phía khách hàng cũng làm cho các giao dịch khó bảo đảm do các lớp truy cập gián tiếp và độ trễ của cơ sở dữ liệu. Đối với nhiều ứng dụng cần bộ nhớ cache client-side chậm trễ thấp, cách tiếp cận local-first để sao chép có thể thực tế hơn.Nhưng đối với bộ nhớ cache đọc đơn giản, bộ nhớ cache client-side có thể là một giải pháp tốt để đạt được độ trễ thấp.Dĩ nhiên, bộ nhớ cache client-side cũng có một sự thỏa hiệp: Nó có thể tăng tiêu thụ bộ nhớ của ứng dụng vì bạn cần không gian cho bộ nhớ cache. phân phối caching Cho đến nay, chúng tôi chỉ thảo luận về bộ nhớ cache như thể một trường hợp bộ nhớ cache duy nhất tồn tại. Ví dụ, bạn sử dụng bộ nhớ cache trong ứng dụng hoặc một máy chủ Redis duy nhất để bộ nhớ cache truy vấn từ cơ sở dữ liệu PostgreSQL. tuy nhiên, bạn thường cần nhiều bản sao của dữ liệu để giảm độ trễ địa lý trên các địa điểm khác nhau hoặc mở rộng để phù hợp với khối lượng công việc của bạn. Với bộ nhớ cache phân tán như vậy, bạn có nhiều trường hợp bộ nhớ cache hoạt động độc lập hoặc trong một cụm bộ nhớ cache. Với bộ nhớ cache phân tán, bạn có nhiều sự phức tạp và cân nhắc tương tự như được thảo luận trong Chương 4 về sao chép và Chương 5 về phân vùng. Với bộ nhớ cache phân tán, bạn không muốn phù hợp với tất cả dữ liệu được lưu trữ trong bộ nhớ cache trên mỗi trường hợp nhưng thay vào đó có dữ liệu bộ nhớ cache phân chia giữa các nút. Nhìn chung, bộ nhớ đệm phân tán là một giao điểm của những lợi ích và vấn đề của bộ nhớ đệm, phân vùng và sao chép, vì vậy hãy cẩn thận nếu bạn đang làm điều đó. * Đánh giá Để tiếp tục đọc, từ ScyllaDB hoặc . Tải chương 3 Latency miễn phí Mua toàn bộ cuốn sách của Manning Thông tin Cynthia Dunlop Cynthia là giám đốc quản lý chiến lược nội dung tại ScyllaDB. Cô đã viết về phát triển phần mềm và kỹ thuật chất lượng trong hơn 20 năm.