Có cách nào để móc vào xóa bộ nhớ cache?


16

Đối với một trang web tổ chức lớn, với bộ nhớ cache nặng, tôi muốn tạo bộ đệm càng sớm càng tốt, để không người dùng nào có thể tạo ra bộ đệm ...

Tôi có một cron đặt tất cả các phút để thực hiện điều đó, bằng cách thực hiện một vài chức năng và yêu cầu các trang quan trọng, nhưng điều tôi đang tìm kiếm là một cách để biết khi nào bộ đệm vừa bị xóa , tốt nhất là một hook, vì vậy tôi có thể khởi chạy hàm tạo.

Bất kỳ ý tưởng ?


Tùy thuộc vào những gì bạn đang cố gắng thực hiện, câu trả lời của trang phay là một giải pháp hay để loại bỏ mã sau khi bộ nhớ cache đã bị xóa.
Lester Peabody

Câu trả lời:


7

Không có trong Drupal 7.x nhưng điều này đã được thêm vào như một cái móc cốt lõi, hook numbuild trong Drupal 8.x sau khi đủ số người yêu cầu. Có thể có một cách tốt hơn để giải quyết vấn đề của bạn trong 7.x - bạn đang cố gắng khởi tạo một số loại chức năng làm ấm bộ đệm ngay sau khi cron xóa bộ đệm, đúng không? Một cách khác để tiếp cận điều này là sử dụng cron Elysia có một số cải tiến đáng kể về cách thức hoạt động của cron nhưng hai cách có thể liên quan đến trường hợp sử dụng của bạn là:

Elysia Cron mở rộng cron tiêu chuẩn Drupal, cho phép kiểm soát hạt tốt đối với từng tác vụ và một số cách để thêm các công việc cron tùy chỉnh vào trang web của bạn.

  • Đặt thời gian và tần suất của từng tác vụ cron (bạn có thể chạy một số công việc mỗi ngày vào một giờ nhất định, chỉ khác hàng tháng và cứ thế ...). Đối với mỗi tác vụ, bạn có thể chỉ cần chọn giữa một số tùy chọn được sử dụng thường xuyên ("mỗi ngày một lần", "mỗi tháng một lần" ...) hoặc sử dụng cú pháp giống như "linux crontab" mạnh mẽ để đặt thời gian chính xác. Bạn thậm chí có thể xác định các tùy chọn thường xuyên sử dụng của mình để tăng tốc cấu hình trang web. ...
  • Thay đổi mức độ ưu tiên / thứ tự thực hiện nhiệm vụ. ...

Bạn có thể sử dụng mô-đun này để kiểm soát tốt hơn cách thức cron của bạn chạy để giúp giải quyết vấn đề bộ đệm cũ. Cụ thể, bạn có thể thêm một hook vào các hàm xây dựng lại của mình thành cron và sau đó sử dụng Elysia cron, đặt các thao tác này chạy ngay sau thao tác xóa bộ nhớ cache.

Có vẻ như bạn có thể gặp sự cố với cron chạy thường xuyên dẫn đến bộ đệm được tạo lại quá thường xuyên. Nếu đó là trường hợp, bạn có thể đặt hoạt động xóa bộ nhớ cache cụ thể trong Elysia cron để chạy ở tốc độ khác với các hoạt động cron còn lại của bạn, vì vậy, lập chỉ mục tìm kiếm sẽ cập nhật cứ sau 5 phút nhưng xóa bộ nhớ cache đầy đủ sẽ chỉ chạy mỗi 6 giờ, v.v.

Tinh chỉnh quản lý bộ đệm cron: drupal cron sẽ làm mất hiệu lực bộ đệm biến đổi mỗi lần chạy cron và đây là một vấn đề hiệu năng tuyệt vời nếu bạn có một tác vụ thường xuyên được gọi. Elysia cron tối ưu hóa quản lý bộ đệm và không cần phải vô hiệu hóa bộ đệm.


Vâng, đây là một bummer thực sự. Nhanh lên D8! Trên thực tế, tôi đã đọc, như tôi đã nói với bạn, một người bạn thân với elysia_cron, chạy mỗi phút, làm ấm những gì tôi cần. Nhưng vì trang web của tôi sẽ có> 10.000 / lượt truy cập / giờ, tôi khá chắc chắn rằng sbdy sẽ rơi vào bộ đệm trống ... Dù sao đi nữa, tôi biết bây giờ đó là giới hạn D7!
Gregory Kapustin

11

Không, không có. Không hẳn vậy. Ít nhất là không trong 6 hoặc 7. Giả sử 7:

Nếu bạn nhìn vào drupal_flush_all_caches()bạn sẽ thấy nó gọi hook_flush_caches(). Móc này có nghĩa là:

"thêm tên bảng bộ đệm vào danh sách các bảng bộ đệm sẽ bị xóa bằng nút Xóa trên trang Hiệu suất hoặc bất cứ khi nào drupal_flush_all_caches được gọi."

