【问题标题】:PHP object serialization for several large objects几个大对象的PHP对象序列化
【发布时间】:2013-07-28 01:31:08
【问题描述】:

我正在开发一个 php 应用程序,它在与用户交互的过程中构建了几个大型对象集合。这些对象需要在来自用户的请求中持续存在,我已经使用 php 会话成功实现了这一点。对象会被持久化,直到用户对他们所做的事情感到满意并且他们请求保存对象所代表的信息。

在分析应用程序时,我发现会话启动大约需要请求总时间的一半(请求总共大约需要 4 秒)。由于并非所有存储的对象都用于用户的每个请求,因此我尝试通过选择性地恢复请求所需的对象来提高应用程序的响应能力。为此,我已将对象序列化为单个文件,并且仅对所需的对象进行反序列化。这种变化实际上炸毁了应用程序,因为序列化/反序列化消耗了大量内存(以及运行时间)。令我惊讶的是,会话处理程序可以在更短的时间内序列化和反序列化所有对象,并且比我尝试只做一个子集的内存消耗更低。我相信这可能是由于将所有序列化的对象数据加载到内存中,但我不确定。

以下是序列化和反序列化我使用过的对象的代码:

将序列化对象写入文件的代码:

public static function writeClose() {
    foreach (self::$activeRegistries as $registryName=>$registry) {
        if (isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]["registries"]) && isset($_SESSION["filemap"]["registries"][$registryName])) {
            $path = $_SESSION["filemap"]["registries"][$registryName];
            if (file_put_contents($path, serialize($registry)) === false) {
                throw new repositoryException("Exception while writing the '$registryName' registry to storage");
            }
        } else {
            throw new repositoryException("Could not find the file path for the '$registryName' registry");
        }
    }
}

检索序列化对象的代码:

private static function getRegistry($registryName) {
    // First check to see if the registry is already active in this request
    if (isset(self::$activeRegistries[$registryName])) {
        $registry = self::$activeRegistries[$registryName];
    } else {
        // The registry is not active, so see if it is stored for the session
        if (isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]["registries"][$registryName])) {
            $filePath = $_SESSION["filemap"]["registries"][$registryName];
            if (file_exists($filePath)) {
                $registry = unserialize(file_get_contents($filePath));
                self::$activeRegistries[$registryName] = $registry;
            } else {
                throw new repositoryException("Exception while getting serialized object for registry '$registryName'");
            }
        } else {
            // The registry is not saved in the session, so create a new one
            $registry = self::createRegistry($registryName);
            $filePath = "/tmp/" . session_id() . $registryName;
            $_SESSION["filemap"]["registries"][$registryName] = $filePath;
            self::$activeRegistries[$registryName] = $registry;
        }
    }
    return $registry;
}

与使用 php 会话处理程序检索每个请求的所有集合相比,如何改进应用程序?

【问题讨论】:

  • 所以你已经使用文件来为用户而不是会话存储数据,对吧?并且您希望通过请求为用户提供数据。我认为把它放在一个临时文件中会是一个很好的解决方案,但你应该让它成为唯一的。但要获得更多帮助,我应该了解更多关于代码的信息,也许 AJAX 也可以帮助你。
  • 我使用了 php 会话处理程序和包含用户创建对象的序列化表示的文件。序列化和反序列化过程消耗大量内存和时间。会话正常工作并且在内存和时间方面效率更高,但仍消耗大约一半或处理来自用户的请求所需的总时间。我正在寻找一种提高性能的方法。我用于执行序列化和反序列化的代码在我的原始帖子中给出如果您需要查看更多代码,请具体说明您需要查看的其他内容。
  • 我没有说我需要查看任何代码。我说我需要更多地了解代码。关于过程。我需要了解每个请求中需要存储或恢复多少数据?是否有一些请求不需要这些数据或某些数据?如果我们需要在每个请求中设置或获取一小部分数据,也许有一些方法可以提高性能。至少给我一个模拟代码模拟数据和模拟请求,以帮助我更多地帮助你。

标签: php performance session serialization large-data


【解决方案1】:

您可以通过更改会话的存储位置来加快现有的基于会话的实施。默认情况下,会话数据被写入服务器上的文件,然后通过浏览器 cookie 关联。如果您的会话包含大量数据,那么您看到的时间可能是物理驱动器的寻道时间和读取时间。

然而,PHP 支持多种会话存储方法。我建议尝试 MemCached 选项:http://php.net/manual/en/memcached.sessions.php

session.save_handler = memcached
session.save_path = "localhost:11211"

您当然需要安装 MemCached。

【讨论】:

    猜你喜欢
    • 2013-02-12
    • 2015-04-08
    • 2012-04-15
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多