Redis–symfony–barcelona–31 05-2012

73
Acelerando aplicaciones Symfony 2 con Ronny López @ronnylt Thursday, May 31, 12

Transcript of Redis–symfony–barcelona–31 05-2012

Page 1: Redis–symfony–barcelona–31 05-2012

Acelerando aplicaciones Symfony 2

con

Ronny López@ronnylt

Thursday, May 31, 12

Page 2: Redis–symfony–barcelona–31 05-2012

¿Quién soy?

Ronny López @ronnylt

Desarrollador @pricebets

Usando Redis+Symfony2 desde abril 2011

Thursday, May 31, 12

Page 3: Redis–symfony–barcelona–31 05-2012

Sumario

1. Introducción a Redis advanced key-value store 2. Principales características y tipos de datos

3. Casos de uso generales

4. Integración con Symfony2

◦ Session storage◦ Monolog logging handlers◦ SwiftMailer spooling◦ Profiler storage◦ Doctrine caching◦ Data Collector for Symfony2 Profiler◦ Dynamic routing

5. Ejemplos y preguntas

Thursday, May 31, 12

Page 4: Redis–symfony–barcelona–31 05-2012

Descubrí Redis cuando una consulta como esta hacia que una página demorara +15 segundos en cargar:

SELECT value FROM oddsINNER JOIN outcomes ON ...INNER JOIN bets ON ...INNER JOIN markets ON ...WHERE ... ORDER BY ...

¿Por qué Redis?

Thursday, May 31, 12

Page 5: Redis–symfony–barcelona–31 05-2012

Problemas

• Hay tareas que no necesitan tanta complejidad

• El modelo relacional actual es difícil de escalar horizontalmente

• No se pueden modelar problemas comunes lo suficientemente bien

Thursday, May 31, 12

Page 6: Redis–symfony–barcelona–31 05-2012

¿Qué es Redis?

• Remote dictionary server

• Motor de almacenamiento clave-valor avanzado, rápido y persistente

• Servidor de estructuras de datos

• NoSQL (Not-only SQL)

• Open source (patrocinado por VMWare)

Thursday, May 31, 12

Page 7: Redis–symfony–barcelona–31 05-2012

Características principales

• Alto rendimiento en escritura y lectura

• Soporte de operaciones atómicas

• Soporte de transacciones

• Persistencia !

Thursday, May 31, 12

Page 8: Redis–symfony–barcelona–31 05-2012

CaracterísticasSimplicidad

• Fácil instalación

• Curva de aprendizaje relativamente baja

• Lenguage de comandos fácil de utilizar y aprender

Thursday, May 31, 12

Page 9: Redis–symfony–barcelona–31 05-2012

CaracterísticasPrevisibilidad

• La memoria es rápida, y permite a Redis tener un redimiento muy fiable

• Operaciones sobre datasets de 10 mil claves tendrán el mismo rendimiento que sobre datasets de 50 millones de claves

• La complejidad algorítmica de todos los comandos está documentada

Thursday, May 31, 12

Page 10: Redis–symfony–barcelona–31 05-2012

CaracterísticasConfiabilidad

• Todos los datos residen en memoria, y son persistidos a disco eventualmente (snapshots, append-only log)

• Replication system (master-slave) , pueden configurarse múltiples esclavos. Un esclavo puede ser el master de otro esclavo

Thursday, May 31, 12

Page 11: Redis–symfony–barcelona–31 05-2012

CaracterísticasPersistencia

• RDB, Point-in-time snapshots en intervalos configurados

• AOF (append-only file) cada operación de escritura

• Es posible combinar RDB y AOF en la misma instancia

• Se puede deshabilitar la persistencia del todo

Thursday, May 31, 12

Page 12: Redis–symfony–barcelona–31 05-2012

CaracterísticasVersatilidad

• Adaptable a varios tipos de aplicaciones

• Modelado de los datos a partir de estructuras de datos como listas, conjuntos, conjuntos ordenados y hashes

Thursday, May 31, 12

Page 13: Redis–symfony–barcelona–31 05-2012

