2009-07-27 9 views
10

Ho un oggetto complesso che creo in uno script PHP. Sto cercando un modo per archiviare questo oggetto in modo tale che le richieste successive non debbano ricrearlo o sprecare tempo per la serializzazione e la ricostruzione. Usando xdebug trovo che trascorro la metà dell'intera richiesta di tempo per costruire questo oggetto. Anche quando immagazzino l'oggetto in modo esplicito in APC (o memcache), il tempo di non serializzarlo e caricare tutte le classi richiede quasi il tempo necessario alla creazione dell'oggetto.Oggetto cache in PHP senza utilizzo di serializzazione

Non so se è possibile archiviare e successivamente caricare un oggetto "compilato" in PHP. È possibile? Ci sono altre soluzioni?

Non sono sicuro che sia possibile, ma ho pensato di chiedere alla comunità.

MODIFICA: l'oggetto è un albero binario e viene utilizzato come albero decisionale. Il codice è fondamentalmente un'API richiesta per restituire rapidamente una risposta dall'albero. Tutto ciò ha bisogno di esibirsi a un ritmo sempre crescente, quindi cerco di massimizzare le prestazioni laddove possibile.

+0

Non che questo sia un modo per farlo 'senza' serializzare. Ma potrebbe voler esaminare i metodi __sleep() e __wakeup() in modo che possa ricostruire automagicamente la classe. http://us3.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep –

+0

@Chacha Grazie per queste informazioni. Non sono sicuro che sia una soluzione, ma ho sicuramente imparato qualcosa di nuovo da questo! Grazie. –

+3

La memorizzazione di un oggetto, per definizione, richiede la serializzazione. Se hai davvero bisogno di un accesso ripetuto e rapido a un grande albero binario in memoria, uno script PHP richiamato su ogni richiesta non è la soluzione giusta. –

risposta

9

per quanto io sappia, non è possibile gli oggetti di cache in PHP senza serializzazione. in generale, comunque, meccanismi di caching (APC, Memcache, ecc.) Stanno davvero cercando di rimuovere le connessioni db più che migliorare le prestazioni (e quindi diminuire lo sforzo complessivo del DB). Questo è sicuramente come memcache, et al sono emp matto per quanto riguarda Drupal. In altre parole, i meccanismi di memorizzazione nella cache dovrebbero consentire la scalabilità, anche se potrebbero non migliorare in particolare le prestazioni.
L'implementazione di un meccanismo di memorizzazione nella cache dovrebbe consentire di scalare più facilmente verso l'esterno, anche se le prestazioni per macchina non sono migliori di quelle precedenti per una singola connessione. A una certa soglia, le prestazioni del DB si ridurranno notevolmente e i meccanismi di memorizzazione nella cache dovrebbero contribuire ad alleviare tale problema.

1

