Escalando sua aplicação para suportar milhões
Not only SQL
Not only SQL
Outro tipo de estruturação de dados, diferente da tabular vista nos bancos de dados relactionais
Você dá a Key(Chave) junto com o Value(valor) para aquela Key
Você dá a Key(Chave) junto com o Value(valor) para aquela Key
'nome' : 'Daniela'
Seu armazenamento principal é feito na memória RAM
E por quê eu quero meu banco de dados In-Memory?
Aqui está um exemplo de uma operação típica em um MySQL
Agora imagine uma aplicação enviando 1 milhão de requisições onde serão realizadas escritas no Banco de Dados
Como o seu sistema irá reagir ao ver que terá que fazer 1kkk disk I/O de vez
Disk I/O é uma operação extremamente custosa
Gargalo
Em situações de fluxo elevado, isso significa: lentidão, Crashes, Usuários Insatisfeitos
Em situações como essa, Redis e sua tecnologia in-memory é o que irá salvar.
Em situações como essa, Redis e sua tecnologia in-memory é o que irá salvar.
"Mas se eu reiniciar a máquina, vou perder minhas informações? Afinal, memória RAM é volátil"
"Mas se eu reiniciar a máquina, vou perder minhas informações? Afinal, memória RAM é volátil"
A estratégia não é substituir o MySQL pelo Redis. A ideia é adiciona-lo na sua stack.
+
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
O papel do Redis é de Memoria Cache
Redis como Memória Cache
Redis até agora:
Redis até agora:
Redis até agora:
Redis até agora:
Redis até agora:
E não para por aí.
Data Structure Server
Data Structure Server
Data Structure Server
> set nome daniela
OK
> get nome
"daniela"
Data Structure Server
List
List
List
List
List
List
> rpush minha_lista rodrigo
(integer) 1
> rpush minha_lista daniela
(integer) 2
> rpush minha_lista lucas
(integer) 3
> rpush minha_lista nadson
(integer) 4
> lrange minha_lista 0 -1
1) "rodrigo"
2) "daniela"
3) "lucas"
4) "nadson"
Sets (conjuntos)
Sets (conjuntos)
Sets (conjuntos)
Sets (conjuntos)
Ordered Sets
Ordered Sets
Ordered Sets
Ordered Sets
Hashes
Hashes
Hashes
Hashes
HMSET user:1000 username antirez password P1pp0 age 34
HGETALL user:1000
HSET user:1000 password 12345
HGETALL user:1000
Hashes
HMSET user:1000 username antirez password P1pp0 age 34
HGETALL user:1000
HSET user:1000 password 12345
HGETALL user:1000
O quão rápido é o Redis?
Redis-Benchmark
Simulando 100mil requests
$ redis-benchmark -t set,lpush -n 100000 -q
Simulando 100mil requests
$ redis-benchmark -t set,lpush -n 100000 -q
SET: 74239.05 requests per second
LPUSH: 79239.30 requests per second
Simulando 100mil requests
$ redis-benchmark -t set,lpush -n 100000 -q
SET: 74239.05 requests per second
LPUSH: 79239.30 requests per second
Voltando ao uso do Redis como Cache....
Implementando um simples Redis Cache
Implementando um simples Redis Cache
Implementando um simples Redis Cache
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:sa@localhost/bancodedados2'
db = SQLAlchemy(app)
cache = redis.StrictRedis(host='localhost', port=6379, db=0)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80))
email = db.Column(db.String(120))
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
def createUsers():
with Timer(verbose=True) as t:
for x in xrange(0,100000):
user = User('teste', 'teste')
db.session.add(user)
db.session.commit()
def getUsers():
with Timer(verbose=True) as t:
users = cache.get('users')
if not users:
users = User.query.all()
cache.set('users', users)
@app.route('/')
def hello_world():
getUsers()
return 'Hello Worldd!'
if __name__ == '__main__':
app.debug=True
app.run(host='0.0.0.0')
O que irá acontecer?
1º Request: Buscar um número enorme de registros no MySQL e depois adicionar no Redis
1º Request: Buscar um número enorme de registros no MySQL e depois adicionar no Redis
Tempo para retornar os dados: 45861 millisegundos
2º Request: Usuário buscando os mesmo dados, dessa vez ele já está no Redis Cache
2º Request: Usuário buscando os mesmo dados, dessa vez ele já está no Redis Cache
Tempo para retornar os dados: 5 millisegundos
2º Request: Usuário buscando os mesmo dados, dessa vez ele já está no Redis Cache
Tempo para retornar os dados: 5 millisegundos
45861 millisegundos
->
5 millisegundos
45861 millisegundos
->
5 millisegundos
9172 vezes mais rápido que o acesso ao MySQL
Quem está usando o Redis?
JusBrasil
Maior rede social jurídica do Brasil
JusBrasil
Maior portal de informação pública
JusBrasil
12 milhões de usuários
1 milhão de acessos diários
JusBrasil
Milhares de documentos extraídos do diário oficial
JusBrasil
Milhares de documentos extraídos do diário oficial
Todos os dias.
JusBrasil
Uso agressivo de Redis Caching em diversos módulos do Sistema
JusBrasil
Uso agressivo de Redis Caching em diversos módulos do Sistema
Transformando minutos em segundos.
E muito mais
Redis é Open Source
Embrace Open Source Software!
Long Live Open Source Software
Perguntas?
Obrigado!
Rodrigo Araújo
@digorithm
BSc. Computer Science
Lucas Santos
@ll_ucasn
BSc. Computer Science
Nadson
@seucontato
BSc. Computer Science