Sẽ thật hấp dẫn khi chỉ cần làm cho hook của mô-đun của bạn đi cuối cùng và viết mã ở đó. Nhưng hãy nhìn lại drupal_flush_all_caches(). Xóa thực tế xảy ra như thế này:

  $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
  foreach ($cache_tables as $table) {
    cache_clear_all('*', $table, TRUE);
  }

Nó có nghĩa là tất cả các hook được bắn trước khi mọi thứ thực sự được xóa. Chỉ có một chức năng gọi là sau khi xóa thực tế, _system_update_bootstrap_status()nhưng nó chỉ gọi hook_boot, hook_exit, hook_watchdoghook_language_init- móc bạn không muốn thực hiện chỉ để cung cấp chức năng bộ nhớ cache rõ ràng phụ thuộc.


Khỉ thật, tôi mất nhiều thời gian để thêm tất cả các liên kết này;) Sẽ rời khỏi nó ngay bây giờ vì tôi không thể ép mình xóa nó, sau quá nhiều thời gian để giải thích lý do tại sao nó không thể được thực hiện.
Mołot

3
Để lại nó, nó là một câu trả lời tốt.
mpdon Arena

Có, hãy để lại, tôi không thể kiểm tra tất cả các câu trả lời hay nhưng tôi đã đánh dấu nó :)
Gregory Kapustin

11

Cách để làm điều này là sử dụng hook_flush_cacheskết hợp với register_shutdown_function. Mã ví dụ:

/**
 * Implements hook_flush_caches().
 */
function mymodule_flush_caches() {
   // After caches are cleared we will run mymodule_cache_rebuild()
   register_shutdown_function('mymodule_cache_rebuild');

   // We don't want to add any custom cache-tables, so just return an empty array
   return array();
}

/**
 * Rebuild expensive cache items that need to be rebuilt immediately.
 */
function mymodule_cache_rebuild() {
  // Do the cache rebuild work here
}

Sử dụng register_shutdown_functioncó nghĩa là chức năng xây dựng lại bộ đệm của chúng tôi sẽ được gọi sau khi bộ nhớ cache đã bị xóa. Chúng tôi đang lạm dụng hook_flush_cachestheo cách mà nó không bao giờ có ý định sử dụng, nhưng điều này sẽ làm chính xác những gì bạn cần.


8

Nét rộng ở đây:

Mặc dù không có kết nối nào ở trước D8, bạn có thể viết phụ trợ cơ sở dữ liệu của riêng bạn dựa trên tiêu chuẩn DrupalDatabaseCachevà sau đó viết bất kỳ hoặc tất cả các loại logic vào clear()chức năng của bạn . Một cái nhìn nhanh sẽ gợi ý rằng đây là một cách đơn giản hợp lý trong D7 (chỉ cần sao chép lớp vào tên tùy chỉnh của bạn và sửa đổi nó, v.v. bằng cách ném vào một module_invoke_all()cách phù hợp) và với mô-đun cache_backport thậm chí sẽ hoạt động trong D6. Sau đó chỉ ra bất kỳ thùng bộ nhớ cache nào bạn muốn rõ ràng và bạn nên tiếp tục.


3
Đây có lẽ là giải pháp tốt nhất, chỉ có "vấn đề" là nếu bạn có nhiều thùng bộ đệm (memcache, redis, v.v.), bạn phải mở rộng một số lớp bộ đệm. Vẫn có giá trị mặc dù
Clive

Sẽ không hoạt động với bộ đệm trong memcached, apc hoặc giải pháp không db khác, phải không?
Mołot

Tôi sử dụng Redis, không chắc chắn rằng sẽ làm việc.
Gregory Kapustin

Nếu bạn đang sử dụng drupal.org/project/redis, bạn sẽ có thể sao chép hoặc sửa đổi các lớp được cung cấp, vv trong một mô-đun tùy chỉnh và sau đó sử dụng chúng. Tuy nhiên, nếu bạn đang sử dụng một cái gì đó dọc theo nền tảng của Pantheon nơi họ cung cấp tất cả các công việc nặng nhọc cho redis, thì đúng vậy, bạn cần phối hợp với họ về tất cả những điều này.
Jimajamma

3

Nếu bạn nhìn vào nguồn cho drupal_flush_all_caches()clear_cache_all(), bạn sẽ thấy rằng không có hook nào được gọi là xóa bài, đó là một lỗi khá hay.

Rất khó để đảm bảo rằng người dùng sẽ không bao giờ phải chờ đợi một số mục bộ nhớ cache được xây dựng, vì vậy tôi cố gắng tránh xóa bộ nhớ cache đầy đủ nhất có thể.

Một phương pháp thực sự hữu ích là hình thành thay đổi trang hiệu suất để kết nối trình xử lý đệ trình, chỉ cần xóa bộ đệm đối diện về phía trước và không chạm vào menu, sổ đăng ký và bộ đệm lõi tương tự. Tôi đã có kết quả tốt với điều này, vì việc xây dựng lại menu và đăng ký chiếm khoảng một nửa thời gian để xây dựng lại bộ đệm đầy đủ.