Tipos de datos

• Redis NO es simplemente un motor de almacenamiento clave-valor

• Es un servidor de estructuras de datos que incluye varios tipos de datos predefinidos (strings, lists, sets, sorted sets, hashes)

Thursday, May 31, 12

Page 14: Redis–symfony–barcelona–31 05-2012

Tipos de datosStrings

• Es el tipo de dato más simple

• Si solamente usa este tipo de dato es similar a usar un servidor memcached pero con persistencia

Thursday, May 31, 12

Page 15: Redis–symfony–barcelona–31 05-2012

OperacionesStrings

• Comandos SET/GET para escribir/leer

• Los valores pueden ser cualquier string no mayor que 1 GB

• Si necesita almacenar algo más grande, Redis is NOT for you ;)

Thursday, May 31, 12

Page 16: Redis–symfony–barcelona–31 05-2012

Tipos de datosIntegers

• Ideal para contadores atómicos

INCR count> 1INCR count > 2INCRBY count 5> 7

Thursday, May 31, 12

Page 17: Redis–symfony–barcelona–31 05-2012

Tipos de datosLists

• Secuencia de elementos ordenados

• Uno de los tipos de datos más usados

• Encaja perfectamente como estructura de datos ideal para resolver varios problemas

Thursday, May 31, 12

Page 18: Redis–symfony–barcelona–31 05-2012

Tipos de datosLists

• Listas doblemente enlazadas garantizan la inserción en cualquier extremo en un tiempo constante O(1)

• Con estas caterísticas puede usarse para modelar una “cola”

Thursday, May 31, 12

Page 19: Redis–symfony–barcelona–31 05-2012

OperacionesLists

• LPUSH agrega un elemento en el extremo izquierdo de la lista

• RPUSH en el extremo derecho

• LRANGE extrae elementos de la lista en cierto rango

Thursday, May 31, 12

Page 20: Redis–symfony–barcelona–31 05-2012

OperacionesLists

• LPUSH, RPUSH, LPOP, RPOP, ...

• LINDEX, LINSERT, LLEN, ...

• LTRIM, LREM, ...

• http://redis.io/commands#list

Thursday, May 31, 12

Page 21: Redis–symfony–barcelona–31 05-2012

Variantes “blocking”

• BLPOP, BRPOP, BRPOPLPUSH

• Bloquean la conexión (del cliente) cuando no hay elementos en la lista

• Ideal para implementar colas de trabajos/mensajes

Thursday, May 31, 12

Page 22: Redis–symfony–barcelona–31 05-2012

Usos de las listas

• Utilice listas cada vez que requiera acceder a los datos en el mismo orden en que se agregan

• Ideal para casos en los que se requiere un ORDER BY de SQL

• Escalable a millones de elementos manteniendo el mismo rendimiento

Thursday, May 31, 12

Page 23: Redis–symfony–barcelona–31 05-2012

Ejemplos de uso de las listas

• Mantener un listado cronológico de los comentarios publicados en un blog

• Es posible paginar usando LRANGE de forma trivial

$redis-cli RPOP post:123:comments c1$redis-cli RPOP post:123:comments cn$redis-cli LRANGE post:123:comments 50 60

Thursday, May 31, 12

Page 24: Redis–symfony–barcelona–31 05-2012

Tipos de datosSets

• Colección NO–ordenada de datos (conjuntos)

• Permite operaciones típicas sobre conjuntos como unión, intersección, diferencia, etc...

• Estas operaciones son difíciles de implementar en un modelo relacional

Thursday, May 31, 12

Page 25: Redis–symfony–barcelona–31 05-2012

OperacionesSets

• SADD, SREM, SCARD, SMEMBERS, SISMEMBER, ...

• SUNION, SDIFF, SINTER, ...

• SPOP, SRAND, .... O(1)

• http://redis.io/commands#set

Thursday, May 31, 12

Page 26: Redis–symfony–barcelona–31 05-2012

Tipos de datosSorted Sets

• Un conjunto ordenado es un conjunto donde a cada elemento se le asocia una puntuación (score)

