SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Redis na prática



    O ruim, o bom e o sensacional




                   
Benchmark
    3 processos / 20 mil inserções / 60 mil selects ordenados / 60 mil counts

    > time ./manage.py benchmark --db=redis
    real     2m32.417s
    user     2m27.341s
    sys      0m3.112s

    > time ./manage.py benchmark --db=mysql
    real     16m25.251s
    user     0m46.115s
    sys      0m4.628s

    > time ./manage.py benchmark --db=mongodb
    ^C
    KeyboardInterrupt
    real     38m28.659s
    user     0m59.056s
    sys      0m2.628s
                                           
Benchmark



    Nunca confie no Benchmark dos outros!




                      
Exemplos


Tornar-se fã
Crawler de vídeo
Responder Quiz
Ranking do Quiz



                    
Exemplos 1: Tornar-se Fã


Muitas consolidações a cada novo fã
Rapidez para não bloquear processos




                   
Consolidações


                     tasks



                   NewFanTask

    TaskManager    NewFanTask       gunicorn

                   NewFanTask




                  ArtistTaskGroup


                           
Fila para consolidações

    redis> rpush tasks oi
    redis> rpush tasks tudo
    redis> rpush tasks bem

    redis> lpop tasks
    "oi"
    redis> lpop tasks
    "tudo"
    redis> lpop tasks
    "bem"
    redis> lpop tasks
    (nil)
                               
Cuidado: Fila virando Pilha

    redis> rpush tasks oi
    redis> rpush tasks tudo
    redis> rpush tasks bem

    redis> rpop tasks
    "bem"
    redis> rpop tasks
    "tudo"
    redis> rpop tasks
    "oi"
    redis> rpop tasks
    (nil)
                               
Abstraindo a fila

    class RedisQueue(object):

      def __init__(self,key,client=client):
        self.key = key
        self.client = client

      def push(self,obj):
        value = ujson.encode(obj)
        self.client.rpush(self.key, value)

      def pop(self):
        value = self.client.lpop(self.key)
        return self.from_json(value)
                                  
Porque não?


    Resque / Pyres
    Redis Pub/Sub




                      
Exemplo 2: Crawler de vídeo


    Dois milhões de músicas
    Restrição da API do Youtube
    Busca de vídeos no browser
    Processamento no server
    Prioridade pros mais acessados


                       
SortedSet

redis> zincrby crawler-video 1 video1
redis> zincrby crawler-video 1 video1
redis> zincrby crawler-video 1 video2
redis> zincrby crawler-video 8 video3

redis> zrevrange crawler-video 0 -1
1) "video3" 2) "video1" 3) "video2"

redis> zrevrank crawler-video video3
(integer) 0



                            
Abstraindo SortedSet

class RedisSortedSet(object):

    def __init__(self,key,client=client):
      self.key = key
      self.client = client

    def incr(self,value,amount=1):
      return self.client.zincrby(self.key, value, amount)

    def bests(self,max=0):
      return self.client.zrevrange(self.key, 0, max-1)

                                  
Exemplo 3: Responder Quiz


    Gravar se acertou ou não
    Impedir responder mesma pergunta




                      
Utilizando Sets

def responder(self, quiz, resposta):
  respondidas = RedisSet(”quiz-respondidos-%s” % self.id, client=redis)
  if respondidas.add(quiz.id):
      if quiz.opcao_correta(resposta):
          acertadas = RedisSet(”quiz-acertadas-%s” % self.id, client=redis)
          acertadas.add(quiz.id)

redis> sadd quiz-respondidos-x 1
(integer) 1
redis> sadd quiz-acertadas-x 1
(integer) 1

redis> sadd quiz-respondidos-x 1
(integer) 0
                                      
Hash

redis> hset estados-capitais amazonas manaus
redis> hset estados-capitais bahia salvador
redis> hgetall estados-capitais
1) "amazonas" 2) "manaus" 3) "bahia" 4) "salvador"

redis> hset estados-capitais amazonas belem
redis> hgetall estados-capitais
1) "amazonas" 2) "belem" 3) "bahia" 4) "salvador"

