Thực hành tốt nhất để thực hiện bộ nhớ đệm tùy chỉnh?


17

Đối với mọi phiên bản của mọi loại thực thể, tôi tạo ra một số bộ đệm, được đặt tên như: [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]

Bây giờ bất cứ khi nào một thực thể được cập nhật, tôi muốn loại bỏ tất cả các bộ đệm bắt đầu bằng loại thực thể và id có liên quan.

Làm thế nào tôi nên lưu trữ / xóa các bộ nhớ cache?

Hiện tại tôi chỉ cache_set () , nhưng điều đó có một vấn đề khi tôi muốn xóa, vì tôi không biết tên của tất cả các bộ đệm có liên quan. Có an toàn khi thả các mục bộ đệm với db_delete () không?


Nếu bạn không biết tên của tất cả các bộ đệm có liên quan, làm thế nào bạn có thể sử dụng db_delete()?
kiamlaluno

Câu trả lời:


6

Để xóa các mục từ bộ đệm, bạn nên sử dụng cache_clear_all () . Lý do là việc triển khai bộ đệm đã sử dụng không thể sử dụng bảng cơ sở dữ liệu trong cơ sở dữ liệu hoạt động. Đó là những gì xảy ra với lớp DrupalDatabaseCache , nhưng nó không đúng với mọi lớp.

Nếu bạn nhìn vào _cache_get_object () (hàm được gọi bởi cache_get ()cache_set () ), bạn sẽ thấy nó chứa đoạn mã sau.

  static $cache_objects; 
  if (!isset($cache_objects[$bin])) {
    $class = variable_get('cache_class_' . $bin);
    if (!isset($class)) {
      $class = variable_get('cache_default_class', 'DrupalDatabaseCache');
    }
    $cache_objects[$bin] = new $class($bin);
  }
  return $cache_objects[$bin];

Lớp để thực hiện bộ đệm có thể khác nhau cho mỗi kho lưu trữ bộ đệm và thậm chí lớp mặc định có thể được thay đổi.

Hệ thống bộ đệm trạng thái cập nhật riêng tư giải thích chính xác lý do tại sao các chức năng bộ đệm thông thường không được sử dụng trong _update_cache_clear () , _update_cache_get ()_update_cache_set () . (Nhấn mạnh là của tôi.)

Chúng tôi đặc biệt KHÔNG sử dụng API bộ đệm lõi để lưu dữ liệu được tìm nạp về các bản cập nhật có sẵn. Điều cực kỳ quan trọng là bộ đệm này chỉ bị xóa khi chúng tôi điền vào nó sau khi tìm nạp thành công dữ liệu cập nhật mới. Việc sử dụng API bộ đệm lõi dẫn đến tất cả các loại sự cố tiềm ẩn dẫn đến việc cố gắng tìm nạp dữ liệu cập nhật có sẵn mọi lúc, bao gồm cả nếu một trang web có "tuổi thọ bộ nhớ cache tối thiểu" (cả tối thiểu và tối đa) được xác định, hoặc nếu một trang web sử dụng memcache hoặc một hệ thống bộ nhớ cache có thể cắm khác giả định bộ đệm dễ bay hơi.

Mô-đun Trình quản lý cập nhật vẫn sử dụng bảng {cache_update}, nhưng thay vì sử dụng cache_set(), cache_get()cache_clear_all(), có các hàm trợ giúp riêng thực hiện cùng các tác vụ cơ bản này nhưng đảm bảo rằng bộ đệm không bị xóa sớm và dữ liệu luôn được lưu trữ trong cơ sở dữ liệu, ngay cả khi memcache hoặc phụ trợ bộ đệm khác đang được sử dụng.

Trình quản lý cập nhật có các nhu cầu cụ thể cần thiết vì cố gắng tìm nạp thông tin cập nhật quá thường xuyên sẽ gây ra sự cố với máy chủ Drupal.org, xem xét rằng Trình quản lý cập nhật có thể có khả năng tìm nạp thông tin cập nhật từ bất kỳ trang web nào chạy Drupal.

Trong trường hợp của bạn, bạn có thể sử dụng [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]làm ID bộ đệm cho một cửa hàng lưu trữ bộ đệm duy nhất. Trong trường hợp bạn cần xóa tất cả các mục nhập cho một thực thể, bạn có thể sử dụng mã sau đây.

cache_clear_all("{$module}__{$entity_type}__{$entity_id}__", $bin, TRUE);

Nếu bạn không thể lấy giá trị để gán $modulekhi xóa bộ đệm hoặc bạn muốn xóa mục nhập bộ đệm một cách độc lập khỏi mô-đun mà dữ liệu đã được lưu trong bộ đệm, thì bạn có thể sử dụng ID bộ đệm khác, chẳng hạn như [entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from], hoặc [entity_type]__[entity_id]__[module_name]__[string_depending_on_where_the_cache_came_from]. cache_clear_all()xóa tất cả các mục bộ nhớ cache với một ID bộ nhớ cache bắt đầu với chuỗi thông qua như là đối số, khi $wildcardTRUE, và ID bộ nhớ cache không phải là '*'. Trong trường hợp này, bộ đệm sẽ bị xóa với đoạn mã sau.

cache_clear_all("{$entity_type}__{$entity_id}__", $bin, TRUE);

8

Tôi không thể nghĩ ra một lý do chính đáng tại sao việc bỏ các mục thủ công sẽ gây ra vấn đề. Tất nhiên, điều này giả định rằng bạn đang sử dụng MySQL làm phụ trợ cho bộ đệm cụ thể của mình; mặc dù tôi nghĩ điều tương tự cũng áp dụng cho bất kỳ loại phụ trợ bộ đệm nào khác, phương thức để xóa không nhất thiết phải là truy vấn cơ sở dữ liệu.

Nếu bạn lấy mô-đun cập nhật lõi làm ví dụ, nó sẽ bỏ qua các cache_*chức năng và xóa bộ nhớ cache của nó theo cách thủ công:

function _update_cache_clear($cid = NULL, $wildcard = FALSE) {
  if (empty($cid)) {
    db_delete('cache_update')
      // Clear everything except fetch task information because these are used
      // to ensure that the fetch task queue items are not added multiple times.
      ->condition('cid', 'fetch_task::%', 'NOT LIKE')
      ->execute();
  }
  else {
    $query = db_delete('cache_update');
    if ($wildcard) {
      $query->condition('cid', $cid . '%', 'LIKE');
    }
    else {
      $query->condition('cid', $cid);
    }
    $query->execute();
  }
}

Tôi luôn nghĩ rằng "nếu nó đủ tốt cho cốt lõi, thì nó đủ tốt cho tôi" :)

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.