• Este valor (score) determina el orden de los elementos dentro del conjunto

Thursday, May 31, 12

Page 27: Redis–symfony–barcelona–31 05-2012

OperacionesSorted Sets

• ZADD, ZREM, ZCARD, ZCOUNT, ZINCR, ...

• ZSCORE, ZINCRBY, ZRANK, ...

• ZCOUNT, ....

• http://redis.io/commands#sorted_set

Thursday, May 31, 12

Page 28: Redis–symfony–barcelona–31 05-2012

Tipos de datosHashes

• Permiten que objetos compuestos se almacenen en una clave específica

• Tipo de dato ideal para almacenar objetos complejos en Redis, usando los atributos del objeto como claves del hash

Thursday, May 31, 12

Page 29: Redis–symfony–barcelona–31 05-2012

OperacionesHashes

• HSET, HGET, HDEL, HEXIST, ...

• HKEYS, HGETALL, HVALS, ...

• HMGET, HMSET, ...

• http://redis.io/commands#hash

Thursday, May 31, 12

Page 30: Redis–symfony–barcelona–31 05-2012

Casos de usoData caching

Thursday, May 31, 12

Page 31: Redis–symfony–barcelona–31 05-2012

Data caching

• Redis como motor primario de cache compartida

• Compartir datos cacheados entre múltiples aplicaciones

• Como un memcached pero persistente

Thursday, May 31, 12

Page 32: Redis–symfony–barcelona–31 05-2012

Casos de usoContadores

Thursday, May 31, 12

Page 33: Redis–symfony–barcelona–31 05-2012

Contadores

• Gran cantidad de escrituras/lecturas

• Datos valiosos, pero NO críticos

• No encajan en el modelo relacional

• Insertar una fila en MySQL o actualizar un contador en cada petición será sin dudas difícil de escalar

Thursday, May 31, 12

Page 34: Redis–symfony–barcelona–31 05-2012

Contadores

$ INCR active:sports:spain> 0$ INCR active:sports:spain> 2$ INCR active:sports:italy> ...

Thursday, May 31, 12

Page 35: Redis–symfony–barcelona–31 05-2012

Casos de usoPresencia

¿Quién está online?

Thursday, May 31, 12

Page 36: Redis–symfony–barcelona–31 05-2012

Presencia

• Mantener en un conjunto los usuarios que se han detectado online en cada minuto

$ redis-cli SADD online:15:01 123$ redis-cli SADD online:15:01 456

$ redis-cli SADD online:15:02 123

Thursday, May 31, 12

Page 37: Redis–symfony–barcelona–31 05-2012

Presencia

• El conjunto de usuarios online se puede obtener de la UNION de los conjuntos relativos a los últimos ¿5? minutos.

A las 15:05$ redis-cli SUNION online:15:01 online:15:02 online:15:03 online:15:04 online:15:051) 1232) 345

Thursday, May 31, 12

Page 38: Redis–symfony–barcelona–31 05-2012

Presencia

• El conjunto de “amigos” online de cierto usuario es otra operación sobre conjuntos

redis-cli SINTER online:15:01 online:15:02 online:15:03 online:15:04 online:15:05 user:123:friends

Thursday, May 31, 12

Page 39: Redis–symfony–barcelona–31 05-2012

Casos de usoDymanic tracking

Thursday, May 31, 12

Page 40: Redis–symfony–barcelona–31 05-2012

Dymamic Tracking

• Queremos mantener un listado de las últimas 100 páginas visitadas en una web

• ¿Qué están leyendo los usuarios ahora?

• Mantenemos una lista y la limitamos a que tenga solo 100 elementos

• Comparado a MongoDB capped collections

Thursday, May 31, 12

Page 41: Redis–symfony–barcelona–31 05-2012

Dynamic Tracking

LPUSH mylist somedataLTRIM mylist 0 99

Thursday, May 31, 12

Page 42: Redis–symfony–barcelona–31 05-2012

Casos de usoTabla de posicionesReal time data sorting

