Bộ nhớ đệm bằng từ điển trong bộ nhớ. Có phải chúng ta đang làm sai?


8

Cách tiếp cận này là khá nhiều cách được chấp nhận để làm bất cứ điều gì trong công ty của chúng tôi. Một ví dụ đơn giản: khi một phần dữ liệu cho khách hàng được yêu cầu từ một dịch vụ, chúng tôi sẽ tìm nạp tất cả dữ liệu cho khách hàng đó (phần có liên quan đến dịch vụ) và lưu nó vào một từ điển trong bộ nhớ sau đó phục vụ nó từ đó theo các yêu cầu sau (chúng tôi điều hành các dịch vụ đơn lẻ). Mọi cập nhật sẽ đến DB, sau đó cập nhật từ điển trong bộ nhớ. Có vẻ như tất cả đều đơn giản và vô hại nhưng khi chúng tôi thực hiện các quy tắc kinh doanh phức tạp hơn, bộ đệm sẽ không đồng bộ và chúng tôi phải đối phó với các lỗi khó tìm. Đôi khi chúng tôi trì hoãn việc ghi vào cơ sở dữ liệu, giữ dữ liệu mới trong bộ nhớ cache cho đến lúc đó. Có những trường hợp khi chúng ta lưu trữ hàng triệu hàng trong bộ nhớ vì bảng có nhiều quan hệ với các bảng khác và chúng ta cần hiển thị dữ liệu tổng hợp một cách nhanh chóng.

Tất cả việc xử lý bộ đệm này là một phần lớn của cơ sở mã của chúng tôi và tôi cảm thấy đây không phải là cách đúng đắn để làm điều đó. Tất cả sự tung hứng này làm tăng quá nhiều tiếng ồn cho mã và nó làm cho khó hiểu logic kinh doanh thực tế. Tuy nhiên tôi không nghĩ rằng chúng tôi có thể phục vụ dữ liệu trong một khoảng thời gian hợp lý nếu chúng tôi phải truy cập cơ sở dữ liệu mỗi lần.

Tôi không hài lòng về tình hình hiện tại nhưng tôi không có cách nào khác tốt hơn. Giải pháp duy nhất của tôi là sử dụng bộ đệm cấp 2 NHibernate nhưng tôi gần như không có kinh nghiệm với nó. Tôi biết nhiều doanh nghiệp sử dụng Redis hoặc MemCached rất nhiều để đạt được hiệu suất nhưng tôi không biết làm thế nào tôi có thể tích hợp chúng vào hệ thống của chúng tôi. Tôi cũng không biết liệu chúng có thể thực hiện tốt hơn các truy vấn và cấu trúc dữ liệu trong bộ nhớ hay không.

Có cách tiếp cận nào khác mà tôi nên xem xét không?

Câu trả lời:


9

Đầu tiên bạn câu hỏi cuối cùng: Tại sao Redis / memcached?

Không, chúng không (thường) nhanh hơn từ điển trong quy trình đơn giản. Lợi thế có được khi bạn có một số quy trình worker, hoặc thậm chí nhiều máy lớp ứng dụng. Trong trường hợp đó, thay vì mỗi tiến trình có bộ đệm nhỏ riêng, tất cả chúng đều chia sẻ một bộ đệm lớn (phân tán). Với bộ nhớ cache lớn hơn, bạn có được tỷ lệ trúng tốt hơn.

Như bạn có thể thấy, lớp bộ đệm trở thành một tài nguyên được chia sẻ, giống như cơ sở dữ liệu, nhưng (hy vọng) nhanh hơn.

Bây giờ, về phần lớn: làm thế nào để tránh sự lộn xộn?

Có vẻ như vấn đề của bạn là giữ bộ nhớ cache nhất quán đồng thời tách nó ra khỏi cơ sở dữ liệu. Tôi thấy ba điểm đau ở đó:

  1. bộ đệm không hợp lệ. Điều này chỉ là khó khăn. Đôi khi, giải pháp đơn giản nhất là thêm ID thế hệ vào mỗi bản ghi và sử dụng nó như một phần của khóa bộ đệm. Khi dữ liệu được cập nhật, bạn sẽ nhận được ID thế hệ mới và truy vấn bộ đệm tiếp theo sẽ không xuất hiện để bạn truy cập cơ sở dữ liệu và làm mới bộ đệm. Tất nhiên, mục nhập (hiện chưa được sử dụng) phải có thời gian hết hạn hợp lý để cuối cùng bị xóa khỏi bộ đệm.

  2. viết lại. Bạn nói rằng bạn làm việc trên bộ đệm và cập nhật cơ sở dữ liệu sau. Điều này nguy hiểm; hầu hết các kiến ​​trúc tránh ý tưởng đó. Một bước đi đúng hướng sẽ là đánh dấu mọi mục nhập mới hoặc được sửa đổi trong bộ đệm là 'bẩn' để có thể chuyển sang cơ sở dữ liệu bằng một quy trình tách rời. Một ý tưởng tốt hơn có thể là thêm vào hàng đợi tin nhắn ngay khi nó được sửa đổi, thực hiện việc viết vào cơ sở dữ liệu 'nội tuyến nhưng không đồng bộ'. Cuối cùng, tôi nghĩ bạn nên nhận ra rằng đây không phải là cách sử dụng hợp lệ cho bộ đệm, đây là "khu vực tổ chức" cần được xử lý với kiến ​​trúc khác với lớp bộ đệm.

  3. đồng bộ hóa quy trình: do bộ đệm trong tiến trình của bạn là riêng tư đối với mỗi quy trình, nên mọi sửa đổi sẽ không được truyền tới các quy trình khác cho đến khi chúng được chuyển sang cơ sở dữ liệu. Điều này có thể đúng theo thiết kế ứng dụng của bạn (loại cách ly giao dịch của người nghèo), nhưng có thể có kết quả ngoài ý muốn. Một kiến ​​trúc dễ quản lý hơn nhiều là một lớp bộ đệm chỉ là một API nhanh hơn cho cơ sở dữ liệu, với các thuộc tính được chia sẻ giống như cơ sở dữ liệu và giống như 'có thẩm quyền' như nó. Cho rằng bạn cần bộ nhớ ngoài quy trình, như memcached hoặc Redis.


8
Chỉ có hai điều khó trong Khoa học máy tính: vô hiệu hóa bộ đệm và đặt tên.
Michael Borgwardt

12
Chỉ có hai điều khó khăn trong Khoa học máy tính: vô hiệu hóa bộ đệm, đặt tên và lỗi do một.
Matthew King

2
@MatthewKing Chỉ có 3 điều khó trong Khoa học Máy tính: lỗi hai lần.
Jimmy Hoffa

@MatthewKing, tôi yêu sự hài hước. :)
Anthony Gatlin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.