Un altro approccio (che non ho provato, ma sembra molto interessante) è quello di sfruttare opcache come cache dei valori chiave. Questo post graphiq contiene più dettagli ma purtroppo nessun codice reale (e si noti i commenti di Kerry Schwab).
Il primo è assicurarsi che l'opcache sia abilitato e abbia abbastanza memoria allocata per i dati che è necessario memorizzare nella cache e quindi qualcosa sulla falsariga di quanto segue (sollevato dall'articolo, verificarlo per esteso) . La scadenza della cache (oltre alla cancellazione manuale) dovrebbe essere gestita anche, ma non sarebbe difficile da aggiungere (ad esempio, avvolgere i dati in un oggetto contenente con una scadenza e controllarli nel tuo cache_get
, eliminando e ignorando il record se è scaduto).
function cache_set($key, $val) {
$val = var_export($val, true);
// HHVM fails at __set_state, so just use object cast for now
$val = str_replace('stdClass::__set_state', '(object)', $val);
// Write to temp file first to ensure atomicity
$tmp = "/tmp/$key." . uniqid('', true) . '.tmp';
file_put_contents($tmp, '<?php $val = ' . $val . ';', LOCK_EX);
rename($tmp, "/tmp/$key");
}
function cache_get($key) {
@include "/tmp/$key";
return isset($val) ? $val : false;
}
causa della opcache questo funzioni come nella memoria cache, ma evita il sovraccarico di serializzazione e deserializzazione. Immagino che il cache_set dovrebbe anche chiamare opcache_invalidate
durante la scrittura (e nella funzione cache_delete
che non esiste nei loro esempi) ma altrimenti sembra un suono per una cache che non ha bisogno di essere condivisa tra i server.
Modifica: un'implementazione di esempio con scadenza cache (solo precisione su un secondo, potrebbe utilizzare microtime(true)
se è richiesta una maggiore precisione) di seguito. I test minimi hanno effettivamente funzionato e ho abbandonato la sostituzione specifica HHVM, quindi YMMV. Suggerimenti per miglioramenti graditi.
class Cache {
private $root;
private $compile;
private $ttl;
public function __construct($options = []) {
$this->options = array_merge(
array(
'root' => sys_get_temp_dir(),
'ttl' => false,
),
$options
);
$this->root = $this->options['root'];
$this->ttl = $this->options['ttl'];
}
public function set($key, $val, $ttl = null) {
$ttl = $ttl === null ? $this->ttl : $ttl;
$file = md5($key);
$val = var_export(array(
'expiry' => $ttl ? time() + $ttl : false,
'data' => $val,
), true);
// Write to temp file first to ensure atomicity
$tmp = $this->root . '/' . $file . '.' . uniqid('', true) . '.tmp';
file_put_contents($tmp, '<?php $val = ' . $val . ';', LOCK_EX);
$dest = $this->root . '/' . $file;
rename($tmp, $dest);
opcache_invalidate($dest);
}
public function get($key) {
@include $this->root . '/' . md5($key);
// Not found
if (!isset($val)) return null;
// Found and not expired
if (!$val['expiry'] || $val['expiry'] > time()) return $val['data'];
// Expired, clean up
$this->remove($key);
}
public function remove($key) {
$dest = $this->root . '/' . md5($key);
if (@unlink($dest)) {
// Invalidate cache if successfully written
opcache_invalidate($dest);
}
}
}
provato con memcached? – Thamilan
@Thamizhan Bene, memcached e redis sono un po 'qualcos'altro. Sto chiedendo la cache di memoria PHP, che ha una latenza molto inferiore rispetto all'utilizzo di quei due (anche su localhost). – Frodik
Qual è la differenza di latenza? L'hai controllato? Non sembra una cosa di cui dovresti preoccuparti. –