Uma das maneiras de aliviar a tensão em um servidor é armazenar dados em cache. Isso é feito armazenando os dados em cache depois de processados e, em seguida, servindo-os do cache na próxima vez que forem solicitados. Este tutorial fornecerá uma discussão detalhada sobre o Redis, explicando como instalar o Redis e armazenar dados em cache em aplicativos Python.
Introdução ao Redis e Caching
O armazenamento em cache refere-se ao armazenamento da resposta do servidor no próprio cliente, para que um cliente não precise fazer uma solicitação do servidor para o mesmo recurso repetidas vezes. Uma resposta do servidor deve ter informações sobre como o armazenamento em cache deve ser feito, para que um cliente armazene a resposta em cache por um período de tempo ou nunca armazene em cache a resposta do servidor.
Um cache, por outro lado, é um componente de hardware ou software usado para armazenar dados para que solicitações futuras dos mesmos dados possam ser atendidas mais rapidamente.
Nesta era em que os usuários esperam resultados em um segundo, é aconselhável atender às solicitações lendo os dados do cache, que é mais rápido do que ler de um armazenamento de dados mais lento; portanto, o desempenho do sistema depende de quantas solicitações podem ser atendidas pelo cache.
O Redis é um armazenamento de estrutura de dados na memória de código aberto, usado como banco de dados, cache e agente de mensagens. Ele funciona armazenando dados em um cache e fornecendo-os na próxima vez que forem solicitados, em vez de consultar o banco de dados todas as vezes.
Instalar o Redis
O Redis já está incluído no repositório de pacotes oficial do Ubuntu. Para instalar a versão mais recente do servidor Redis, execute os seguintes comandos um após o outro.
1 |
sudo apt-get update |
2 |
sudo apt install redis |
Depois de instalar o Redis, você pode verificar sua versão com o seguinte comando:
Se você estiver no Windows, poderá executar o Redis usando o Windows Subsystem for Linux, também conhecido como WSL2. O WSL2 basicamente permite executar um ambiente Linux (ferramentas de linha de comando, utilitários, aplicativos, etc.) diretamente em sua máquina Windows.
Para instalar e executar o Redis no Windows, primeiro você precisará executar o seguinte comando em seu terminal Powershell local para habilitar o Windows Subsystem for Linux (certifique-se de executar isso como administrador):
1 |
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux |
Em seguida, abra a Microsoft Store em sua máquina Windows, procure por ubuntu e instale-o. Isso lhe dá acesso ao terminal do Ubuntu, onde você executará o comando para instalar o Redis.
Depois que o Ubuntu estiver instalado, inicie o terminal e digite seu nome de usuário e senha do UNIX. Em seguida, execute estes três comandos em sucessão para instalar o Redis:
1 |
sudo apt-add-repository ppa:redislabs/redis
|
2 |
sudo apt-get update
|
3 |
sudo apt-get upgrade
|
4 |
sudo apt-get install redis-server |
Execute o seguinte comando para iniciar seu servidor:
1 |
sudo service redis-server restart
|
Exemplo de API do Django
Vamos criar nosso projeto Django. Nosso projeto será capaz de armazenar em cache todos os produtos de uma loja, facilitando e agilizando a recuperação de dados em consultas subsequentes.
Para fazer uso do Redis em nosso aplicativo, precisamos fazer o seguinte:
- Verifique se os resultados da consulta atual existem no cache.
- Se houver resultados no cache, recupere-os.
- Se os resultados não existirem, busque-os, armazene-os no cache e, em seguida, encaminhe-os para a entidade solicitante.
Requisitos
- Django
- django-redis
- Redis
- teste de carga
Crie Seu Projeto
Antes de começarmos, crie um diretório e instale um ambiente virtual. Um ambiente virtual permitirá que você instale as versões de biblioteca exigidas pelo seu aplicativo.
1 |
mkdir myprojects
|
2 |
|
3 |
cd myprojects
|
Em seguida, ative o ambiente virtual e instale os requisitos do projeto.
1 |
source venv/bin/activate
|
2 |
|
3 |
pip install django==1.9 |
4 |
|
5 |
pip install django-redis
|
6 |
|
7 |
pip install djangorestframework
|
Criar um projeto Django
1 |
django-admin startproject django_cache |
Crie um novo aplicativo chamado store, que fará o gerenciamento de produtos em nossa loja.
1 |
cd django_cache
|
2 |
|
3 |
python manage.py startapp store |
Adicione o aplicativo da loja e rest_framework à lista de aplicativos instalados no settings.py
Arquivo.
1 |
# settings.py
|
2 |
INSTALLED_APPS = [ |
3 |
'django.contrib.admin', |
4 |
'django.contrib.auth', |
5 |
'django.contrib.contenttypes', |
6 |
'django.contrib.sessions', |
7 |
'django.contrib.messages', |
8 |
'django.contrib.staticfiles', |
9 |
'store', # add here |
10 |
'rest_framework', # add here too |
11 |
]
|
Criando os modelos
No store/models.py
começamos criando o modelo Product para armazenar os detalhes do produto da seguinte maneira:
1 |
from __future__ import unicode_literals |
2 |
from django.db import models |
3 |
import datetime |
4 |
|
5 |
# Create your models here.
|
6 |
|
7 |
|
8 |
class Product(models.Model): |
9 |
|
10 |
name = models.CharField(max_length=255) |
11 |
description = models.TextField(null=True, blank=True) |
12 |
price = models.IntegerField(null=True, blank=True) |
13 |
date_created = models.DateTimeField(auto_now_add=True, blank=True) |
14 |
date_modified = models.DateTimeField(auto_now=True, blank=True) |
15 |
|
16 |
def __unicode__(self): |
17 |
return self.name |
18 |
|
19 |
def to_json(self): |
20 |
return { |
21 |
'id': self.id, |
22 |
'name': self.name, |
23 |
'desc': self.description, |
24 |
'price': self.price, |
25 |
'date_created': self.date_created, |
26 |
'date_modified': self.date_modified |
27 |
}
|
Migrações
Crie uma migração inicial para nosso modelo de produtos e sincronize o banco de dados pela primeira vez.
1 |
python manage.py makemigration store |
2 |
|
3 |
python manage.py migrate |
Criar superusuário
Crie um superusuário, faça login no painel de administração e preencha seu banco de dados com alguns dados de amostra que usaremos para fazer nossos testes.
1 |
python manage.py createsuperuser |
Configurando o Redis em aplicativos Python
Para usar o Redis com um aplicativo Django, precisamos configurar o Redis para armazenar os dados de cache do aplicativo. E o seguinte para o seu settings.py
Arquivo:
1 |
CACHES = { |
2 |
'default': { |
3 |
'BACKEND': 'django_redis.cache.RedisCache', |
4 |
'LOCATION': 'redis://127.0.0.1:6379/', |
5 |
'OPTIONS': { |
6 |
'CLIENT_CLASS': 'django_redis.client.DefaultClient', |
7 |
}
|
8 |
}
|
9 |
}
|
Em seguida, vamos criar um endpoint que recupere todos os produtos do nosso banco de dados. Primeiro, testaremos o desempenho do aplicativo em termos de quanto tempo leva para recuperar dados do banco de dados sem armazená-los em cache. Em seguida, implementaremos outro endpoint que recupera dados de um cache e comparamos o desempenho.
No store/views.py
adicione o seguinte código que recupera todos os produtos presentes no banco de dados.
1 |
from django.shortcuts import render |
2 |
from rest_framework.decorators import api_view |
3 |
from rest_framework.response import Response |
4 |
from rest_framework import status |
5 |
|
6 |
# Create your views here.
|
7 |
|
8 |
|
9 |
|
10 |
@api_view(['GET']) |
11 |
def view_books(request): |
12 |
|
13 |
products = Product.objects.all() |
14 |
results = [product.to_json() for product in products] |
15 |
return Response(results, status=status.HTTP_201_CREATED) |
Configurando URLs
Criar um arquivo store/urls.py
e adicione o seguinte código.
1 |
# store/urls.py
|
2 |
from django.conf.urls import url |
3 |
from .views import view_books |
4 |
|
5 |
|
6 |
urlpadrões = [ |
7 |
url(r'^$', view_books), |
8 |
]
|
Também precisamos importar URLs do aplicativo de usuários para o principal django_cache/urls.py
Arquivo.
1 |
# django_cache/urls.py
|
2 |
|
3 |
from django.conf.urls import url, include |
4 |
from django.contrib import admin |
5 |
|
6 |
urlpadrões = [ |
7 |
url(r'^admin/', admin.site.urls), |
8 |
url(r'^store/', include('store.urls')) |
9 |
]
|
Vamos fazer um teste e ver se estamos no caminho certo. Estaremos usando loadtest. Se você não estiver familiarizado com loadtest, é uma ferramenta para testar o desempenho.
Instalar loadtest como root é simples:
1 |
sudo npm install -g loadtest |
1 |
$ loadtest -n 100 -k https://localhost:8000/store/ |
2 |
|
3 |
# result
|
4 |
INFO Requests per second: 55 |
5 |
As seen from the above, 55 requests are processed per second.
Let’s create another endpoint for retrieving data after caching with Redis. Edit users/views.py
to match the following:
1 |
from rest_framework.decorators import api_view |
2 |
from rest_framework import status |
3 |
from rest_framework.response import Response |
4 |
from django.core.cache import cache |
5 |
from django.conf import settings |
6 |
from django.core.cache.backends.base import DEFAULT_TIMEOUT |
7 |
|
8 |
CACHE_TTL = getattr(settings, 'CACHE_TTL', DEFAULT_TIMEOUT) |
9 |
from .models import Product |
10 |
|
11 |
|
12 |
# Create your views here.
|
13 |
|
14 |
|
15 |
@api_view(['GET']) |
16 |
def view_books(request): |
17 |
# rest of the code
|
18 |
|
19 |
|
20 |
@api_view(['GET']) |
21 |
def view_cached_books(request): |
22 |
if 'product' in cache: |
23 |
# get results from cache
|
24 |
products = cache.get('product') |
25 |
return Response(products, status=status.HTTP_201_CREATED) |
26 |
|
27 |
else: |
28 |
products = Product.objects.all() |
29 |
results = [product.to_json() for product in products] |
30 |
# store data in cache
|
31 |
cache.set(product, results, timeout=CACHE_TTL) |
32 |
return Response(results, status=status.HTTP_201_CREATED) |
33 |
The code above will check if the key product is present in the cache, and if found, the data represented will be returned to the browser. In the event that no data is present in the cache, we first retrieve the data from the database, store it in the cache, and then return the data queried to the browser.
Update store/urls.py
as follows.
1 |
from django.conf.urls import url |
2 |
from .views import view_books, view_cached_books |
3 |
|
4 |
|
5 |
urlpadrões = [ |
6 |
url(r'^$', view_books), |
7 |
url(r'^cache/', view_cached_books), |
8 |
|
9 |
]
|
Vamos fazer os testes.
1 |
$ loadtest -n 100 -k http://localhost:8000/store/cache/ |
2 |
|
3 |
# results
|
4 |
INFO Requests per second: 233 |
5 |
|
6 |
Na primeira vez que você acessar o endpoint localhost:8000/store/cache, o aplicativo consultará o banco de dados e retornará os dados, mas as chamadas subsequentes para a URL ignorarão o banco de dados e consultarão o cache, pois os dados já estão disponíveis no cache .
Conclusão
Neste tutorial, usamos o Redis para dar a um aplicativo a ilusão de velocidade. Aproveitamos o uso de RAM no Redis para armazenar os resultados das consultas e, em seguida, retornamos esses resultados do cache nas consultas subsequentes, em vez de fazer a viagem de ida e volta ao banco de dados.
Existem outras ferramentas de cache disponíveis, como o Memcached, que é semelhante ao Redis. No entanto, o Redis é mais popular do que o Memcached porque leva apenas alguns minutos para configurar e começar a trabalhar nos aplicativos. O Redis possui mecanismos mais sofisticados, pois foi descrito como um “armazenamento de estrutura de dados”, tornando-o mais poderoso e flexível. O Redis também tem uma vantagem maior porque você pode armazenar dados em qualquer formato.
Espero que este tutorial tenha mostrado como é fácil adicionar uma camada de cache ao seu aplicativo, melhorando assim o desempenho. O armazenamento em cache deve ser algo a ser considerado quando você precisa reduzir o tempo de carregamento e os custos do servidor.
Poste a imagem em miniatura gerada pelo OpenAI DALL-E.