variable una terminar sesion ini_set how destruir comprobar close capturar php memcached

php - terminar - Compruebe si existe una clave en Memcache



php session close (11)

¿Cómo verifico en PHP si un valor está almacenado en Memcache sin recuperarlo? No me gusta buscarlo porque los valores que he establecido tienen un tamaño de 1 MB y, después de recuperarlos, no tengo ningún uso, así que estoy desperdiciando recursos. Estoy usando esto en una secuencia de comandos que comprueba si ciertas claves se almacenan en caché en memcache y, si no, las lee de una fuente de datos lenta y las establece en memcache.

Editar: ¿Qué Memcached::append si uso Memcached::append para agregar NULL a la clave que estoy marcando? Devuelve TRUE en caso de éxito o FALSE en caso de error. Memcached::getResultCode devolverá Memcached::RES_NOTSTORED si la clave no existe. De esta manera, compruebo si existe la clave y debería colocar la clave en la parte superior de la lista de LRU, ¿no?

Gracias.


(un poco tarde para la discusión, pero) en realidad puede acceder a todas las claves / valores almacenados en el memcache, por:

$allSlabs = $memcache->getExtendedStats(''slabs''); $items = $memcache->getExtendedStats(''items''); foreach ($allSlabs as $server => $slabs) foreach ($slabs as $slabId => $slabMeta) foreach ($memcache->getExtendedStats(''cachedump'', (int) $slabId) as $entries) if (!empty($entries)) foreach ($entries as $key => $entry)


Básicamente, lo que quieres hacer es llenar memcached con tus datos, ¿verdad?

La cuestión es que preguntar si hay una clave allí sin recuperar el valor no es muy útil. Ver este escenario de caso:

Usted pregunta si existe una clave y lo hace. Justo después de preguntar, los datos de la clave se expulsan del caché. Si bien su respuesta regresa diciendo que la fecha está ahí, la realidad es que los datos no están allí. Así que perdiste el tiempo preguntando, porque la respuesta es diferente de la realidad.

Supongo que lo que quieres hacer es preguntar si existe una clave y, si no es así, rellenarla con tus datos. ¿Por qué no rellenas directamente todos los datos? Por cierto, ¿ha considerado que mientras está llenando memcached con datos, podría estar expulsando claves que acaba de insertar?


Esto no tiene sentido desde la perspectiva de Memcached. Si desea evitar la fuente de datos lenta (por un trabajo programado, ¿supongo?), Guarde los datos en una fuente de datos más rápida pero estable (por ejemplo, un archivo) en su trabajo programado. Cuando necesite los datos, intente leer primero desde Memcached, y si eso falla, lea el archivo y guárdelo en Memcached.

Memcached no puede darte una buena respuesta, ya que pakore ya respondió. La arquitectura no pretende ser una fuente de datos estable.


He resuelto esto utilizando Memcached :: append. Intento agregar el valor NULL y si devuelve VERDADERO, significa que la clave existe. Si devuelve FALSE significa que la clave no existe. Si existe la clave, también la pondrá en la parte superior de la lista LRU.


La forma más fácil es obtener la clave dada y convertirla en un valor booleano.

(bool) Memcache::get(string $key)


Me pregunto por qué Memcached no tiene un método especial para ello. Aquí está lo que vine después de algunas consideraciones:

function has($key) { $m->get($key) return /Memcached::RES_NOTFOUND !== $m->getResultCode(); }


Necesitaba una prueba confiable para saber si usar Memcache Set o memcache replace.

Esto es con lo que terminé.

Otra opción sería configurar un socket de red para la consulta de memcache, pero al final terminará haciendo lo mismo y esta conexión ya existe, ahorrándome la sobrecarga de hacer y mantener otra conexión como en la respuesta de Joel Chen.

$key = ''test''; $value = ''foobarbaz''; /** * Intricate dance to test if key exists. * If it doesn''t exist flags will remain a boolean and we need to use the method set. * If it does exist it''ll be set to integer indicating the compression and what not, then we need to use replace. */ $storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED); $flags = false; $memcache->get($key, $flags); if(false === $flags) { $memcache->set($key, $value, storageFlag , $minutes); } else { $memcache->replace($key, $value, storageFlag, $minutes); }

