2011-07-02 13 views
12

Un poco más de detalle: ya estamos tratando de aprovechar al máximo los zipmaps, ziplist, etc., y me pregunto si estas representaciones ya están comprimidas, o solo son hashes y listas serializadas; ¿La compresión reduce significativamente el uso de la memoria?Comprimir cadenas antes de ponerlas en redis: ¿tiene sentido?

Además, ¿la sobrecarga de compresión en la capa del servidor de aplicaciones se compensa con un menor uso de la red? StackOverflow's experience sugiere que lo haga, ¿alguna otra opinión?

En resumen, ¿tiene sentido, para cuerdas cortas y largas?

Respuesta

2

Los redis y los clientes suelen estar vinculados a IO y los costos de IO son típicamente de al menos 2 órdenes de magnitud con respecto al resto de la secuencia de solicitud/respuesta. Las cargas más pequeñas le proporcionarán un mayor rendimiento y menores latencias.

No creo que haya reglas duras y rápidas más allá de: cost of compression << IO gains. Debes ponerlo en un banco y encontrar el punto de sudor al establecer el límite inferior, pero el MTU de tu red no es un mal punto de partida para el límite inferior.

+1

He encontrado [este punto de referencia] (http://dev.mensfeld.pl/2013/04/compressing-large-data-sets-in-redis-with-gzip-ruby-test-case/) muy útil y [estos pensamientos adicionales] (http://nosql.mypopescu.com/post/46926679137/compressing-large-data-sets-in-redis-with-gzip) también. – robert4

14

Redis no comprime sus valores, y si debe comprimirlos usted mismo depende mucho del tamaño de las cadenas que va a almacenar. Para cadenas grandes, cientos de K's y más, probablemente valga la pena los ciclos extra de CPU en el lado del cliente, al igual que cuando se prestan servicios a páginas web, pero para cadenas más cortas es probable que sea una pérdida de tiempo. Las cuerdas cortas generalmente no comprimen mucho, por lo que la ganancia sería demasiado pequeña.

+0

Entonces, para algo que es de aproximadamente 10K, dices no comprimir, ¿estoy en lo cierto? ¿Qué pasa con un caso específico, donde tiene mucho contenido que es consistentemente de 2 a 5 K de JSON, gzipping de bajo nivel debería recortar la huella de memoria de esos por un factor de 2 como mínimo, especialmente si esos terminan representados como zipmaps ? O estoy equivocado – Hristo

+0

Si puede disminuir el tamaño de sus cuerdas por un factor de dos, entonces por supuesto, debe comprimirlas. Lo que estoy diciendo es que no es del todo seguro que obtendrá suficiente compresión en cadenas pequeñas. Dependiendo del contenido de las cadenas, 2-5K puede ser demasiado bajo.XML se comprime muy bien debido a los nombres de etiquetas repetidos, pero los datos de imagen en JPEG, GIF o PNG no se comprimen del todo ya que ya está comprimido, otros tipos de datos tienen otras propiedades. Pruebe cargar datos sin comprimir y observe el uso de memoria ('redis-cli info | grep used_memory') y luego con datos comprimidos. – Theo

6

Hay una forma práctica de conseguir una buena compresión, incluso para muy pequeñas cadenas (50 bytes!) -

Si sus valores son algo similares entre sí - por ejemplo, son representaciones JSON de unos pocos relacionados clases de objetos: puede precomputar un diccionario de compresor/descompresor basado en algún texto de ejemplo.

Suena complicado, pero es simple en la práctica, y aún más simple con el código de envoltura correcto para manejarlo.

Aquí hay una implementación de Python:

https://github.com/internetarchive/openlibrary/blob/master/openlibrary/utils/compress.py

y aquí es un envoltorio para la compresión de una clase específica de cadenas: (registros JSON cortas)

https://github.com/internetarchive/openlibrary/blob/master/openlibrary/utils/olcompress.py

un problema: para hacer esto de manera eficiente, su biblioteca de compresión debe admitir 'clonación' del estado interno. (La biblioteca de Python sí) Puede implementar algo similar anteponiendo el texto de ejemplo al comprimir, pero esto significa pagar un costo de cálculo adicional.

Gracias a solrize por este increíble truco.

Cuestiones relacionadas