Кэш-объект в PHP без использования сериализации

У меня есть сложный объект, который я создаю в PHP-скрипте. Я ищу способ сохранить этот объект таким образом, чтобы последующие запросы не нуждались в его воссоздании, или тратили время на неэтериализацию и перестройку. Используя xdebug, я обнаружил, что потратил половину всего времени запроса на создание этого объекта. Даже когда я храню объект явно в APC (или memcache), время его неэтериализации и загрузки всех классов занимает почти столько же времени, сколько и создание объекта.

Я не знаю, можно ли хранить и затем загружать «скомпилированный» объект в PHP. Это возможно? Существуют ли другие решения?

Я не уверен, что это возможно, но я подумал, что я должен спросить об этом.

EDIT: объект является двоичным деревом и используется как дерево решений. Код – это, в основном, API, который необходим для быстрого возврата ответа от дерева. Все это должно постоянно возрастать, поэтому я стараюсь максимизировать производительность везде, где это возможно.

Насколько мне известно, невозможно кэшировать объекты в PHP без сериализации. В общем, однако, механизмы кэширования (APC, Memcache и т. Д.) Действительно пытаются удалить соединения (-ы) db более, чем улучшить производительность (и тем самым уменьшить общую нагрузку DB). Это определенно, как memcache и другие работают в отношении Drupal. Другими словами, механизмы кэширования должны позволить вам масштабировать, хотя они могут не особенно повысить производительность.
Реализация механизма кэширования должна позволять вам более легко масштабироваться наружу, даже если производительность на машину не лучше, чем раньше для одного соединения. При определенном пороге производительность БД резко ухудшится, и механизмы кэширования должны помочь смягчить эту проблему.

Посмотрите на PHP-расширение Igbinary . Это замена для сериализации и нессериализации, и это может удовлетворить ваши потребности.

Он хранит объекты в двоичном формате вместо строки, которая уменьшает использование памяти, а также уменьшает время для сериализации и несериализации объектов.

Несмотря на то, что этот процесс проходит процесс нессериализации объекта, двоичный формат может увеличить производительность, достаточную для того, чтобы этот процесс был разумным для использования в вашем приложении.

Возможно, решение состоит в том, чтобы не построить один, массивный, дорогой объект.

Учитывая, что приложение PHP в значительной степени начинается с чистого листа при каждой загрузке страницы, решение, зависящее от одного гигантского объекта, плохо подходит для языка. Поскольку вы не вдаетесь в подробности о том, что ваш объект и что он делает, я не могу быть уверенным, но я подозреваю, что вам действительно не нужно все, что делает объект на каждой загрузке страницы. Если это так, вы можете серьезно рассмотреть возможность разделения на несколько меньших, более простых классов, которые вы можете создать при необходимости.

igBinary – полезное расширение, которое может помочь вам ускорить процесс сериализации / несериализации. Он заменяет стандартный механизм сериализации более умным, двоичным. Если вы управляете своим собственным сервером и можете установить его, стоит попробовать.

НЕТ, невозможно сохранить объект PHP в несериализованной форме; по крайней мере, не со следующими решениями кэширования (я пробовал эти, не знаю о других, которые могут существовать) :

  • файлы
  • Memcached
  • APC
  • База данных (yeap, вы можете думать о кешировании вещей в DB ^^ Drupal делает это по умолчанию, например)

Если для удаления вашего объекта требуется много времени, может быть, он действительно большой ? Есть ли способ уменьшить размер?

Например, у вас есть большой кусок HTML-кода в этом объекте? Если да, может ли он быть сохранен в другой записи кэша?
(сериализация – это «преобразование некоторых данных в строку, поэтому, если вы уже работаете со строкой, вам не нужно повторно сериализовать ее для хранения в кеше)

Или, может быть, это не займет много времени, чтобы создать его с нуля? В этом случае кэширование действительно необходимо?

если возможно, на вашей платформе напишите простой демон, который загружает ваше дерево при запуске, затем отвечает на запросы по сокету. Ваш серверный процесс может обрабатывать и отвечать на запросы без повторного создания дерева. Написание демона не является тривиальным, но очень хорошо документированным (по крайней мере, для C). Вам не придется переводить это на PHP с помощью расширений pcntl и posix.

в этом случае лучшим вариантом было бы написать собственный сервер.

это легко выполнимо в php – и у вас уже есть код, но php не может быть первым выбором большинства, когда дело доходит до написания серверов.

  • это может стать новым узким местом вашего приложения (поскольку php на самом деле не готов к многопоточности, и запросы отвечают последовательно)
  • не все хостеры позволяют создавать собственные скрипты cli
  • если ваше дерево решений изменяется, вы должны уведомить свой сервер о восстановлении дерева

Хотя PHP может предоставлять множество динамических функций для разных типов данных, эти операции не являются волшебными, и данные по-прежнему сохраняются в качестве базовых родных типов данных в том, что называется zval, что является технически сложной хэш-таблицей внутри родной zend api. Как и любой другой тип данных на любом языке, каждый zval будет существовать только в течение конечного периода. Для PHP этот период (максимально) – период обработки HTTP-запроса. В любой ситуации, чтобы сделать эти данные длиннее, чем один запрос, он должен быть преобразован из исходного zval в какой-либо другой вид, а затем каким-то образом сохранен (сюда относятся сложные типы, такие как объекты PHP, а также базовые типы, такие как Интс). Это всегда требует повторной инициализации каждого zval, а затем преобразования данных обратно из хранимой формы обратно в различные типы данных PHP в zval. Некоторые форматы хранения, такие как BSON, будут быстрее, чем сериализованные строки PHP, но (по крайней мере, на данный момент) это не обеспечит значительную часть заметного скачка производительности, поскольку он нигде не близок к производительности сохранения исходного zval по нескольким запросам. Вам все равно придется сериализовать эти данные в некотором роде, пройти время хранения, затем извлечь его и затем неэтериализировать. В настоящее время нет реальных решений для этого.

Обратите внимание, что PHP можно назвать тремя различными областями: SAPI, который инициирует и, в конечном счете, обрабатывает все состояния в каждом запросе; расширения, которые инициируются до начала каждого события запроса; а затем область сценария, которая инициируется каждым запросом. Все PHP-классы инициируются в рамках области сценария, но к ним могут обращаться как расширения, так и SAPI. Но единственным областью, которая может существовать за каждым отдельным запросом, является SAPI. Другими словами, объект PHP может поддерживаться только в нескольких запросах внутри SAPI (расширение не может помочь в этой проблеме в настоящее время), поэтому только пользовательский SAPI может поддерживать zvals в запросах.

Вы можете переписать свое приложение на ReactPHP, чтобы создать веб-сервер в одном долговременном PHP-процессе (например, Node.js или Web.py). Затем вы можете создать свой большой объект один раз (на сервере) в качестве глобальной переменной и получить доступ к нему из обработчиков событий запроса.