Ahora bien, si tiene "datos grandes", la solución es bastante simple. Use una segunda clave en cojoin que contenga algo simple como un entero para verificar. Siempre úsalos juntos y no tendrás problemas.

$key = ''test''; $value = ''foobarbaz''; $storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED); $flags = false; $exist_key = $key.''_exists''; $memcache->get($exist_key, $flags); if(false === $flags) { $memcache->set($key, $value, storageFlag , $minutes); $memcache->set($exist_key, 42, false , $minutes); } else { $memcache->replace($key, $value, storageFlag, $minutes); $memcache->replace($exist_key, 42, false , $minutes); }


No estoy seguro de si esto es de alguna ayuda para usted, pero puede usar

Memcache::add ( string $key , mixed $var)

Devolverá false si la clave ya existe.

En caso de que se devuelva true, puede usar

Memcache::delete ( string $key)

para eliminar la clave que acaba de configurar. De esa manera no necesitarás buscar los datos.


No me gusta la sugerencia de agregar / eliminar porque inserta datos no válidos de los que su aplicación puede depender. Si su aplicación hace esta suposición, causaría un error sutil que ocurre cada cierto tiempo debido a la condición de carrera que introduce.

Una solución es echar un vistazo al valor y si sus datos temporales pretenden que no está allí, pero eso requeriría que todos los códigos de la aplicación usen la misma API o que necesitaría actualizar la aplicación en sí, ni son divertidos y son propensos a errores. Debido a la complejidad adicional.

Si el conjunto de claves es lo suficientemente pequeño, puede almacenarlo en memcached y usarlo para determinar si recuperar o no los datos de la fuente nuevamente. Sin embargo, si es tan grande o grande el valor, este método es peor que solo obtener el valor completo de memcached.

Luego, puede resolver el nuevo problema utilizando un índice para separar sus claves en conjuntos más pequeños (por supuesto, una buena manera de fragmentar estos datos para que cada grupo tenga un tamaño determinado es más fácil decirlo que hacerlo).

La implementación consistiría en el uso de memcached append o prepend para mantener su lista de claves vinculadas a alguna clave maestra o una clave maestra que apunta a un conjunto de subclave que apunta a las propias claves :)

De cualquier manera, la aplicación es cada vez más compleja, por lo que solo recomendaría hacer esto si existe un cuello de botella (como si hubiera que verificar la existencia de las claves a menudo a través de una red), o si la facilidad de uso en Una preocupación (latencia).

En mi caso, no lo haré porque solo voy a acceder a memcached a través de localhost y lo estoy utilizando como una extensión más de mi aplicación para almacenar en caché los recursos que tardan más de unos segundos en cargarse normalmente.


Simplemente no es posible, no es posible verificar si la clave existe o no. Mejor cree una clave separada con valores verdaderos / falsos para verificar la existencia de claves


memcached ahora tiene el comando cas. puede usarlo con un cas único como 0 para obtener las respuestas EXISTS o NOT_FOUND:

$ telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. Escape character is ''^]''. set hello 0 0 5 12345 STORED gets hello VALUE hello 0 5 6743 12345 END cas hello 0 0 0 0 EXISTS cas foo 0 0 0 0 NOT_FOUND

En la transcripción anterior, primero uso el comando set para establecer una clave hola con el valor 12345. Luego se recupera, lo que también devolvió un cas único 6743. Luego trato de usar el comando cas para reemplazar el valor con nada, pero debido a que Cas único que utilicé es 0, volví al error EXISTS.

Finalmente, trato de usar cas para establecer una clave foo que no existe y obtengo el error NOT_FOUND.

Debido a que memcached usa un valor incremental global para cas único, usar 0 es seguro que no es válido para el elemento que está tratando de establecer y obtendría un error EXISTS si existiera.

Lo sentimos, no estoy familiarizado con el cliente de memcache de php para ponerlo en código php.