Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Redis

Betabeers
January 27, 2012
340

 Redis

Presenta @ronnylt de @pricebets

Betabeers

January 27, 2012
Tweet

Transcript

  1. ¿Quién soy? SELECT value FROM odds INNER JOIN outcomes ON

    ... INNER JOIN bets ON ... INNER JOIN markets ON ... ... WHERE ... ORDER BY ... Ronny López @ronnylt Desarrollador @pricebets Descubrí Redis cuando una consulta como esta hacia que una página demorara +15 segundos en cargar:
  2. Antes de continuar... ¿Qué hay de malo en los sistemas

    tradicionales de BD relacionales? Nada...
  3. Pero... • 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
  4. ¿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
  5. ¿Quién está detrás de Redis? • Creado por Salvatore Sanfilippo

    @antirez • Release inicial en marzo del 2009 • Actualmente el desarrollo es patrocinado por VMWare • Comunidad activa y amigable
  6. ¿Quién usa Redis? • Usado hoy en el mundo real

    por grandes y pequeñas empresas • Resolviendo grandes y pequeños problemas
  7. ¿Para qué lo usan? • github.com: motor de almacenamiento clave/valor,

    cola de trabajos (resque) • guardian.co.uk: servidor de estructuras de datos persistente • disqus.com: sistema estádistico desarrollado sobre Redis • stackoverflow.com: capa de cache para toda su red • flickr.com: lista de trabajos • pricebets.es: almacenamiento primario (conjuntos, listas, hashes, etc...), routing, cache, sessions
  8. Características principales • Escrito en C • Muy pocas dependencias

    • Super rápido • Single-threaded • Clientes disponibles para varios lenguajes
  9. Características principales • Alto rendimiento en escritura y lectura •

    Soporte de operaciones atómicas • Soporte de transacciones
  10. Características Simplicidad • Fácil instalación • Curva de aprendizaje relativamente

    baja • Lenguage de comandos fácil de utilizar y aprender
  11. Características Previsibilidad • 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
  12. Características Confiabilidad • 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
  13. Características Persistencia • 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
  14. Características Versatilidad • Adaptable a varios tipos de aplicaciones •

    Modelado de los datos a partir de estructuras de datos como listas, conjuntos, conjuntos ordenados y hashes
  15. 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)
  16. Claves • Puede usarse cualquier cadena de caracteres como clave

    • Es recomendable tener organizadas las claves en namespaces (keyspaces) de la forma: object-type:id:field Ejemplo: user:123:password user:456:friends
  17. Claves • NO es recomendable que las claves sean demasiado

    grandes (memoria, localización en el keyspace) • Tampoco es recomendable que las claves sean demasiado cortas por cuestiones de legibilidad Ejemplo: u:123:pw
  18. Tipos de datos Strings • 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
  19. Operaciones Strings • 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 ;)
  20. Operaciones atómicas Strings Atomic increment $ redis-cli SET counter 100

    OK $ redis-cli INCR counter (integer) 101 $ redis-cli INCR counter (integer) 102 $ redis-cli INCRBY counter 10 (integer) 112
  21. ¿Por qué atómico? Aún cuando hayan varios clientes ejecuntando operaciones

    sobre la misma clave, no se va a incurrir en una condición de carrera (race condition)
  22. Otras operaciones Strings • APPEND, GETRANGE, STRLEN, ... • MSET,

    MGET, ... • SETNX, MSETNX, GETSET, ... http://redis.io/commands#string
  23. Tipos de datos Lists • Son simplemente una secuencia de

    elementos (strings) ordenados • Son implementadas como listas enlazadas
  24. Tipos de datos Lists • Listas doblemente enlazadas garantizan la

    inserción en cualquier extremo en un tiempo constante O(1) • Con estas caterísticas también puede modelarse una “cola”
  25. Operaciones Lists • 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
  26. Operaciones Lists • LPUSH, RPUSH, LPOP, RPOP, ... • LINDEX,

    LINSERT, LLEN, ... • LTRIM, LREM, ... http://redis.io/commands#list
  27. 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
  28. Operaciones Lists $ redis-cli RPUSH messages "Hola, ¿qué tal?" OK

    $ redis-cli RPUSH messages "Bien, gracias" OK $ redis-cli RPUSH messages "Muy grande Redis" OK $ redis-cli LRANGE messages 0 2 1. Hola, ¿qué tal? 2. Bien, gracias 3. Muy grande Redis
  29. 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
  30. 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 456 $ redis-cli RPOP post:123:comments 789 $ redis-cli LRANGE post:123:comments 50 60
  31. Tipos de datos Sets • 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
  32. Ejemplos Sets $ redis-cli SADD user:123:friends 456 (integer) 1 $

    redis-cli SADD user:123:friends 789 (integer) 1 $ redis-cli SADD user:123:friends 123 (integer) 1 $ redis-cli SMEMBERS user:123:friends 1. 123 2. 456 3. 789 $ redis-cli SISMEMBER user:123:friends 789 (integer) 1
  33. Ejemplos Sets Etiquetado de noticias $ redis-cli SADD news:123:tags 1

    (integer) 1 $ redis-cli SADD tags:1:objects 123 (integer) 1 Obtener todos los tags de una noticia es trivial $ redis-cli SMEMBERS news:123:tags
  34. Operaciones Sets • SADD, SREM, SCARD, SMEMBERS, SISMEMBER, ... •

    SUNION, SDIFF, SINTER, ... • SPOP, SRAND, .... O(1) http://redis.io/commands#set
  35. Tipos de datos Sorted 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
  36. Tipos de datos Sorted Sets • ZADD es usado para

    agregar nuevos elementos o para actualizar el score de uno ya existente $ redis-cli ZADD top-sites: 4 “pricebets” (integer) 1 $ redis-cli ZADD top-sites: 6 “betabeers” (integer) 1 $ redis-cli ZRANGE top-sites 0 -1 1. betabeers 2. pricebets
  37. Operaciones Sorted Sets • ZADD, ZREM, ZCARD, ZCOUNT, ZINCR, ...

    • ZSCORE, ZINCRBY, ZRANK, ... • ZCOUNT, .... http://redis.io/commands#sorted_set
  38. Tipos de datos Hashes • 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
  39. Operaciones Hashes $ redis-cli HSET event:1 name betabeers $ redis-cli

    HSET event:1 date 2012-01-17 $ redis-cli HSET event:1 where Barcelona $ redis-cli HGETALL event:1 1) name 2) betabeers 3) date 4) 2012-01-17 5) where 6) Barcelona
  40. Operaciones Hashes • HSET, HGET, HDEL, HEXIST, ... • HKEYS,

    HGETALL, HVALS, ... • HMGET, HMSET, ... http://redis.io/commands#hash
  41. Contadores • Gran cantidad de escrituras/lecturas • Datos valiosos, pero

    NO críticos • Insertar una fila en MySQL o actualizar un contador en cada petición será sin dudas difícil de escalar
  42. Contadores $ redis-cli INCR active:sports:spain $ redis-cli INCR active:sports:italy $

    redis-cli GET active:sports:spain $ redis-cli GETSET active:sports:spain 0
  43. 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
  44. 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:05
  45. Presencia • El conjunto de “amigos” online es otra operación

    sobre conjuntos $ redis-cli SUNION online:15:01 online:15:02 online:15:03 online: 15:04 online:15:05 user:123:friends • Puede almacenarse en otra clave: $ redis-cli SUNIONSTORE friends:online:123 online:15:01 online:15:02 online:15:03 online: 15:04 online:15:05 user:123:friends
  46. 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
  47. 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
  48. 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/copa-del-rey => /competition/3120
  49. URL Routing • Convertir paths internos a friendly URLs Ejemplo:

    /sport/1 => http://www.apuestas.com/futbol /competition/3120 http://www.apuestas.com/futbol/espana/copa-del-rey
  50. 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 • Tiempo constante O(1) para cualquier número de rutas/alias
  51. ¿Qué se espera para próximas vesiones? • Scripting (con LUA)

    (Redis 2.6) • High resolution expires (Redis 2.6) • Mejoras en el rendimiento de la escritura/lectura de grandes objetos (Redis 2.6) • Redis Cluster (Redis 3.0)
  52. Algunos consejos • Instancias de Redis en 64 bits consumen

    más RAM • No usar el comando KEYS en producción • Comando MONITOR para observar y monitorear
  53. Benchmarks redis-benchmark -q -n 100000 PING (inline): 108459.87 requests per

    second PING: 89766.61 requests per second MSET (10 keys): 48053.82 requests per second SET: 80064.05 requests per second GET: 87108.02 requests per second INCR: 82644.62 requests per second LPUSH: 82169.27 requests per second LPOP: 78802.20 requests per second SADD: 71890.73 requests per second SPOP: 93283.58 requests per second LPUSH (again, in order to bench LRANGE): 86880.97 requests per second LRANGE (first 100 elements): 64061.50 requests per second LRANGE (first 300 elements): 40064.10 requests per second LRANGE (first 450 elements): 30478.51 requests per second LRANGE (first 600 elements): 25873.22 requests per second Processor 2.2 GHz Intel Core i7 Memory 8 GB 1333 MHz DDR3