Thuật toán cho các mục hết hạn trong lưu trữ khóa-giá trị là gì?


10

Tôi đã suy nghĩ về cách các kho lưu trữ khóa-giá trị hiện tại thực hiện "ngày hết hạn" cho các mặt hàng. Hiện tại tôi có 2 biến thể cho điều đó trong tâm trí:

  1. họ không làm gì cả (giữ dữ liệu hết hạn) và chỉ kiểm tra khi bạn làm, ví dụ, NHẬN bằng một số phím. Vấn đề ở đây là nếu bạn bị giới hạn về bộ nhớ, các mục đã hết hạn sẽ không bị xóa.
  2. họ giữ các cấu trúc dữ liệu bổ sung để có thể "sớm hết hạn". Tôi thấy nó có thể được thực hiện với một cái gì đó như thế này:

    storage_data = dict(key -> [value, expire_timestamp])
    expire_tree = SomeBinaryLikeTree(expire_timestamp -> [keys])
    

Câu trả lời:


6

Vấn đề xóa các mục đã hết hạn trong bộ đệm rất giống với bộ sưu tập rác , trừ đi sự phức tạp của việc đếm tham chiếu.

Mọi người tại Nasza-Klasa đã đề xuất thuật toán O (1) cho Memcache như sau:

Dường như nhiều người tin rằng vì một số lý do mà việc giải phóng các mục đã hết hạn không thể được thực hiện trong O (1) hoặc thậm chí là nó yêu cầu các hoạt động của Omega (N). Sử dụng một đống, hoặc các cấu trúc dữ liệu hàng đợi ưu tiên khác rõ ràng có thể cung cấp cho bạn O (log N), nhưng bản vá dưới đây nhắm vào O (1). Điều này đạt được bằng cách có một thùng cho mỗi giây và bằng cách đặt từng mục vào một thùng thích hợp bằng cách xem thời gian hết hạn. Sau đó, ở mỗi giây, chúng tôi chỉ cần các phần tử miễn phí từ thùng tiếp theo. Đây rõ ràng là thời gian khấu hao O (1), nhưng có thể xảy ra là bạn có rất nhiều yếu tố hết hạn cùng một lúc, do đó, bản vá cung cấp một giới hạn cố định cho số lượng hoạt động mà bạn sẵn sàng thực hiện cho mỗi yêu cầu, để làm cho bộ sưu tập rác chạy trơn tru hơn.

Xem toàn bộ đề xuất với mã đính kèm .


Cảm ơn. Tôi cũng nghĩ về giải pháp "xô" là một cách. Ngoài ra, không có vấn đề gì với "quá nhiều vật phẩm trong xô" vì bạn có thể sử dụng thuật toán "lấy những thùng bạn không lấy lần trước và lấy lại khi bạn hoàn thành".
Kostiantyn Rybnikov

@k_bx: đó là lý do tại sao họ đề xuất danh sách liên kết kép, vì vậy bạn có thể quay lại các nhóm trước đó.
vartec

Nếu xô giống như giây, thì bạn hoàn toàn không cần danh sách liên kết. Để đi trước, bạn chỉ cần giảm phím :)
Kostiantyn Rybnikov

@k_bx: giảm khóa bao nhiêu? một giây? Điều gì xảy ra nếu xô không hoàn toàn trống trước đó là 5 phút trước? giảm từng bước 1s 300 lần?
vartec

Khi máy chủ đầu tiên bắt đầu, biến init của bạn được gọi là current_baoire_bucket thành một số giá trị. Sau đó, bạn chạy dọn dẹp bắt đầu từ current_Exire_bucket, kết thúc thứ hai hiện tại. Sau khi dọn dẹp kết thúc, bạn ngủ trong một khoảng thời gian nhỏ. Nếu máy chủ dừng, bạn sẽ lại tiếp tục "hết hạn", nhưng điều đó chỉ xảy ra khi dừng máy chủ.
Kostiantyn Rybnikov

7

Tôi giả sử bộ lưu trữ khóa-giá trị quá lớn để chỉ lặp đi lặp lại trên tất cả các cặp kv để tìm ra cái nào có thể hết hạn. Tôi cũng giả định rằng mỗi lần truy cập đọc làm mới dấu thời gian hết hạn, do đó, chỉ những mục không được truy cập trong một thời gian mới hết hạn.

Thách thức là tìm hiệu quả tất cả các bản ghi có thể hết hạn (bất cứ khi nào dọn dẹp), nhưng cũng làm mới hiệu quả dấu thời gian hết hạn trên mỗi lần truy cập đọc (vì vậy chúng tôi phải tìm khóa trong cấu trúc được sử dụng để hết hạn).

Đề xuất của tôi: nhóm expiry_timestamp vào xô; ví dụ: nếu các mặt hàng tồn tại trong 8 giờ, hãy tạo một thùng mỗi giờ. Những thùng đó được giữ trong một danh sách liên kết; khi hết hạn, thùng đầu tiên được làm trống và danh sách giảm. Số lượng xô là khoảng thời gian tuổi thọ / dọn dẹp. Mỗi nhóm chứa một hàm băm của tất cả các khóa sẽ hết hạn. Lặp lại tất cả các khóa trong một bộ băm là đủ hiệu quả.

Trong quá trình truy cập đọc, chương trình sẽ kiểm tra khóa nào hiện tại và khóa nào thuộc về nhóm nào. Trong hầu hết các trường hợp, đó là cùng một nhóm, vì vậy không cần thực hiện thêm hành động nào. Mặt khác, loại bỏ khóa khỏi nhóm cũ (loại bỏ khỏi bộ băm có hiệu quả) và chèn nó vào nhóm mới.

   +--------------+   +--------------+   +--------------+
-->+ Expiry 08:00 +-->+ Expiry 09:00 +-->+ Expiry 10:00 +
   | KeySet       |   | KeySet       |   | KeySet       |
   +--------------+   +--------------+   +--------------+
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.