¿Para qué casos de uso es adecuado o no adecuado Redis en una aplicación web de alto tráfico a principios de 2016?

Los principales beneficios de Redis son la velocidad y la funcionalidad. Redis es casi tan rápido como memcache (solo aproximadamente 0.1 ms más lento que memcache en el percentil 99 de latencia para recibir llamadas) y proporciona una amplia variedad de funciones de estructura de datos que lo extienden mucho más allá de un simple almacén de valores clave.

Sin embargo, Redis tiene algunas limitaciones que guiarán este análisis:

  • Cada instancia de Redis tiene un solo subproceso. Esto significa que las consultas individuales que llevan mucho tiempo no son recomendables, ya que bloquearán otras consultas a la misma instancia de Redis hasta que se completen.
  • El tamaño del conjunto de datos está limitado por la memoria disponible en la máquina en la que se ejecuta el servidor.

En un escenario de alto tráfico y gran conjunto de datos, casi seguramente tendremos que usar una instancia fragmentada para sortear estos límites. Redis se puede dividir de diferentes maneras (por ejemplo, utilizando Redis Cluster o twemproxy), pero muchos comandos de varias teclas no están disponibles a menos que el conjunto de datos esté cuidadosamente organizado y se usen claves de fragmentos, y la velocidad puede degradarse ya que se requiere más tráfico de red para ejecutar cualquier mando. Incluso en un entorno fragmentado, las consultas lentas bloquearán la ejecución de otras consultas en el mismo fragmento, por lo que aún debemos ser cuidadosos.

Estas limitaciones significan que querremos usar Redis para datos estructurados de manera bastante simple que requieran un acceso rápido y no sean demasiado grandes. Redis se puede usar como caché con desalojo automático, como memcache, pero en Quora lo usamos como un almacén de datos persistente al deshabilitar el desalojo y guardar el conjunto de datos en el disco varias veces al día en las instancias esclavas. Algunos casos de uso que hemos desarrollado:

  • Almacenar pequeñas cantidades de datos en una dimensión; por ejemplo, el último tiempo de acceso para cada usuario. Redis funciona bien aquí porque cada clave es muy pequeña (solo un número entero) e incluso con un billón de usuarios, todos los datos para estas claves caben fácilmente en la memoria de una máquina.
  • Almacenar pequeñas cantidades de datos en dimensiones cero; por ejemplo, estado entre ejecuciones de un trabajo cron. Tenemos algunos crons que iteran sobre los usuarios, las preguntas y las respuestas creadas más recientemente, por lo que almacenamos la ID máxima examinada para cada uno de estos en Redis. También almacenamos información de monitoreo en Redis (por ejemplo, el último tiempo de verificación para varios servicios en nuestra infraestructura).
  • Almacenar estado temporal que requiere acceso rápido; por ejemplo, las vistas de contenido más recientes. Almacenar todas las vistas de contenido en Redis para siempre sería ineficiente; muchos de estos valores se usan muy raramente y no necesitamos un acceso súper rápido a ellos. Almacenamos los recuentos de la vista de la verdad del terreno en HBase, pero es difícil para HBase manejar la carga causada por el aumento de los recuentos para cada vista en tiempo real. Por lo tanto, almacenamos las vistas en Redis y las volcamos cada minuto a HBase, agrupando los incrementos individuales en incrementos más grandes y reduciendo drásticamente la carga de escritura de HBase. (Consulte la Ingeniería del producto detrás de los escritores más vistos para obtener más información sobre el canal de vistas).

No queremos usar Redis para casos de uso como estos:

  • Almacenar grandes cantidades de datos en un solo valor de cadena (por ejemplo, los contenidos de feed más recientes para cada usuario). Esto significa que las consultas en estas teclas serán lentas, lo que bloqueará otras consultas y, por lo tanto, ralentizará a todos los clientes.
  • Almacenar datos en dos o más dimensiones (por ejemplo, una puntuación para cada par (usuario, tema)). El tamaño del conjunto de datos para estas claves probablemente crecerá de forma superlineal con el resto del conjunto de datos, y tendremos que buscarlo demasiado pronto.
  • Almacenar datos que requieren consultas con alta complejidad de tiempo. Usar una lista Redis como cola está bien (las consultas al final de la lista toman tiempo constante), pero si la lista es larga, las consultas que operan lejos de los extremos de la lista o en toda la lista serán muy lentas. Algunos comandos tienen una complejidad de tiempo incondicionalmente alta (por ejemplo, SMEMBERS, HGETALL, KEYS) y queremos evitarlos por completo.
  • Almacenar datos que requieren rutas de acceso secundarias. Redis no tiene índices secundarios ya que es un almacén de valores clave, por lo que tendríamos que implementarlos en el cliente, y usarlos requeriría múltiples consultas al servidor.

