3

状況:

  • 複数の複雑なオブジェクトを含む複数の配列があり、それぞれが異なるデータを同じ形式で格納しています。
  • さて、これらの配列(オブジェクトを含む)は複雑すぎてSQLテーブルに格納できないので、それらをシリアル化し、各配列を別々のファイルに格納します。
  • PHP関数を使用しfile_get_contents()てデータを読み取り、データを使用unserialize()します。
  • クライアントリクエストごとに1つのファイル(最大100mb)をロードし、それを「unserialize()」して処理する必要があります。
  • このデータはすべてのクライアントで同じではありません
  • 合計で約3GBのデータです。
  • このデータは24時間ごとに更新され、データのサイズは更新ごとに増加します。
  • ファイルあたりの最大データは100MBです。

問題:

  • 私が現在使用している方法は、小さなファイルサイズ(最大5MB)で正常に機能します。
  • しかし、サイズの大きいファイルになると、時間がかかりすぎます。
  • unserialize()サイズが約40MBのファイルを読み込もうとすると、関数の実行に約33秒かかります。
  • したがって、私の現在の方法の主な問題はunserialize()

主な質問:

  • 非常に複雑なオブジェクトをシリアル化せずに保存するにはどうすればよいですか、またはシリアル化解除を高速化するにはどうすればよいですか?
4

2 に答える 2

2

非常に複雑なオブジェクトをシリアル化せずに保存するにはどうすればよいですか、またはシリアル化解除を高速化するにはどうすればよいですか?

そうでないstdClass(データメンバーの隣にクラス定義がある)PHPオブジェクトが必要な場合は、あらゆる種類のPHP互換のシリアル化を使用する必要があります。

PHP言語とは関係なく、シリアル化はデータ変換とマッピングであるため、代償が伴います。文字列(バイナリ)情報との間で転置する必要のある大量のデータがある場合は、その処理とメモリが必要になります。

デフォルトでは、serializeとで使用するPHPの組み込みシリアル化ですunserialize。PHPには、2つのデフォルトのシリアル化タイプがあります。他の拡張機能も同様のものを提供します。関連する質問:

ある種のシリアル化が必要であり、非シリアル化がボトルネックであるとおっしゃっていたので、 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と。次に比較します。収集するときに更新された情報を質問に残しておくと、問題が解決しない場合に備えて追加の提案を行うことができます。

頭に浮かぶもう1つのことは、Json形式を使用することです。一部のデータストアはそれに最適化されているため、ストアに直接クエリを実行できます。また、map-reduce手法は、これらのデータストアの多くで使用できるため、データの処理を分散させることができます。serializeこれは、 /でまっすぐにunserialize理解できないことです。これは、常に一度に1つの大きなデータのチャンクを処理するため、違いはありません。

于 2012-10-27T13:39:19.573 に答える
2

内部phpシリアル化のより良い代替手段はMessagePackです:http://msgpack.org/

より速く、より小さく、ほとんどすべての言語をサポートしています。

php拡張機能はpecl(pecl install msgpack-beta)にあります。

かなり大きなオブジェクト(phpで75Mシリアル化)の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のシリアル化よりも明らかに優れていますが、それでも、unserializeのパフォーマンスは説明したほど悪くはありませんでした。

于 2012-10-27T14:54:11.683 に答える