2012-10-27 26 views
3

的狀況(高達每客戶端請求共100MB的數據):用PHP管理大量數據的最快方法?

  • 我有包含多個複雜的對象的多個陣列,每一個都存儲不同的數據,但在相同的格式。
  • 現在,這些數組(包含對象)太複雜,無法存儲在sql表中,所以我將它們序列化,並將每個數組存儲在單獨的文件中。
  • 我使用PHP函數file_get_contents()讀取數據,然後我用數據上的unserialize()
  • 我必須爲每個客戶端請求加載一個文件(最大100mb)並'unserialize()'並對其進行處理。
  • 這個數據是不一樣的每個客戶端
  • 所有數據總共大約3GB。
  • 此數據每24小時更新一次,並且每次更新的數據量都會增加。
  • 每個文件的最大數據量爲100MB。

問題:

  • 的方法我目前使用的作品適合於小文件大小(高達5MB)。
  • 但是,當涉及到更大的文件大小,它花費了太多的時間。
  • 功能unserialize()大約需要33秒執行,如果我嘗試加載大小約爲40mb的文件。
  • 所以我現在的方法的主要問題是unserialize()

的主要問題:

  • 我如何保存我非常複雜的對象,而它們的序列化,或者我怎樣才能讓我的反序列化速度更快?
+2

你可以嘗試更好地解釋這種情況。你的序列化是什麼?爲什麼? – Gordon

+1

這是一個有趣的問題,但正如戈登所說 - 你能給我們提供更多的信息嗎?您是否反序列化您通過file_get_contents獲取的數據?您是在同一臺機器上抓取的文件還是通過file_get_contents遠程抓取它們? –

+2

如果序列化是你的瓶頸,請切換到[igbinary serialization](http://pecl.php.net/package/igbinary),它的速度更快。否則,請採用不需要將所有數據都拉入到php內存空間的文件格式(例如sqlite或xml)。但這正是@戈登所要求的。小心輕放。 – hakre

回答

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,這是不能改變的。

2

爲內部PHP序列一個更好的選擇將MessagePack:http://msgpack.org/

這是更快,更小,具有幾乎任何語言的支持。

你可以找到PECL(pecl install msgpack-beta

我做了一個簡單的基準來比較PHP內部系列化,信息包和JSON的(在php序列化75M)相當大的物體PHP擴展。 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的序列化更好,但即使所以,反序列化並沒有像你描述的那樣糟糕。

+1

有趣,不知道msgpack。但是,反序列化似乎代價很高。序列化看起來不錯。 – hakre

相關問題