Một điều nữa là tôi có một tập lệnh drush thực hiện drupal_http_request()trên tất cả các URL của tôi (không chỉ các tập tin quan trọng) để mọi thứ được lưu trữ. Làm thế nào điều này được thực hiện khác nhau tùy theo trang web. Đôi khi tôi chỉ có thể EFQ các nút được xuất bản và xây dựng các URL theo cách đó. Những lần khác, bạn có thể truy vấn các bảng sơ đồ trang web XML để lấy URL của mình. Sau đó tôi gọi nó từ cron hệ thống của tôi thường xuyên khi tôi cần.


1

Một vài lựa chọn:
https://www.drupal.org/project/cache_graceful có thể chính xác là những gì bạn muốn.

https://www.drupal.org/project/apdqc có 2 hook bắn vào bộ nhớ cache cho phép bạn thay đổi phần xóa drupal_alter('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);và sau khi cho phép bạn phản ứng với phần xóa module_invoke_all('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);. Để APDQC hoạt động chính xác và được đặt $conf['apdqc_call_hook_on_clear'] = TRUE;trong tệp settings.php của bạn và sau đó các hook sẽ được gọi bất cứ khi nào xóa bộ nhớ cache.


1

Điều này có thể không phù hợp với tất cả mọi người và có thể không đủ nhanh cho OP - vì nó chỉ được kích hoạt trong lần khởi tạo trang tiếp theo. Tuy nhiên, nó đã giúp tôi kích hoạt mã chỉ sau khi "xóa tất cả bộ đệm" không nhạy cảm với thời gian.

Rõ ràng là HOOKcần thay thế bằng tên mô-đun của riêng bạn.

/**
 * Implements hook_init().
 */
function HOOK_init(){
  // if there is no cache_not_empty defined, define it 
  // and then trigger our cache cleared code
  if ( !cache_get('HOOK_cache_not_empty') ) {
    cache_set('HOOK_cache_not_empty', TRUE);
    foreach (module_implements('cache_cleared') as $module) {
      module_invoke($module, 'cache_cleared');
    }
  }
}

/**
 * Implements hook_cache_cleared().
 */
function HOOK_cache_cleared(){
  // do what you need here, in which ever module.
}

Nếu bạn có một thùng cụ thể mà bạn cần nhắm mục tiêu, có thể sửa đổi ở trên để hỗ trợ điều đó, miễn là toàn bộ thùng được dọn sạch tại điểm xóa bộ nhớ cache của bạn.

hook_initchỉ được thực hiện cho các trang không lưu trữ. Mặc dù vì xóa bộ nhớ cache đầy đủ có nghĩa là không có trang được lưu trong bộ nhớ cache, nhưng điều này không gây ra sự cố. Tuy nhiên, các hệ thống bộ nhớ đệm bên ngoài như Varnish sẽ cản trở việc kích hoạt này và điều đó có nghĩa là nó sẽ chỉ xảy ra khi yêu cầu thích hợp tiếp theo quay trở lại Drupal.

Cũng cần lưu ý rằng tùy thuộc vào hệ thống bộ nhớ đệm của bạn - chính xác là khi nào cache_setcó sẵn cho tất cả người dùng đồng thời - rằng hook này có thể được kích hoạt nhiều lần đồng thời, đặc biệt nếu bạn có số lượng người dùng lớn.


0

Tôi có một nhu cầu tương tự, trong đó một khách hàng muốn xóa cả bộ đệm Drupal và Varnish khi họ nhấn nút "tuôn tất cả bộ đệm". Tôi chiếm đoạt mục menu đó để làm như vậy.

Điều này sẽ không đạt được bất kỳ xóa bộ nhớ cache trên cron hoặc bất cứ nơi nào khác - chỉ trên liên kết menu.

/**
 * Implements hook_menu_alter().
 */
function mymodule_menu_alter(&$items) {
  if (isset($items['admin_menu/flush-cache'])) {
    $items['admin_menu/flush-cache']['page callback'] =
      "_mymodule_custom_flush_cache";
  }
}

/**
 * Hijacks the "flush all caches" button in menu
 */
function _mymodule_custom_flush_cache() {
  /**
   * Clear varnish, or other logic here
   */
  admin_menu_flush_cache(); //Run the normal cache clearing stuff
}

Thx Travis, nhưng tôi đang tìm kiếm một cách liên kết với bất kỳ bộ nhớ đệm rõ ràng nào, không chỉ một cách tự động được kích hoạt bởi người dùng.
Gregory Kapustin

0

Bạn có thể muốn thử https://www.drupal.org/project/recacher - nó sử dụng mô-đun hết hạn bộ nhớ cache để phát hiện các trang đã hết hạn và sau đó chỉ lưu lại bộ đệm những trang đó bằng HTTPRL tuyệt vờ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.