NO, non è possibile memorizzare un oggetto PHP in un modulo non serializzato; almeno, non con le seguenti soluzioni di caching (ho provato questi, non conoscono l'altra che potrebbe esistere):

  • file
  • memcached
  • APC
  • Database (yeap, si può pensare di caching cose nel DB ^^ Drupal lo fa di default, per esempio)

Se ci vuole più di tanto ti per annullare la serializzazione del tuo oggetto, forse è davvero grande? C'è un modo per ridurne le dimensioni?

Per esempio, hai un sacco di codice HTML in quell'oggetto? In tal caso, potrebbe essere memorizzato in un'altra voce della cache?
(serializzazione è "trasformare alcuni dati in una stringa, quindi, se si sta già lavorando con una stringa, non c'è bisogno di ri-serializzare per memorizzarlo nella cache)

O forse è doesn 't vuole molto tempo per creare da zero? in questo caso, è il caching davvero necessario?

+0

BTW, Wordpress non memorizza nella cache di default nulla. Quindi, sì è possibile memorizzare nella cache nel database. –

+0

L'oggetto non memorizza alcun html o informazioni extra. La domanda afferma che è molto costoso creare da zero, e questo è l'intero obiettivo di "caching" dell'oggetto. –

3

Forse la soluzione è di non costruire un oggetto singolo, massiccio e costoso.

Dato che un'applicazione PHP praticamente inizia da una lavagna pulita su ogni caricamento di pagina, una soluzione che dipende da un singolo oggetto gigante non è adatta al linguaggio. Dal momento che non fai molti dettagli su ciò che il tuo oggetto è &, non posso esserne certo, ma sospetto che non hai davvero bisogno di tutto ciò che l'oggetto fa su ogni pagina caricata. In questo caso, potresti prendere seriamente in considerazione la possibilità di dividerlo in un numero di classi più piccole e semplici che puoi creare in base alle necessità.

6

Cerca nell'estensione PHP Igbinary. È una sostituzione in sostituzione per serializzare e unserialize e potrebbe soddisfare le tue esigenze.

Memorizza gli oggetti in un formato binario anziché in una stringa che riduce l'utilizzo della memoria e diminuisce anche il tempo di serializzazione e non serializzazione degli oggetti.

Sebbene questo processo non venga serializzato, il formato binario può aumentare le prestazioni in modo da rendere questo processo ragionevole per l'utilizzo nell'applicazione.

+0

Dalla mia lettura di Igbinary, non sembra che ciò aumenterà necessariamente le prestazioni. Non vedo alcuna documentazione che dichiari un aumento di velocità, ma solo una diminuzione delle dimensioni degli oggetti serializzati. –

0

in questo caso un'opzione migliore sarebbe scrivere il proprio server.

è facilmente eseguibile in php - e hai già il codice - ma php potrebbe non essere la prima scelta di più quando si tratta di scrivere server.

  • potrebbe diventare il nuovo collo di bottiglia del vostro app (come php non è davvero il multithreading-ready e le richieste vengono risposto in serie)
  • non tutti gli hoster permettono script CLI personalizzato
  • se la vostra decisione modifiche degli alberi, è devi avvisare il tuo server per ricostruire l'albero
2

igBinary è un'estensione utile che può aiutarti a ottenere un processo serialize/unserialize più veloce. Sostituisce il meccanismo di serializzazione standard con uno più intelligente, binario. Se gestisci il tuo server e puoi installarlo, vale la pena provare.

1

se possibile sulla piattaforma scrivere un demone semplice che carica l'albero all'avvio, quindi risponde alle richieste tramite un socket. Il processo del server può biforcare e rispondere alle query senza ricreare l'albero. Scrivere un daemon non è banale, ma molto ben documentato (almeno per C). Non dovresti avere problemi a tradurre questo in PHP usando le estensioni pcntl e posix.

0

Mentre PHP può fornire molte funzionalità dinamiche per vari tipi di dati, queste operazioni non sono magiche e i dati sono ancora memorizzati come tipi di dati nativi di base all'interno di uno zval che è tecnicamente un hash complesso all'interno della zend api nativa . Come qualsiasi altro tipo di dati in qualsiasi lingua, ogni zval esisterà solo per un periodo finito. Per PHP, questo periodo è (al massimo) il periodo di gestione di una richiesta HTTP. In ogni situazione, per fare in modo che questi dati durino più a lungo di una singola richiesta, devono essere convertiti dallo zval originale in qualche altra forma e quindi immagazzinati in qualche modo (questo include tipi complessi come oggetti PHP e tipi di base come iNT). Ciò richiederà sempre la reinizializzazione di ogni zval e quindi la conversione dei dati dal modulo memorizzato in vari tipi di dati PHP all'interno dello zval. Alcuni formati di archiviazione come BSON saranno più veloci delle stringhe serializzate in PHP, ma (almeno fino a ora) questo non fornirà molte delle prestazioni notate in quanto non è affatto vicino alle prestazioni di mantenimento dello zval originale su più richieste. Dovrai comunque serializzare questi dati in qualche modo, passare il tempo di memorizzarli, quindi recuperarli e quindi non serializzarli. Non ci sono soluzioni reali per questo in questo momento.

Si noti che PHP può avere tre diversi ambiti: il SAPI, che avvia e alla fine gestisce tutti gli stati all'interno di ciascuna richiesta; estensioni, che vengono avviate prima dell'inizio di ogni evento di richiesta; e quindi l'ambito dello script che viene avviato da ciascuna richiesta. Tutti i vars di PHP vengono avviati nell'ambito dello script, ma è possibile accedervi sia da estensioni che da SAPI. Ma l'unico scopo che può esistere oltre ogni singola richiesta è il SAPI. In altre parole, un oggetto PHP può essere mantenuto solo su più richieste all'interno del SAPI (un'estensione non può aiutare a questo problema in questo momento), quindi solo un SAPI personalizzato è in grado di mantenere zvals attraverso le richieste.

0

È possibile riscrivere l'app su ReactPHP creando un server Web in un processo PHP a esecuzione prolungata (proprio come Node.js o Web.py). Quindi puoi creare il tuo oggetto grande una volta (all'avvio del server) come variabile globale e accedervi dai gestori di eventi della richiesta.

Problemi correlati