3

情况:

  • 我有多个包含多个复杂对象的数组,每个数组都存储不同的数据,但格式相同。
  • 现在,这些数组(包含对象)太复杂而无法存储在 sql 表中,所以我将它们序列化,并将每个数组存储在单独的文件中。
  • 我使用 PHP 函数file_get_contents()读取数据,然后unserialize()在数据上使用。
  • 我必须为每个客户端请求加载一个文件(最大 100mb)并“反序列化()”并处理它。
  • 每个客户的数据都不相同
  • 所有数据总计约为 3GB。
  • 此数据每 24 小时更新一次,并且每次更新都会增加数据的大小。
  • 每个文件的最大数据为 100mb。

问题:

  • 我目前使用的方法适用于小文件(最大 5mb)。
  • 但是当涉及到较大的文件时,它会花费太多时间。
  • unserialize()如果我尝试加载大小约为 40mb 的文件,则该功能大约需要 33 秒才能执行。
  • 所以我目前方法的主要问题是unserialize().

主要问题:

  • 如何在不序列化它们的情况下存储我的非常复杂的对象,或者如何使我的反序列化更快?
4

2 回答 2

2

如何在不序列化它们的情况下存储我的非常复杂的对象,或者如何使我的反序列化更快?

如果您需要不是的 PHP 对象stdClass(您在数据成员旁边有类定义),您需要使用任何类型的 PHP 兼容序列化。

独立于 PHP 语言,序列化是有代价的,因为它是数据转换和映射。如果您有大量数据需要从字符串(二进制)信息转换为字符串(二进制)信息,则会占用其处理和内存。

默认情况下,您可以使用 PHP 的内置序列化serializeunserialize. PHP 提供了两种默认的序列化类型。其他扩展提供类似的东西。相关问题:

正如您所说,您需要某种序列化并且反序列化是瓶颈,您可以考虑选择另一个序列化程序,例如igbinary

但是,将 PHP 存储在平面文件中也可以。见var_export

// storing
file_put_contents(
    'name-of-data.php', '<?php return ' . var_export($data, true) . ';'
);

此示例以 PHP 可以读取文件的格式存储数据。对于 stdClass 对象和数组形式的结构化数据很有用。读回来很简单:

// reading
$data = include('name-of-data.php');

如果将 PHP 代码放入数据库,则不需要<?php前缀:

// storing
$string = 'return ' . var_export($data, true) . ';';
$db->store($key, $string);

// reading
$string = $db->read($key);
$data = eval($string);

使用的好处var_export是您可以使用 PHP 本身来解析数据。它通常比serialize/快,unserialize但是对于您的情况,您无论如何都需要对其进行度量。

我建议你尝试var_export一下它在文件大小和速度方面的表现。还有 igbinary。那就比较吧。收集时将更新的信息与您的问题一起留下,以便在这不能解决您的问题的情况下提供额外的建议。

想到的另一件事是使用 Json 格式。一些数据存储针对它进行了优化,因此您可以直接查询存储。此外,map-reduce 方法可以与这些数据存储中的许多一起使用,因此您可以扩展数据的处理。这是你无法直接理解的东西serialize/unserialize因为它总是一次处理一大块数据,你不能有所不同。

于 2012-10-27T13:39:19.573 回答
2

内部 php 序列化的更好选择是 MessagePack: http: //msgpack.org/

它更快、更小,并且支持几乎所有语言。

您可以在 pecl ( pecl install msgpack-beta)上找到 php 扩展

我做了一个简单的基准测试来比较一个相当大的对象(75M 在 php 中序列化)的 php 内部序列化、消息包和 json。Json 不在讨论范围内,因为它不能序列化对象,但它很快就会失败:)。结果如下所示(以秒为单位):

___________
msgpack
___________
Serialization: 0.203326
File size 33976K
Deserialization: 0.787364

___________
serialize
___________
Serialization: 1.912351
File size 75971K
Deserialization: 0.861699

___________
json
___________
Serialization: 0.000019
File size 0K
Deserialization: 0.000023

这是此基准测试源代码的要点 https://gist.github.com/3964906#comments

如您所见,消息包的性能明显优于 php 的序列化,但即便如此,反序列化的性能也没有您描述的那么糟糕

于 2012-10-27T14:54:11.683 回答