redis> hsetnx estados-capitais bahia recife
redis> hgetall estados-capitais
1) "amazonas" 2) "belem" 3) "bahia" 4) "salvador"

                             
Utilizando Hash

def responder(self, quiz, resposta):
  respondidos = RedisHash(”quiz-respondidos-%s” % self.id, client=redis)
  acertou = 1 if quiz.opcao_correta(resposta) else 0
  respondidos.set_if_new(quiz.id, acertou)

redis> hsetnx quiz-respondidos-x 20 0
(integer) 1

redis> hsetnx quiz-respondidos-x 20 1
(integer) 0




                                    
Exemplo 4: Ranking do Quiz


    Sugestões?




                  
Exemplo 4: Ranking do Quiz


    Sugestões?
    SortedSet?




                  
Exemplo 4: Ranking do Quiz


    Ranking dos amigos?
    1 ranking por usuário
    Atualizar rankings a cada resposta?




                        
Fila e SortedSet
Ao responder um quiz:
redis> rpush tasks rankings-quiz-usuario-x

Cron:
redis> lpop tasks
"rankings-quiz-usuario-x"
redis> smembers amigos-usuario-x
1) "a" 2) "b" 3) "c"
redis> hval respostas-usuario-x
1) "1" 2) "1" 3) "0"
redis> zadd ranking-usuario-x 2 usuario-x
redis> zadd ranking-usuario-a 2 usuario-x
redis> zadd ranking-usuario-b 2 usuario-x
redis> zadd ranking-usuario-c 2 usuario-x
                            
Muito complexo?


    Porque não MySql?




                     
Cansei de exemplos


    Vamos falar de OCLs




                      
OCLs: Multi / Exec

redis> multi
redis> zadd ranking-usuario-x 2 usuario-x
redis> zadd ranking-usuario-a 2 usuario-x
redis> zadd ranking-usuario-b 2 usuario-x
redis> zadd ranking-usuario-c 2 usuario-x
redis> exec


redis = Redis(**confs).pipeline()
for id in [id, ”a”,”b”,”c”]:
   sorted_set = RedisSortedSet(”ranking-usuario-%s” % id, client=redis)
   sorted_set.add(”usuario-x”,amount=2)
redis.execute()


                                     
OCLs: Multi / Exec

redis> multi
redis> hsetnx respostas-usuario-id quiz-1 1
redis> rpush tasks rankings-quiz-usuario-x
redis> exec


acertou = 1 if pergunta.certa == resposta else 0
redis = Redis(**confs).pipeline()
hash = RedisHash(”respostas-usuario-%s” % usuario.id, client=redis)
hash.set_if_new(”quiz-” % pergunta.id, acertou):
if acertou:
    queue = RedisQueue(”tasks”, client=redis)
    queue.push(”ranking-quiz-usuario-%s” % usuario.id)
redis.execute()

                                    
OCLs: Master / Slave

> sudo vim /etc/redis/redis-slave.conf
port 6380
slaveof 127.0.0.1 6739
> sudo redis-server /etc/redis/redis-slave.conf

> redis-cli
redis> monitor
OK
1335985598.138718 "monitor"
1335986003.209676 "SYNC"


                              
OCLs: Master / Slave

    > redis-cli
    redis 127.0.0.1:6379> set x b

    > redis-cli -h 127.0.0.1 -p 6380
    redis 127.0.0.1:6380> monitor
    OK
    1335986423.169745 "monitor"
    1335986441.430632 "PING"
    1335986441.430632 "PING"
    1335986462.113501 "set" "x" "b"
    1335986471.500976 "PING"


                               
OCLs: Script em lua

    Redis 2.6:

    redis> eval "return {ARGV[1]}" valor

    Ainda não usei, por isso não vou falar nada.




                                
Conclusão

    Performático
    Escalável
    Divertido

    No entando...
    + Complexo que Sql e Mongo

                      
Mais informações


http://redis.io/commands
http://rediscookbook.org




                     
Mantenha contato

timotta@gmail.com

@timotta

http://programandosemcafeina.blogspot.com




                      

Weitere ähnliche Inhalte

Was ist angesagt?

Proxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testesProxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testesStanislaw Pusep
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9Nando Vieira
 