Thursday, May 31, 12

Page 43: Redis–symfony–barcelona–31 05-2012

Tabla de posiciones

• Se necesita listar elementos ordenados por una puntuación

• Las puntuaciones se actualizan en tiempo real

• Consultas lentas por naturaleza

SELECT * FROM ... WHERE ... ORDER BY ... LIMIT 10

Thursday, May 31, 12

Page 44: Redis–symfony–barcelona–31 05-2012

Tabla de posiciones

• Mantener un conjunto ordenado (sorted set) con los elementos y su score

$ redis-cli ZADD popular:sports 10 football$ redis-cli ZADD popular:sports 6 basketball$ redis-cli ZADD popular:sports 12 football

$ redis-cli ZREVRANGE popular:sports 0 9

Thursday, May 31, 12

Page 45: Redis–symfony–barcelona–31 05-2012

Tabla de posiciones

• Mantener un conjunto ordenado (sorted set) con los elementos y su score

$ redis-cli ZADD popular:sports 10 football$ redis-cli ZADD popular:sports 6 basketball$ redis-cli ZADD popular:sports 12 football

$ redis-cli ZREVRANGE popular:sports 0 9

Thursday, May 31, 12

Page 46: Redis–symfony–barcelona–31 05-2012

Casos de usoLogging

Thursday, May 31, 12

Page 47: Redis–symfony–barcelona–31 05-2012

Loggin

• Redis como motor de almacenamiento de logs

• Escribimos logs en orden en una lista, y la limitamos a que tenga uan cierta cantidad de elementos

Thursday, May 31, 12

Page 48: Redis–symfony–barcelona–31 05-2012

Casos de usoURL Routing

Data dictionary

Thursday, May 31, 12

Page 49: Redis–symfony–barcelona–31 05-2012

URL Routing

• Convertir alias de URL a paths internos de la aplicación

Ejemplo:

http://www.apuestas.com/futbol => /sport/1

http://www.apuestas.com/futbol/espana/

Thursday, May 31, 12

Page 50: Redis–symfony–barcelona–31 05-2012

URL Routing

• Convertir paths internos a friendly URLs

Ejemplo: /sport/1=> http://www.apuestas.com/futbol

/competition/3120http://www.apuestas.com/futbol/espana/copa-del-rey

Thursday, May 31, 12

Page 51: Redis–symfony–barcelona–31 05-2012

URL Routing

• Mantener un hash con el routing y otro con los alias

redis-cli HSET routing /futbol /sport/1

redis-cli HSET alias /sport/1 /futbol

Thursday, May 31, 12

Page 52: Redis–symfony–barcelona–31 05-2012

URL GenerationDictionary

Path (internal) URL

sport/1 /football

article/1234 /news/football/very-nice-friendly-url

user/345 /users/spain/el-fary

alias:example.com

Thursday, May 31, 12

Page 53: Redis–symfony–barcelona–31 05-2012

URL MatchingDictionary

URL Path (internal)

/football sport/1

/news/football/very-nice-friendly-url article/1234

/users/spain/el-fary user/345

routes:example.com

Thursday, May 31, 12

Page 54: Redis–symfony–barcelona–31 05-2012

Integración con Symfony2

Thursday, May 31, 12

Page 55: Redis–symfony–barcelona–31 05-2012

Integración con Symfony2

• Construye tu propia integración

• Usa algún bundle de 3ras partes

• https://github.com/lessthan/LtRedisBundle

• https://github.com/snc/SncRedisBundle

Thursday, May 31, 12

Page 56: Redis–symfony–barcelona–31 05-2012

Clientes para PHP

• Predishttps://github.com/nrk/predis

• PhpRedishttps://github.com/nicolasff/phpredis

Thursday, May 31, 12

Page 57: Redis–symfony–barcelona–31 05-2012

Predishttps://github.com/nrk/predis

• Escrito en PHP

• Diferentes server profiles (versions)

https://github.com/nrk/predis#main-features

Thursday, May 31, 12

Page 58: Redis–symfony–barcelona–31 05-2012

