Вопрос или проблема
Я уже некоторое время решаю проблему с помощью третьестороннего веб-сайта, который регулярно достигает пределов памяти. Для начала сайт мог работать только с лимитом памяти в 1 ГБ. Он перешел на хостинг, который позволял только 512 МБ, и нам пришлось попытаться разобраться, что происходит.
После изучения мы обнаружили, что загрузка постов в плагине cartflows извлекает огромное количество данных из таблицы postmeta. Это в основном было вызвано тем, что редактор Beaver Builder использует postmeta для хранения версий страниц. Удалив предыдущие версии, мы по крайней мере смогли запустить сайт, хотя он все еще загружал около 150 МБ данных из postmeta. (Мы добавили мини-плагин из GitHub, предназначенный для регулярного удаления этих версий, который заявляет, что написан для “картофельных хостов с низкими лимитами”, хотя я бы не назвал 512 МБ низким лимитом)
Однако у нас теперь есть проблема с памятью в определенной части сайта, где случайно происходит потребление более 500 МБ памяти.
Я решил еще раз изучить плагин cartflows, чтобы посмотреть, могу ли я вручную ограничить извлекаемые метаданные в попытке уменьшить размер этого запроса и, надеюсь, сократить общее использование памяти.
Оказалось, что плагин использует get_posts
и уже указывает параметр meta_query для ограничения метаданных только одним ключом, что должно извлекать очень небольшое количество данных.
При более детальном исследовании выясняется, что, несмотря на то, что плагин пытается делать правильные вещи, система get_posts
в WordPress вызывает update_postmeta_cache, который бездумно извлекает все метаданные для соответствующих постов, чтобы обновить кэш в памяти (по сути, массив) всех метаданных постов.
Можно ли что-то сделать, чтобы решить эту проблему? Можно утверждать, что Beaver Builder не должен хранить большие объемы данных в postmeta, но я, очевидно, не могу удалить его активные данные, не нарушив работу сайта, а WordPress бездумно помещает все метаданные постов в кэш-массив, используя несколько сотен мегабайт оперативной памяти, хотя плагины, запрашивающие посты, этого не требуют.
Я не знаю, возможно ли вообще отключить кэширование метаданных или вся система построена на предположении, что все метаданные доступны через кэш. Даже попытка вручную изменить кэш метаданных так, чтобы игнорировать записи Beaver Builder, может остановить работу редактора страниц, если он предполагает, что к соответствующим метаданным можно получить доступ через кэш.
Ответ или решение
Способы отключения или ограничения кэширования postmeta в WordPress
На текущий момент вы сталкиваетесь с проблемами памяти на сайте, использующем WordPress, особенно в контексте использования плагина CartFlows и редактора Beaver Builder. Поскольку оба этих решения генерируют и хранят значительные объемы данных в таблице postmeta, это приводит к высокому потреблению памяти, что вызывает проблемы при ограничении в 512MB. Давайте подробно рассмотрим другие пути ограничения или отключения кэширования postmeta.
1. Отключение кэширования postmeta
К сожалению, полное отключение кэширования postmeta в WordPress является довольно сложной задачей, так как система полагается на этот механизм. Однако существуют подходы, позволяющие минимизировать его влияние:
-
Изменение поведения
update_postmeta_cache
:
В функциях вашего плагина или в theme-файле, можно изменить поведение функцииget_posts
, чтобы отключить кэширование. Один из простых способов сделать это — использовать фильтры. Вы можете создать свой собственный запрос без использования кэширования:add_filter('posts_results', function($posts, $query) { if($query->get('post_type') === 'your_post_type') { foreach ($posts as $post) { delete_post_meta_cache($post->ID); } } return $posts; }, 10, 2);
2. Оптимизация запроса get_posts
Хотя вы уже использовали параметр meta_query
, может быть полезно убедиться, что запросы максимально оптимизированы:
-
Используйте
fields
:
Когда вы запрашиваете посты, указывайте только те поля, которые вам действительно нужны. Например, можно запросить только ID и заголовок, избегая загрузки всей метаинформации:$args = [ 'post_type' => 'your_post_type', 'fields' => 'ids', // Запрашиваем только ID 'meta_query' => [ [ 'key' => 'your_meta_key', 'value' => 'your_meta_value', ] ], ]; $post_ids = get_posts($args);
3. Удаление неиспользуемых метаданных
Регулярно очищая таблицу postmeta от неиспользуемых или устаревших данных, вы можете снизить объем занимаемой памяти:
- Создание плагина для очистки postmeta:
Если у вас уже есть плагин для удаления ревизий, рассмотрите возможность расширения его функциональности для удаления метаданных, которые не были использованы в течение определенного времени.
4. Перемещение метаданных
Если вы управляете собственным кэшем, подумайте о перемещении больших объемов данных, которые Beaver Builder помещает в postmeta, в другие структуры данных. Например, вы можете рассмотреть возможность использования пользовательских таблиц для хранения больших объемов данных, что позволит сохранить постметаданные более легкими.
5. Использование систем кэширования
-
Кэширование запросов:
Используйте плагины кэширования, такие как W3 Total Cache или WP Super Cache, чтобы кэшировать результаты запросов. Это поможет снизить нагрузку на базу данных и уменьшить использование памяти. -
Оптимизация использования памяти:
На уровне сервера стоит рассмотреть возможность увеличения выделяемой памяти или использование сервисов кэширования, таких как Redis или Memcached, которые позволят разбить нагрузку на базу данных и улучшат производительность.
Заключение
Находясь в сложной ситуации с ограничением памяти для сайта WordPress, необходимо подойти к решению проблемы комплексно, применяя комбинацию технологий и оптимизаций. Отключение или ограничение кэширования postmeta, как видно, требует бережного подхода. Применяя предложенные вами стратегии, вы сможете значительно снизить потребление памяти и обеспечить более стабильную работу сайта.