Yet Another Ruby Framework - Como o Rails funciona por dentro
Yet Another Ruby Framework - Como o Rails funciona por dentroYet Another Ruby Framework - Como o Rails funciona por dentro
Yet Another Ruby Framework - Como o Rails funciona por dentroCarlos Brando
 
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...Miguel Gallardo
 
Identifique brechas, proteja sua aplicação | Php avenger e octopus
Identifique brechas, proteja sua aplicação | Php avenger e octopusIdentifique brechas, proteja sua aplicação | Php avenger e octopus
Identifique brechas, proteja sua aplicação | Php avenger e octopusLeonn Leite
 
Fluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaFluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaCésar Araújo
 
Frontline - Rails3.1
Frontline - Rails3.1Frontline - Rails3.1
Frontline - Rails3.1Daniel Lopes
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN StackBruno Catão
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantesEduardo Mendes
 
Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Luis Gustavo Almeida
 
A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoNando Vieira
 
Entre na fila. Processamento distribuído usando Gearman
Entre na fila. Processamento distribuído usando GearmanEntre na fila. Processamento distribuído usando Gearman
Entre na fila. Processamento distribuído usando GearmanElton Minetto
 
Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017 Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017 Luis Gustavo Almeida
 

Was ist angesagt? (20)

Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1
 
Proxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testesProxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testes
 
Redis
RedisRedis
Redis
 
A busca pelo deploy continuo
A busca pelo deploy continuoA busca pelo deploy continuo
A busca pelo deploy continuo
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9
 
Mongo + php
Mongo + phpMongo + php
Mongo + php
 
Yet Another Ruby Framework - Como o Rails funciona por dentro
Yet Another Ruby Framework - Como o Rails funciona por dentroYet Another Ruby Framework - Como o Rails funciona por dentro
Yet Another Ruby Framework - Como o Rails funciona por dentro
 
Treinamento Elasticsearch - Parte 2
Treinamento Elasticsearch - Parte 2Treinamento Elasticsearch - Parte 2
Treinamento Elasticsearch - Parte 2
 
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...
Elasticsearch: Motor de busca e além. Lições aprendidas criando Tu Próximo...
 
Identifique brechas, proteja sua aplicação | Php avenger e octopus
Identifique brechas, proteja sua aplicação | Php avenger e octopusIdentifique brechas, proteja sua aplicação | Php avenger e octopus
Identifique brechas, proteja sua aplicação | Php avenger e octopus
 
Fluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibanaFluentd/LogStash + elastic search + kibana
Fluentd/LogStash + elastic search + kibana
 
Implementação de
Implementação de Implementação de
Implementação de
 
Frontline - Rails3.1
Frontline - Rails3.1Frontline - Rails3.1
Frontline - Rails3.1
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantes
 
Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP
 
A explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo pretoA explosão do Node.js: JavaScript é o novo preto
A explosão do Node.js: JavaScript é o novo preto
 
Entre na fila. Processamento distribuído usando Gearman
Entre na fila. Processamento distribuído usando GearmanEntre na fila. Processamento distribuído usando Gearman
Entre na fila. Processamento distribuído usando Gearman
 
Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017 Mini Curso PHP Twig - PHP Conference 2017
Mini Curso PHP Twig - PHP Conference 2017
 
Realtime com node.js e socket.io
Realtime com node.js e socket.ioRealtime com node.js e socket.io
Realtime com node.js e socket.io
 

Ähnlich wie Redis na prática: exemplos e OCLs

Quick introduction to Ruby on Rails
Quick introduction to Ruby on RailsQuick introduction to Ruby on Rails
Quick introduction to Ruby on RailsWhitesmith
 
Ruby and Rails intro
Ruby and Rails introRuby and Rails intro
Ruby and Rails introNuno Silva
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeIgor Nicoli
 
Esta começando a programar para a web? Então começe com Rails
Esta começando a programar para a web? Então começe com RailsEsta começando a programar para a web? Então começe com Rails
Esta começando a programar para a web? Então começe com Railsismaelstahelin
 