En un entorno de alto tráfico, hay algunas cosas a tener en cuenta que no son obvias a menor escala. Para nombrar unos pocos:

  • El comando DEL puede ser lento. DEL no regresa hasta que se libera toda la clave, lo que puede tomar varios segundos si se trata de una lista o conjunto grande (> 1 GB más o menos). Para evitar esto, podemos usar LPOP / SPOP para iterar destructivamente la lista / conjunto. Esto es mucho más lento en el lado del cliente y requiere mucho más tráfico de red, pero se pueden ejecutar otras consultas mientras lo hacemos. Eliminar una gran cantidad de claves en una sola llamada DEL también es desaconsejable. (Redis 4.0 admite UNLINK, que soluciona este problema).
  • Los scripts de Lua son atómicos, pero bloquean otras consultas mientras se ejecutan. Las secuencias de comandos que funcionan en varias claves también pueden fallar en un entorno fragmentado si las claves no están todas en el mismo fragmento. Evitamos scripts complejos por estos motivos; generalmente limitamos nuestros scripts para operar exactamente en una clave y tener una complejidad de tiempo hasta lineal en la longitud del valor de la clave (aunque esto también podría decirse que es peligroso).
  • El guardado en segundo plano puede ralentizar notablemente la instancia, y el uso de la memoria aumentará lentamente hasta que esté hecho, debido a la semántica de copia en escritura de la bifurcación de Unix (). Si tenemos habilitado el sobrecompromiso de VM, no podemos permitir que el uso de memoria de nuestra instancia de Redis se acerque a la cantidad de memoria instalada, o no podremos guardar el conjunto de datos sin usar memoria virtual.
  • La paginación de memoria virtual ralentiza a Redis y es inaceptable en un entorno de producción. Evitamos usar el disco en absoluto.
  • Si utilizamos un enfoque de fragmentación basado en proxy, la reorganización es difícil y costosa. Escribimos un proxy de replicación en Quora que permite que un clúster fragmentado de Redis se replique desde otro clúster fragmentado con un número diferente de fragmentos, pero es mucho más lento que la replicación estándar: lleva casi un día sincronizar todo nuestro conjunto de datos a un nuevo clúster.

En resumen, Redis es apropiado para datos pequeños y simples que requieren un acceso rápido, pero en la mayoría de los entornos deben estar respaldados por otro almacén de datos más lento y menos costoso. En AWS, los datos almacenados en la memoria son aproximadamente 25 veces más caros que los datos almacenados en el disco, por lo que en Quora, utilizamos Redis como un almacén de datos independiente solo para datos sensibles al rendimiento, y preferimos MySQL o HBase para datos que pueden tolerar una mayor latencia de acceso .

Redis proporciona aproximadamente cuatro tipos de servicio:

  1. Almacenamiento en caché
  2. Almacenamiento
  3. Colas y autobuses de servicio
  4. Descarga de procesamiento limitada (clasificación, operaciones de conjuntos, secuenciación, secuencias de comandos Lua)