PhpRedishttps://github.com/nicolasff/phpredis

• PHP Extension

• Ligeramente más rápido

• No sporta todas las versiones

Thursday, May 31, 12

Page 59: Redis–symfony–barcelona–31 05-2012

Conexiones

• Configuración de las conexiones a través de los archivos de configuración de la aplicación

Thursday, May 31, 12

Page 60: Redis–symfony–barcelona–31 05-2012

Session storage• Redis como almacenamiento primario de

sessiones de Symfony2

• Persistente

• Rápido

• Replicable

• Escalable

Thursday, May 31, 12

Page 61: Redis–symfony–barcelona–31 05-2012

Session storageRedisSessionHandler implementation

Thursday, May 31, 12

Page 62: Redis–symfony–barcelona–31 05-2012

Session storageConfigurando el handler de session

Thursday, May 31, 12

Page 63: Redis–symfony–barcelona–31 05-2012

Session storage

redis 127.0.0.1:6379> keys *

1) "sf2:session:pc5gsvnkap6q1ishmvf7lonba2"2) "sf2:session:cv1dnt9aradi7c1ehbo12gp410"

redis 127.0.0.1:6379> get sf2:session:pc5gsvnkap6q1ishmvf7lonba2

"_sf2_attributes|a:2:{s:4:\"test\";s:15:\"testing session\";s:5:\"test1\";s:15:\"testing session\";}_sf2_flashes|a:2:{s:7:\"display\";a:0:{}s:3:\"new\";a:0:{}}_sf2_meta|a:3:{s:1:\"u\";i:1338469484;s:1:\"c\";i:1338469484;s:1:\"l\";s:1:\"0\";}"redis 127.0.0.1:6379>

Thursday, May 31, 12

Page 64: Redis–symfony–barcelona–31 05-2012

Monolog handler• Redis como almacenamiento para logs

• Muy útil cuando se necesita conservar logs para inspeccionar

• El filesystem es muy lento

• Fácil de leer desde otras aplicaciones (monitoreo)

Thursday, May 31, 12

Page 65: Redis–symfony–barcelona–31 05-2012

Monolog handler

• Se implementa un servicio que actúe como un custom Monolog Handler y utilice una lista de redis para almacenar los logs

• Configuración

Thursday, May 31, 12

Page 66: Redis–symfony–barcelona–31 05-2012

SwiftMailer spooling

• Unsando una lista de Redis para hacer el mail spooling

• La aplicación no ejecuta el envio de los correos durante ningún request

• Los correos salientes son puestos en una cola

• Otro proceso (en otro nodo, por ejemplo) se encarga de hacer el envio de los correos

Thursday, May 31, 12

Page 67: Redis–symfony–barcelona–31 05-2012

Profiler storage

• Agregado al HttpKernel Component en la 2.1

https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php

• Usar como alternativa al SquileteProfilerStorage o al FileProfilerStorage

Thursday, May 31, 12

Page 68: Redis–symfony–barcelona–31 05-2012

Doctrine Caching

• Usado como almacenamiento primario para la cache de metadatos, resultados, y query de Doctrine

• Alternativa al APC cache que se usa generalmente

Thursday, May 31, 12

Page 69: Redis–symfony–barcelona–31 05-2012

Data Collector• LtRedisBundle implementa un DataCollector

de los comandos enviados a Redis a través de su cliente

Thursday, May 31, 12

Page 70: Redis–symfony–barcelona–31 05-2012

Data Collector

Thursday, May 31, 12

Page 71: Redis–symfony–barcelona–31 05-2012

Dynamic Routing

• Necesitamos convertir URLs amigables a rutas internas de Symfony2

• No queremos tener que hacer una consulta a una base de datos para generar cada URL amigables de una página (Ej. Doctrine Route)

Thursday, May 31, 12

Page 72: Redis–symfony–barcelona–31 05-2012

Dynamic Routing

Thursday, May 31, 12

Page 73: Redis–symfony–barcelona–31 05-2012

Muchas gracias...

Thursday, May 31, 12