Rails - EXATEC2009
Rails - EXATEC2009Rails - EXATEC2009
Rails - EXATEC2009Caue Guerra
 
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...Big Data Week São Paulo
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmGuilherme Blanco
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Emerson Macedo
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAThiago Cifani
 
Docker 1.12 - Swarm Mode
Docker 1.12 - Swarm ModeDocker 1.12 - Swarm Mode
Docker 1.12 - Swarm ModeRafael Gomes
 
Busca Visual
Busca VisualBusca Visual
Busca Visualgsroma
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricksTales Andrade
 
Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Cristiano Rafael Steffens
 

Ähnlich wie Redis na prática: exemplos e OCLs (20)

Curso de Node JS Básico
Curso de Node JS BásicoCurso de Node JS Básico
Curso de Node JS Básico
 
PHP e Redis
PHP e RedisPHP e Redis
PHP e Redis
 
Quick introduction to Ruby on Rails
Quick introduction to Ruby on RailsQuick introduction to Ruby on Rails
Quick introduction to Ruby on Rails
 
Ruby and Rails intro
Ruby and Rails introRuby and Rails intro
Ruby and Rails intro
 
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
 
Esta começando a programar para a web? Então começe com Rails
Esta começando a programar para a web? Então começe com RailsEsta começando a programar para a web? Então começe com Rails
Esta começando a programar para a web? Então começe com Rails
 
Rails - EXATEC2009
Rails - EXATEC2009Rails - EXATEC2009
Rails - EXATEC2009
 
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...
Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big ...
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010
 
Minicurso Ruby on Rails
Minicurso Ruby on RailsMinicurso Ruby on Rails
Minicurso Ruby on Rails
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVA
 
Docker 1.12 - Swarm Mode
Docker 1.12 - Swarm ModeDocker 1.12 - Swarm Mode
Docker 1.12 - Swarm Mode
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 
Oficial
OficialOficial
Oficial
 
Busca Visual
Busca VisualBusca Visual
Busca Visual
 
Ruby On Rails Regis
Ruby On Rails RegisRuby On Rails Regis
Ruby On Rails Regis
 
Debugging tips and tricks
Debugging tips and tricksDebugging tips and tricks
Debugging tips and tricks
 
TDD do seu jeito
TDD do seu jeitoTDD do seu jeito
TDD do seu jeito
 
Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)
 

Mehr von Tiago Albineli Motta

Challenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXChallenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXTiago Albineli Motta
 
Inteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosInteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosTiago Albineli Motta
 
Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Tiago Albineli Motta
 
Machine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorMachine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorTiago Albineli Motta
 
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayMachine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayTiago Albineli Motta
 
A ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoA ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoTiago Albineli Motta
 
Recomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comRecomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comTiago Albineli Motta
 
Testes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTestes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTiago Albineli Motta
 

Mehr von Tiago Albineli Motta (18)

Multi Armed Bandit
Multi Armed BanditMulti Armed Bandit
Multi Armed Bandit
 
Challenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLXChallenges and research for a real-time recommendation at OLX
Challenges and research for a real-time recommendation at OLX
 
Inteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dadosInteligência Artificial: Da ciência da computação à ciência de dados
Inteligência Artificial: Da ciência da computação à ciência de dados
 
Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)Machine Learning no dia a dia do desenvolvedor (Atualizado)
Machine Learning no dia a dia do desenvolvedor (Atualizado)
 
Machine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedorMachine Learning no dia a dia do desenvolvedor
Machine Learning no dia a dia do desenvolvedor
 
Experimentation anti patterns
Experimentation anti patternsExperimentation anti patterns
Experimentation anti patterns
 
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlayMachine Learning e experimentos online para evitar o cancelamento no GloboPlay
Machine Learning e experimentos online para evitar o cancelamento no GloboPlay
 
A ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendaçãoA ciência de dados por traz de sistemas de recomendação
A ciência de dados por traz de sistemas de recomendação
 
xCLiMF
xCLiMFxCLiMF
xCLiMF
 
Rastros digitais
Rastros digitaisRastros digitais
Rastros digitais
 
Big data
Big dataBig data
Big data
 
Recomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.comRecomendação de ponta a ponta na Globo.com
Recomendação de ponta a ponta na Globo.com
 