El primero, más obvio, es el almacenamiento en caché . Asocia algún valor con una clave y, opcionalmente, con un tiempo de vencimiento. Normalmente, configuraría sus instancias de Redis de almacenamiento en caché para renunciar a cualquier persistencia (sin guardar los datos en el disco o registrar cada cambio) y lo configurará para algún tipo de política de desalojo (de modo que, cuando las instancias estén en su parte superior umbral de utilización de la memoria, aceptará los nuevos datos y descartará algo (por lo general, el elemento (s) LRU más antiguo o menos utilizado recientemente).

En este sentido, Redis puede ser muy similar a memcached. La principal diferencia es que memcached está diseñado para distribuirse de forma transparente en varias instancias. Sus clientes manejan automáticamente el hash constante de las claves para distribuir la carga en varios sistemas. (Redis 3.0 y las bibliotecas de cliente que se actualizan para usarlo también pueden proporcionar estas características, pero son más complicadas por el hecho de que Redis también se puede usar para fines distintos al almacenamiento en caché).

Una forma de usar Redis para el almacenamiento en caché es hacer que cada uno de sus servidores web también aloje una instancia de Redis. Configure los clientes para que realicen sus solicitudes de caché en la instancia local y, tal vez, recurran a otras instancias si eso no está disponible. Los servidores web a menudo tienen más memoria de la que necesitan para su aplicación … por lo que tiene sentido usar la memoria “extra” para el almacenamiento en caché. (Los sistemas operativos adecuados y modernos ya usan la mayor parte de su memoria disponible para el almacenamiento en caché del sistema de archivos, pero eso es independiente del almacenamiento en caché de datos específicos de la aplicación de la que estamos hablando en Redis; en infraestructuras modernas en niveles con servidores web dedicados que en su mayoría representan plantillas en páginas web dinámicas, el caché del sistema de archivos puede tener un valor limitado en comparación con el caché de datos de una aplicación).

Por varias razones, es preferible tener un proceso de caché de larga ejecución en un sistema con los subprocesos y procesos de la aplicación (generalmente no tan largo) que intentar almacenar los datos directamente en la memoria de la aplicación. (Entre otras cosas, que permite que el servidor web elimine los procesos y subprocesos de trabajo mientras se preserva la memoria caché … y permite que todos los procesos de trabajo compartan la memoria caché, incluidos los procesos distribuidos en varios sistemas).

En un lugar donde trabajé, tenían una pequeña cantidad de servidores Redis muy grandes (y cada uno tenía un par de esclavos. Esto fue antes de Redis 3.x con soporte de agrupación. El primer problema fue que una falla de cualquier servidor Redis causa un retraso inmediato en su juego mientras el sistema fallaba a uno de los esclavos. El mayor problema era que la falla de un fragmento Redis (maestro y sus esclavos) causaría una interrupción en todo el juego. En otras palabras, la carga en la base de datos sin el almacenamiento en caché era simplemente demasiado alto. Es por eso que recomiendo escalar su número de instancias de almacenamiento en caché de Redis lineales con su número de servidores de aplicaciones (nivel intermedio) o web (front-end).

El problema era que tenían muchas instancias de Redis en cada servidor … porque cada instancia de Redis tiene un solo subproceso. Intentaban maximizar el uso de la capacidad de cada servidor, con 12 núcleos por servidor.

( Sugerencia : use servidores más pequeños, menos de 8 núcleos cada uno, para Redis; varios servidores pequeños serán mucho más resistentes y ofrecerán un mejor rendimiento que una pequeña cantidad de servidores grandes con muchos procesadores).

Muchas instancias, cada una de las cuales proporciona almacenamiento en caché para menos del 20% de su carga, presentará mucho menos riesgo que cualquier modelo en el que el 30% o más de su sistema dependa de un solo servidor. (El 20% es un número mágico para la planificación de la capacidad … se trata del espacio libre ideal para mantener la carga máxima al menor costo).

El siguiente caso de uso para Redis es como un almacén de datos primario . En este caso, seguramente permitiría la persistencia … posiblemente una combinación sofisticada de almacenamiento de imágenes (RDB) con registro de archivos de solo agregado (AOF). También organizaría alguna forma de replicación y copia de seguridad de esos datos. Además, debe administrar activamente sus datos para asegurarse de que siempre se ajusten a la RAM de sus instancias de Redis.

Además, para Redis 3.x, si desea utilizar Redis como el almacenamiento principal para algunos de sus datos, puede considerar también usar el comando WAIT – Redis para asegurarse de que sus datos se hayan replicado a cierto número de esclavos antes de considerar los datos sean “seguros”. (También puede usar LASTSAVE – Redis para asegurarse de que sus datos se hayan convertido en “duraderos” – guardados en el disco en RDB o como una entrada de AOF. En ese caso, probablemente desearía detalles de todas sus operaciones de “escritura” del cliente Redis en una cola de confirmación (con marcas de tiempo locales en “segundos desde el formulario de época), emita sus propios comandos BGSAVE según corresponda a sus necesidades de durabilidad, y verifique los comandos LASTSAVE y TIME del servidor actual y asegúrese de que LASTSAVE se produjo más tarde que la escritura más reciente operación que está rastreando; si se produce un tiempo de espera local, reproduzca todas las operaciones de escritura locales, por ejemplo).

Por cierto, aquí hay un script rápido de Lua para devolver el TIEMPO (segundos y microsegundos) y LASTSAVE (segundos) en una sola llamada a Redis:

eval “local x = {}; para i, y en pares (redis.call (‘TIME’)) do x [i] = tonumber (y) end; x [3] = redis.call (‘LASTSAVE’); volver x “0

… Eso devolverá tres valores enteros que le permitirán comparar el tiempo relativo desde el guardado hasta el tiempo relativo desde que se enviaron sus escrituras (esto explica cualquier sesgo de reloj entre su cliente y su servidor, aunque es posible que desee alertar o advertir sobre eso por separado).

Si usa Redis tanto para el almacenamiento en caché como para el almacenamiento primario de algunos tipos de datos, colóquelos en instancias separadas. Configure sus aplicaciones con conexiones separadas para el almacenamiento de datos frente al manejo de caché.

Para cualquiera de estos casos de uso, debería considerar usar twitter / twemproxy (cascanueces). Esto puede manejar algunos de los detalles quisquillosos de distribuir sus claves en múltiples “fragmentos” de Redis y mantener conexiones persistentes a los servidores de Redis (y manejar la conmutación por error) de forma transparente a sus bibliotecas / módulos de cliente de Redis.

El siguiente caso de uso común para Redis es como un sistema coherente de colas de mensajes y bus de mensajes.

Para las colas utilizamos los objetos “LISTA” de Redis y los * PUSH y * POP (generalmente en forma de LPUSH y BRPOPLPUSH o mediante Lua personalizada como la descrita por Salvatore en las colas confiables de Redis con secuencias de comandos Lua.

Como bus de mensajes podemos usar las funciones de Pub / Sub de Redis. Mientras que una cola proporciona “como máximo” una semántica de entrega, y las colas confiables se esfuerzan por * exactamente * una entrega … pub / sub proporciona publicación de difusión a múltiples suscriptores para cada canal.

También es posible usar “conjuntos ordenados” como un montón / cola prioritario. Por lo general, usaría “segundos desde la época” como la puntuación para cada elemento agregado al conjunto ordenado (ZADD – Redis) y luego usaría ZRANGE – Redis para mirar la entrada superior (más antigua) y varios otros comandos para eliminar el elemento o ajustar su puntaje (moviéndolo efectivamente al final de la cola, por ejemplo) o moviéndolo a una cola “pendiente”.

Busque en Google: Redis zset “Priority Queue” para encontrar varias discusiones de implementaciones sobre este patrón de uso.

Hay muchos sistemas de colas de mensajes. Redis se encuentra entre las funciones más simples y menos repletas. Para muchos casos, esta falta de características también es una falta refrescante de complejidad.

Existe una complejidad inherente en el manejo confiable de datos a través de cualquier sistema de colas (al igual que, inherentemente, hay problemas complejos relacionados con la invalidación de caché y el almacenamiento confiable de datos). Pero las formas en que varios sistemas dedicados de colas de mensajes intentan manejar la confiabilidad y la semántica de entrega “exactamente una vez” a menudo oscurecen los modos de falla, en lugar de suavizarlos realmente.

El último caso de uso que enumeré es como un servicio remoto para descargar ciertos tipos de procesamiento. El más simple de estos es proporcionar contadores simples y coherentes. Puede tener claves que contengan números enteros y usarlas para proporcionar atómicamente números de secuencia (ID) a sus clientes. Otra es hacer que sus sistemas Redis realicen la clasificación de conjuntos de datos por usted, o realicen operaciones de conjuntos (intersecciones y diferencias), y administren datos con una semántica de acceso tipo “montón”.

Esto se resume en el soporte de Redis para las secuencias de comandos Lua del lado del servidor. Puede usar EVAL y sus posibilidades para enviar un script Lua al servidor, hacer que lo evalúen y que el servidor devuelva sus resultados. Por lo general, el objetivo es proporcionar una semántica personalizada sobre cómo se mueven los datos en el servidor Redis. Por ejemplo, proporcionar bloqueo y confiabilidad en lugar de usar Transacciones complejas.

  • ¿Por qué Redis supera a Memcached por el almacenamiento en caché?
  • Elefantes grandes: agrupación de redis
  • Estoy buscando en Redis, Varnish y MemcacheD para el almacenamiento en caché. ¿Cuáles son sus experiencias personales con cada uno y cuáles recomendaría?
  • carlosabalde / libvmod-redis (habilite Redis como backend de almacenamiento en caché para Varnish)

En este momento, Redis no es la mejor opción para mensajería compleja (no como un AMQP u otro bus dedicado; ciertamente no es una cola distribuida como Apache Kafka. No es la solución adecuada para la gestión coordinada de datos / configuración como Apache) ZooKeeper o Consul o coreos / etcd. No es tan simple escalar horizontalmente como memcached, pero se puede usar para cada uno de estos y es más simple que la mayoría de las alternativas.

Puede utilizar cualquier instancia para todos estos fines (para el desarrollo, por ejemplo). Como se mencionó anteriormente, recomendaría que cree instancias separadas para roles separados (almacenamiento en caché versus almacenamiento principalmente) y tenga cuidado al compartir demasiadas instancias separadas en cualquier rol en el mismo hardware (para la resistencia). (Recomiendo no más de 4 instancias de Redis por servidor … y aún así sugiero que considere seriamente la ubicación conjunta de sus instancias de Redis con otros tipos de carga de trabajo.

Comencemos por responder qué es Redis y en qué se diferencia de otros almacenes de valores clave.

Redis es un almacén de datos de valor de clave SQL sin memoria en código abierto. Es similar a Memcached con dos diferencias principales persistencia incorporada y más tipos de datos .

Redis es diferente a otras soluciones de bases de datos en muchos aspectos: utiliza la memoria como soporte de almacenamiento principal y el disco solo para persistencia.

Los tipos de datos adicionales son probablemente aún más importantes. Los valores clave pueden ser cadenas simples, como las que encontrará en Memcached, pero también pueden ser tipos más complejos como Hashes, Listas (colección ordenada, hace una gran cola), Conjuntos (colección no ordenada de valores no repetidos) u Ordenado Conjuntos (colección ordenada / clasificada de valores no repetidos).

Vea este hilo de desbordamiento de pila para más detalles ¿Qué es Redis y para qué lo uso?


Casos de uso adecuados para Redis

¿Para qué se puede usar Redis? Pocos ejemplos de http://highscalability.com/blog/ …:

  1. Muestra los últimos listados de artículos en tu página de inicio. Este es un caché en memoria en vivo y es muy rápido. LPUSH se utiliza para insertar una ID de contenido en la cabecera de la lista almacenada en una clave. LTRIM se usa para limitar el número de elementos en la lista a 5000. Si el usuario necesita avanzar más allá de este caché, entonces se envían a la base de datos.
  2. Eliminación y filtrado. Si se elimina un artículo almacenado en caché, se puede eliminar de la memoria caché utilizando LREM.
  3. Tablas de clasificación y problemas relacionados. Una tabla de clasificación es un conjunto ordenado por puntuación. Los comandos ZADD implementan esto directamente y el comando ZREVRANGE puede usarse para obtener los 100 mejores usuarios por puntaje y ZRANK puede usarse para obtener un rango de usuarios. Muy directo y fácil.
  4. Ordenar por votos y tiempo del usuario. Esta es una tabla de clasificación como Reddit donde el puntaje es la fórmula de los cambios a lo largo del tiempo. LPUSH + LTRIM se utilizan para agregar un artículo a una lista. Una tarea en segundo plano sondea la lista y vuelve a calcular el orden de la lista, y ZADD se utiliza para completar la lista en el nuevo orden. Esta lista se puede recuperar muy rápido incluso en un sitio con mucha carga. Esto debería ser más fácil, la necesidad del código de sondeo no es elegante.
  5. El implemento caduca en los artículos. Para mantener una lista ordenada por tiempo, utilice el tiempo de Unix como clave. La difícil tarea de expirar elementos se implementa indexando current_time + time_to_live. Otro trabajador en segundo plano se utiliza para realizar consultas con ZRANGE … con PUNTUACIONES y eliminar entradas con tiempo de espera agotado.
  6. Contando cosas. Mantener estadísticas de todo tipo es común, digamos que desea saber cuándo bloquear una dirección IP. El comando INCRBY facilita mantener atómicamente los contadores; GETSET para despejar atómicamente el mostrador; el atributo expire puede usarse para indicar cuándo se debe eliminar una clave.
  7. N elementos únicos en un período de tiempo determinado. Este es el problema único de los visitantes y se puede resolver utilizando SADD para cada visita a la página. SADD no agregará un miembro a un conjunto si ya existe.
  8. Análisis en tiempo real de lo que está sucediendo, para estadísticas, antispam o lo que sea. Con las primitivas de Redis es mucho más sencillo implementar un sistema de filtrado de spam u otro sistema de seguimiento en tiempo real.
  9. Pub / Sub. Mantener un mapa de quién está interesado en las actualizaciones de qué datos es una tarea común en los sistemas. Redis tiene una función de pub / sub para facilitar esto usando comandos como SUBSCRIBE, UNSUBSCRIBE y PUBLISH.
  10. Colas Las colas están en todas partes en la programación. Además de los comandos de tipo push y pop, Redis tiene comandos de bloqueo de cola para que un programa pueda esperar a que otro programa agregue el trabajo a la cola. También puede hacer cosas interesantes para implementar una cola rotativa de canales RSS para actualizar.
  11. Almacenamiento en caché. Redis se puede usar de la misma manera que memcache.
  12. Caché de sesión: uno de los casos de uso más aparentes para Redis es usarlo como caché de sesión. Las ventajas de usar Redis sobre otros almacenes de sesiones, como Memcached, es que Redis ofrece persistencia. Si bien el mantenimiento de un caché no suele ser crítico para la misión con respecto a la consistencia, la mayoría de los usuarios no disfrutarían exactamente si todas sus sesiones de carrito desaparecieran, ¿verdad?

Este artículo explica claramente con la ayuda de ejemplos algunos de los casos de uso más comunes para Redis.

Redis hace que su aplicación se ejecute más rápido y más fácil de programar, ya que los tipos de datos que utiliza se corresponden mejor con los conceptos de su programa.

Muchas grandes empresas están utilizando Redis para escalar sus sitios web a millones de usuarios. Pinterest es un muy buen ejemplo que utiliza Redis para administrar miles de millones de relaciones.

Usando Redis en Pinterest para miles de millones de relaciones

La próxima vez que inicie sesión en Pinterest, recuerde que Redis se está ejecutando en segundo plano y almacena varios tipos de listas para usted como usuario:

  • Una lista de usuarios a los que sigues
  • Una lista de tableros (y sus usuarios relacionados) a quienes sigues
  • Una lista de tus seguidores.
  • Una lista de personas que siguen tus foros
  • Una lista de tableros que sigues
  • Una lista de tableros que dejó de seguir después de seguir a un usuario
  • Los seguidores y no seguidores de cada tablero

Esta publicación explica en detalle cómo Twitter usa Redis para escalar a millones de usuarios.

Cómo Twitter usa Redis para escalar – 105TB RAM, 39MM QPS, más de 10,000 instancias – Alta escalabilidad –

Github ha hecho que su sitio web funcione mucho más rápido con Redis. Cómo hicimos GitHub rápido

Aquí hay una lista de algunas grandes empresas que usan Redis.


Casos de uso no adecuados para Redis

A pesar de todos estos beneficios, hay algunos casos de uso en los que Redis puede no ser adecuado. Redis debe usarse como la base de datos primaria en los casos en que sea posible ajustar todo el conjunto de datos en la memoria.

Esto se debe a que no es trivial (aunque posible) crear un grupo de instancias de Redis, cada una de las cuales puede contener hasta 2 gb (o 4 u 8). Además, si su aplicación almacena grandes volúmenes de datos, probablemente Redis nunca será su opción debido a la economía (¿puede permitirse terabytes de RAM?). En ese caso, debe darle una mirada profunda y significativa a Amazon S3.

La mayoría de las aplicaciones web grandes Redis se pueden usar junto con un RDBMS. Un patrón de diseño común implica tomar datos pequeños muy pesados ​​en escritura en Redis (y los datos que necesita las estructuras de datos de Redis para modelar su problema de manera eficiente) y grandes blobs de datos en una base de datos en disco SQL o eventualmente coherente.

Redis 3.0 parece estar resolviendo este problema al introducir un mayor soporte para los clústeres.

Algunas personas han intentado usar Redis como el almacén de datos principal y se han enfrentado a algunos problemas. Lea esta publicación para más detalles.

Este comentario sobre Stack Overflow lo resume muy bien.

Redis ofrece funciones que Memcached no ofrece, RDBMS ofrece muchas funciones que Redis no ofrece. Redis debería ser MUCHO más rápido que cualquier RDBMS, pero tampoco puede hacer tanto. Si puede asignar su caso de uso de RDBMS a Redis, puede valer la pena echarle un vistazo, pero si no puede, no lo fuerce. La mejor herramienta para el trabajo y todo eso. Un almacén No-SQL que tiene una mejor oportunidad de reemplazar su RDBMS es MongoDB, pero incluso eso debe evaluarse cuidadosamente y debe elegir el mejor, que puede ser un RDBMS


No es recomendable crear su aplicación únicamente en Redis, excepto en algunos casos de esquina. El siguiente hilo de noticias de hackers discute esto en detalle. Pregúntele a HN: ¿Es factible usar redis como el único almacén de datos?

Dicho esto, Redis ofrece muchas características agradables que pueden ayudarlo a escalar su aplicación. Muchas grandes compañías han apostado por Redis y no se han sentido decepcionadas. Le sugeriría que primero enumere qué requiere exactamente su aplicación y luego decida cómo puede encajar Redis en su pila.

Fuera del autobús de publicación-suscripción del pobre, diferenciaría tres patrones de uso de Redis distintos:

  1. Redis sin Lua como DB de nivel API.
  2. Redis con Lua extensa como base de datos de nivel API.
  3. Redis como un reemplazo inteligente para Memcached, conectado directamente a nginx u otra capa de alto rendimiento para hacer una cosa y hacerlo bien.

Redis sin Lua tiene que residir detrás de un backend de alto rendimiento. No tiene sentido ocultar un Redis QPS de 50+ K detrás de un solo nodo.js / Python / Ruby / lo que sea un proceso de back-end API que difícilmente puede manejar más allá de 1K QPS. Algunos desarrolladores lo llevan al extremo, suponiendo que dado que Redis es mucho más rápido que el marco que usaron para construir la API, pueden permitirse hacer llamadas Redis múltiples y / o demasiado caras por una llamada API. Está bien por sí mismo, especialmente junto con la escala horizontal de los servidores API. Sin embargo, esta escala termina rápida y repentinamente, ya que Redis comienza a correr a toda capacidad.

Casos de uso para los que Redis es adecuado en este modo:

  • Base de datos de usuario simple.

    Ejemplo : asigne nombres de usuario y correos electrónicos a sus URL de avatar.

  • Casos de uso de servicio de bloqueo y / o autenticación, donde los requisitos para el “DB” son tan simples como “tabla única, búsquedas rápidas, lecturas raras”.

    Ejemplo : tienda de tokens de acceso.

  • Canales PubSub de módulos de back-end de tráfico bajo a medio donde la topología es sencilla y no se requiere una persistencia estricta (use Kafka ++ ya que la persistencia se convierte en un problema, y ​​use RabbitMQ ++ para el enrutamiento / corretaje de mensajes a medida que la topología se vuelve compleja y / o dinámica )

    Ejemplo : notificaciones push, generadas por un backend simple con tecnología ML, que a veces llegan al navegador abierto (Socket.IO ++), a veces como notificaciones push (aplicación iOS), a veces como resúmenes de correo electrónico, posiblemente agrupados.

  • Caché a medio plazo previamente rellenado para contenido superior clasificado por feed (s) / categorías, etc. Personalmente estoy dispuesto a usar Redis para potenciar el backend de un servicio simple de una escala de Secret, hasta que alcance unos 5M + total / 250K usuarios activos.

    Ejemplo : “Gente sugerida para seguir” en una plataforma similar a Twitter, leída por la API en tiempo real, actualizada por un trabajo cron por lotes que ejecuta Spark / Hadoop / lo que sea bajo el capó.

Redis con Lua puede ser un buen patrón si el acceso a datos requiere uniones semi-triviales. Por un lado, Redis mantiene los datos en la memoria. Por otro lado, comunicarse con él a través de un canal de bajo rendimiento como lo que haría node.js simplemente no lo logra si una solicitud requiere una serie de unas diez lecturas consecutivas.

Ejemplo : tipo de solicitud “Las personas que siguieron X también siguieron Y”. Se puede diseñar el esquema de Redis para calcular previamente las agregaciones por hora y por día, divididas por usuario / tema / celebridad / contenido específico que atrajo la atención. Este es un campo [estrecho] donde una secuencia de comandos de Lua de ~ 100 líneas se ejecuta dentro de Redis simplemente lo clavaría, mientras que escribir una llamada de fondo “adecuada” no pasaría la barra en términos de rendimiento.

Por lo general, estoy en contra de este tipo de soluciones por una simple razón: son difíciles de probar en regresión y, por lo tanto, difíciles de mantener funcionales. Pero para un caso de uso simple y bien establecido como el ejemplo anterior, donde toda la matemática y la ciencia de los datos se han realizado y son a prueba de balas, y todo lo que se necesita es una infraestructura que “simplemente lo haga”, Redis + Lua = < 3)

Redis como reemplazo de Memcached. Esto tendría mucho sentido ya que los datos son fáciles de almacenar, tienen que actualizarse con frecuencia, pero representan algo que es más complejo que un almacén pasivo. Quizás una recuperación de objetos de grado avatar (unos pocos cientos de bytes), donde se puede almacenar en caché más del 99%, mientras que se requiere una verificación de permisos un poco más fina que Memcached en el momento de la consulta puede ser un gran caso de uso para Redis.


En general, mi impresión es que el modo en que hay espacio para un requisito comercial [potencial] para los patrones de acceso a datos y ML / AI a ciertos conjuntos de recursos, se vuelve menos valioso Redis.

Por ejemplo, un sistema de archivos de bloqueo rápido o una tienda de permisos / tokens, incluso cuando se trata de permisos detallados y jerárquicos, podrían ser buenos ejemplos de Redis.

Sin embargo, no confiaría en conjuntos de tipos de estructuras de datos para aplicaciones de ML reales o planificadas. Redis puede ser una buena herramienta para armar rápidamente algún prototipo que involucre algunas agregaciones con varios coeficientes y conjuntos para unirse, pero a medida que el sistema crece y la capa de persistencia se mueve fuera de Redis, en aras del aislamiento y las mejores prácticas de ingeniería, es mucho más limpio para lanzar un binario dedicado manteniendo su propio almacén en memoria de varias vistas de datos, optimizado para recuperaciones personalizadas, así como para casos relativamente sencillos pero demasiado avanzados para los casos de uso de Redis como “cargar un nuevo modelo” y “recuperar mejores resultados para el usuario U con el modelo M3 “.

Imagine que tiene un servicio API que utiliza un back-end basado en redis para almacenar access_tokens. Tenga en cuenta que los puntos finales en esta API están autenticados, es decir, requieren que pase access_tokens mientras realiza las llamadas REST.

Ahora, cuando se elimina un token, su cliente tiene que recuperarlo de alguna manera. Siempre que necesite buscar redis para el token, el cliente debe conectarse mediante una conexión TCP. Cada llamada TCP implica cierta cantidad de latencia, y además el sistema donde se aloja esta instancia de redis también agrega su propia latencia por sí misma.

Para una aplicación de alto tráfico, el número de conexiones TCP concurrentes aumenta exponencialmente. Es cierto que Redis conservará los datos en el disco, pero no garantiza el rendimiento de un sistema que involucra una gran cantidad de conexiones TCP simultáneas. Además, Redis tiene un solo subproceso, lo que significa que si hay una llamada que esencialmente está bloqueando, otros clientes serán bloqueados antes de que el cliente en cuestión (que realiza la llamada TCP de redis) haya sido atendido.

Ahora imagine que tiene N APIS, donde cada API es un microservicio separado. Por alguna razón, debe realizar llamadas autenticadas para el mismo usuario (por ejemplo) en ambos microservicios. El mismo usuario esencialmente significa que access_token utilizado es el mismo para ambos microservicios. Tradicionalmente, comenzaría con una instancia de redis compartida entre estos dos servicios. Pero ahora imagine que desea extender esta funcionalidad de intercambio de tokens a muchas más API (microservicios). En tal escenario, necesita saber cómo puede fragmentar su instancia de redis de manera eficiente.

En resumen, para una aplicación que involucra mucho tráfico y que probablemente apunta a usar un enfoque basado en microservicios, usar redis como back-end de almacenamiento definitivamente conduciría a problemas de latencia, degradando inadvertidamente el rendimiento a medida que se agregan más servicios / contenedores.

Redis tiene habilidades únicas como sua-scripts ultrarrápidos. Su tiempo de ejecución es igual a la ejecución de los comandos C. Esto también brinda atomicidad para la sofisticada manipulación de datos de Redis requerida para el trabajo de muchos objetos avanzados como cerraduras y semáforos.

Hay una red de datos en memoria basada en Redis llamada Redisson que permite construir fácilmente aplicaciones distribuidas en Java . Gracias a los servicios distribuidos Lock , Semaphore , ReadWriteLock , CountDownLatch , ConcurrentMap , List , Set RemoteService, ExecutorService , SchedulerService , MapReduce y muchos otros. Podría reemplazar fácilmente productos como Hazelcast, Apache Ignite, GridGain, EhCache …

Funciona perfectamente en la nube y es compatible con AWS Elasticache, AWS Elasticache Cluster y Azure Redis Cache

Existe otro caso de uso y es usar Redis como un servicio externo para generar PK para sus tablas SQL.

Esto lo ayudará a evitar conflictos de PK en caso de que sus datos estén fragmentados o replicados en múltiples maestros, etc.

Vea Claves primarias únicas (PK) para MySQL usando Redis y comentarios también.

Redis es una solución NoSQL que está todo en la memoria. Esto significa que no funciona en dos situaciones específicas

1) Si tiene más datos de los que puede guardar en la memoria

2) Si tiene datos persistentes que necesitan garantías de alta integridad.

El principal caso de uso en el que se destaca Redis es el de un caché, particularmente si es un caché temporal. Obtiene los datos que cree que necesitará manejar de inmediato en la memoria y guarda los datos en un almacén más persistente según sea necesario.

More Interesting

¿Cuáles son algunos trucos del inspector web que usa para el desarrollo web?

¿Flask solo es adecuado para aplicaciones a pequeña escala? ¿Debería usarse Django (o sus equivalentes) en su lugar para aplicaciones a gran escala?

Mi cliente me ha pedido que cree una aplicación personalizada para administrar su escuela. Esa aplicación debe sincronizar los datos con los servidores en línea siempre que Internet esté disponible. Sé algo de programación, un poco de PHP. ¿Qué lenguaje y herramientas pueden ayudarme a realizar la tarea rápidamente?

Suponiendo que la industria tecnológica está en una burbuja, ¿afectará el pop a las proyecciones de estadísticas laborales del crecimiento del empleo en el desarrollo web?

¿Qué implica típicamente el mantenimiento de aplicaciones web?

¿Cuáles son las principales fortalezas y debilidades de MediaWiki como plataforma para un sitio web de contenido de conocimiento generado por el usuario?

¿Qué necesitas para desarrollar una aplicación móvil o una aplicación web como Airbnb?

Cómo lograr una interfaz de usuario suave como la seda (60 fps) en la aplicación react / redux

¿Puedo crear aplicaciones web con Bootstrap y Ruby on Rails? Si es así, ¿por qué las personas usan frameworks Javascript?

¿Se puede crear una aplicación web progresiva en una instalación de WordPress, por ejemplo, para tener Pokedex PWA en domain.com/database?

¿Por qué el desarrollo web con Java es tan difícil y engorroso en comparación con Ruby on Rails o Django?

¿Cuál es el futuro de la gamificación de aplicaciones web?

¿Cuánto costaría el desarrollo de un sitio web como Kickstarter?

¿Cómo se puede construir un sistema de navegación con AngularJS para una aplicación web?

¿Cuál es el procedimiento a seguir mientras se prueba una aplicación?