Recomendação na Globo.com
Recomendação na Globo.comRecomendação na Globo.com
Recomendação na Globo.com
 
Otimizando seu projeto Rails
Otimizando seu projeto RailsOtimizando seu projeto Rails
Otimizando seu projeto Rails
 
Meta-programacao em python
Meta-programacao em pythonMeta-programacao em python
Meta-programacao em python
 
Testes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e PorqueTestes unitários e de integração: Quando e Porque
Testes unitários e de integração: Quando e Porque
 
Dinamizando Sites Estáticos
Dinamizando Sites EstáticosDinamizando Sites Estáticos
Dinamizando Sites Estáticos
 
Escalando Sites com Nginx
Escalando Sites com NginxEscalando Sites com Nginx
Escalando Sites com Nginx
 

Redis na prática: exemplos e OCLs

  • 1. Redis na prática O ruim, o bom e o sensacional    
  • 2. Benchmark 3 processos / 20 mil inserções / 60 mil selects ordenados / 60 mil counts > time ./manage.py benchmark --db=redis real 2m32.417s user 2m27.341s sys 0m3.112s > time ./manage.py benchmark --db=mysql real 16m25.251s user 0m46.115s sys 0m4.628s > time ./manage.py benchmark --db=mongodb ^C KeyboardInterrupt real 38m28.659s user 0m59.056s sys 0m2.628s    
  • 3. Benchmark Nunca confie no Benchmark dos outros!    
  • 4. Exemplos Tornar-se fã Crawler de vídeo Responder Quiz Ranking do Quiz    
  • 5. Exemplos 1: Tornar-se Fã Muitas consolidações a cada novo fã Rapidez para não bloquear processos    
  • 6. Consolidações tasks NewFanTask TaskManager NewFanTask gunicorn NewFanTask ArtistTaskGroup    
  • 7. Fila para consolidações redis> rpush tasks oi redis> rpush tasks tudo redis> rpush tasks bem redis> lpop tasks "oi" redis> lpop tasks "tudo" redis> lpop tasks "bem" redis> lpop tasks (nil)    
  • 8. Cuidado: Fila virando Pilha redis> rpush tasks oi redis> rpush tasks tudo redis> rpush tasks bem redis> rpop tasks "bem" redis> rpop tasks "tudo" redis> rpop tasks "oi" redis> rpop tasks (nil)    
  • 9. Abstraindo a fila class RedisQueue(object): def __init__(self,key,client=client): self.key = key self.client = client def push(self,obj): value = ujson.encode(obj) self.client.rpush(self.key, value) def pop(self): value = self.client.lpop(self.key) return self.from_json(value)    
  • 10. Porque não? Resque / Pyres Redis Pub/Sub    
  • 11. Exemplo 2: Crawler de vídeo Dois milhões de músicas Restrição da API do Youtube Busca de vídeos no browser Processamento no server Prioridade pros mais acessados    
  • 12. SortedSet redis> zincrby crawler-video 1 video1 redis> zincrby crawler-video 1 video1 redis> zincrby crawler-video 1 video2 redis> zincrby crawler-video 8 video3 redis> zrevrange crawler-video 0 -1 1) "video3" 2) "video1" 3) "video2" redis> zrevrank crawler-video video3 (integer) 0    
  • 13. Abstraindo SortedSet class RedisSortedSet(object): def __init__(self,key,client=client): self.key = key self.client = client def incr(self,value,amount=1): return self.client.zincrby(self.key, value, amount) def bests(self,max=0): return self.client.zrevrange(self.key, 0, max-1)    
  • 14. Exemplo 3: Responder Quiz Gravar se acertou ou não Impedir responder mesma pergunta    
  • 15. Utilizando Sets def responder(self, quiz, resposta): respondidas = RedisSet(”quiz-respondidos-%s” % self.id, client=redis) if respondidas.add(quiz.id): if quiz.opcao_correta(resposta): acertadas = RedisSet(”quiz-acertadas-%s” % self.id, client=redis) acertadas.add(quiz.id) redis> sadd quiz-respondidos-x 1 (integer) 1 redis> sadd quiz-acertadas-x 1 (integer) 1 redis> sadd quiz-respondidos-x 1 (integer) 0    
  • 16. Hash redis> hset estados-capitais amazonas manaus redis> hset estados-capitais bahia salvador redis> hgetall estados-capitais 1) "amazonas" 2) "manaus" 3) "bahia" 4) "salvador" redis> hset estados-capitais amazonas belem redis> hgetall estados-capitais 1) "amazonas" 2) "belem" 3) "bahia" 4) "salvador" redis> hsetnx estados-capitais bahia recife redis> hgetall estados-capitais 1) "amazonas" 2) "belem" 3) "bahia" 4) "salvador"    
  • 17. Utilizando Hash def responder(self, quiz, resposta): respondidos = RedisHash(”quiz-respondidos-%s” % self.id, client=redis) acertou = 1 if quiz.opcao_correta(resposta) else 0 respondidos.set_if_new(quiz.id, acertou) redis> hsetnx quiz-respondidos-x 20 0 (integer) 1 redis> hsetnx quiz-respondidos-x 20 1 (integer) 0    
  • 18. Exemplo 4: Ranking do Quiz Sugestões?    
  • 19. Exemplo 4: Ranking do Quiz Sugestões? SortedSet?    
  • 20. Exemplo 4: Ranking do Quiz Ranking dos amigos? 1 ranking por usuário Atualizar rankings a cada resposta?    
  • 21. Fila e SortedSet Ao responder um quiz: redis> rpush tasks rankings-quiz-usuario-x Cron: redis> lpop tasks "rankings-quiz-usuario-x" redis> smembers amigos-usuario-x 1) "a" 2) "b" 3) "c" redis> hval respostas-usuario-x 1) "1" 2) "1" 3) "0" redis> zadd ranking-usuario-x 2 usuario-x redis> zadd ranking-usuario-a 2 usuario-x redis> zadd ranking-usuario-b 2 usuario-x redis> zadd ranking-usuario-c 2 usuario-x    
  • 22. Muito complexo? Porque não MySql?    
  • 23. Cansei de exemplos Vamos falar de OCLs    
  • 24. OCLs: Multi / Exec redis> multi redis> zadd ranking-usuario-x 2 usuario-x redis> zadd ranking-usuario-a 2 usuario-x redis> zadd ranking-usuario-b 2 usuario-x redis> zadd ranking-usuario-c 2 usuario-x redis> exec redis = Redis(**confs).pipeline() for id in [id, ”a”,”b”,”c”]: sorted_set = RedisSortedSet(”ranking-usuario-%s” % id, client=redis) sorted_set.add(”usuario-x”,amount=2) redis.execute()    
  • 25. OCLs: Multi / Exec redis> multi redis> hsetnx respostas-usuario-id quiz-1 1 redis> rpush tasks rankings-quiz-usuario-x redis> exec acertou = 1 if pergunta.certa == resposta else 0 redis = Redis(**confs).pipeline() hash = RedisHash(”respostas-usuario-%s” % usuario.id, client=redis) hash.set_if_new(”quiz-” % pergunta.id, acertou): if acertou: queue = RedisQueue(”tasks”, client=redis) queue.push(”ranking-quiz-usuario-%s” % usuario.id) redis.execute()    
  • 26. OCLs: Master / Slave > sudo vim /etc/redis/redis-slave.conf port 6380 slaveof 127.0.0.1 6739 > sudo redis-server /etc/redis/redis-slave.conf > redis-cli redis> monitor OK 1335985598.138718 "monitor" 1335986003.209676 "SYNC"    
  • 27. OCLs: Master / Slave > redis-cli redis 127.0.0.1:6379> set x b > redis-cli -h 127.0.0.1 -p 6380 redis 127.0.0.1:6380> monitor OK 1335986423.169745 "monitor" 1335986441.430632 "PING" 1335986441.430632 "PING" 1335986462.113501 "set" "x" "b" 1335986471.500976 "PING"    
  • 28. OCLs: Script em lua Redis 2.6: redis> eval "return {ARGV[1]}" valor Ainda não usei, por isso não vou falar nada.    
  • 29. Conclusão Performático Escalável Divertido No entando... + Complexo que Sql e Mongo