Você vai aprender duas técnicas para armazenar e recuperar dados. Ao escolher qual método usar em seu aplicativo, selecione o que simplifique sua arquitetura com base em seus padrões de acesso de dados.
Mas antes, não esqueça de conectar-se ao Redis.
Tempo para a conclusão do módulo: 60 minutos
sintaxe: shell
$ python
Caso o comando trave, consulte a observação após o exemplo.
sintaxe: python
syntax: python >>> import redis >>> client = redis.Redis.from_url('redis://endpoint:6379') >>> client.ping() True
Obs.: caso o comando trave, isso significa que você está sendo bloqueado pelas configurações de Grupos de segurança. Verifique se a instância do EC2 tem acesso ao grupo de segurança atribuído à sua instância do ElastiCache. Por exemplo, digamos que sua instância do EC2 foi atribuída ao grupo de segurança padrão. Agora você pode modificar o grupo de segurança de sua instância do Amazon ElastiCache e adicionar uma regra TCP personalizada permitindo conexões na porta 6379 com origem em qualquer instância que esteja no grupo de segurança padrão:
Em Origem, você pode começar a digitar o nome do grupo de segurança e também será possível clicar no ID do Grupo de segurança. Caso precise aprender mais sobre Grupos de segurança, você pode conferir a documentação ou a Referência de regras de grupos de segurança.
No repositório você vai encontrar um código em Python que pode executar em sua instância do EC2. Porém, antes é necessário configurar algumas variáveis de ambiente:
sintaxe: shell
$ export REDIS_URL=redis://your_redis_endpoint:6379/ $ export DB_HOST=your_mysql_endpoint $ export DB_USER=admin $ export DB_PASS=your_admin_password $ export DB_NAME=tutorial
Observe que os valores para mysql_endpoint, redis_endpoint e password são os valores que você salvou nas etapas anteriores.
O primeiro dos dois métodos implementados no exemplo de código funciona ao armazenar em cache uma representação serializada do resultado da consulta SQL. O trecho de código em Python abaixo ilustra a lógica:
sintaxe: python
def fetch(sql): result = cache.get(sql) if result: return deserialize(result) else: result = db.query(sql) cache.setex(sql, ttl, serialize(result)) return result
Primeiramente, a instrução SQL é usada como uma chave no Redis e o cache é inspecionado para verificar se há um valor presente. Caso um valor não esteja presente, a instrução SQL é usada para consultar o banco de dados. O resultado da consulta ao banco de dados é armazenado no Redis. De acordo com a natureza de seu aplicativo, a variável ttl (vida útil) precisa estar definida com um valor sensível. Quando a ttl expira, o Redis remove a chave e libera a memória associada. Esse código está disponível no repositório do tutorial e você pode executá-lo sem alterações, mas sinta-se à vontade para acrescentar instruções de impressão ocasionais caso deseje visualizar o valor de uma variável em determinado momento.
Em termos de estratégia, a desvantagem dessa abordagem é que ao haver alterações de dados no banco de dados, as alterações não serão refletidas automaticamente para o usuário se houver um resultado anterior armazenado em cache e sua ttl ainda não tiver expirado.
Veja um exemplo de como você usaria a função de busca:
sintaxe: python
print(fetch("SELECT * FROM planet"))
O resultado seria:
sintaxe: python
[{'id': 10, 'name': 'Mercury'}, {'id': 11, 'name': 'Venus'}, {'id': 12, 'name': 'Earth'}, {'id': 13, 'name': 'Mars'}, {'id': 14, 'name': 'Jupiter'}, {'id': 15, 'name': 'Saturn'}, {'id': 16, 'name': 'Uranus'}, {'id': 17, 'name': 'Neptune'}]
Obviamente este é um exemplo bastante básico, mas seu aplicativo pode obter grandes benefícios com a implementação desse padrão de armazenamento em cache quando não houver diferença entre um resultado que venha do cache e um resultado que venha diretamente do banco de dados.
O segundo exemplo que você vai implementar mapeia um registro de banco de dados para um hash do Redis:
sintaxe: python
def planet(id): key = "planet:" + str(id) result = cache.hgetall(key) if result: return result else: sql = "SELECT `id`, `name` FROM `planet` WHERE `id`=%s" result = db_record(sql, (id,)) if result: cache.hmset(key, result) cache.expire(key, ttl) return result
O keyspace no Redis é invariável, mas há uma convenção para simular uma estrutura usando strings separadas por dois pontos (:). No exemplo, a chave para o registro com ID 1 será “planet:1”. Embora esse trecho seja suficientemente bom para exibir um padrão comum, é possível alcançar uma maior abstração: um módulo pode ficar responsável por gerar as chaves e outro pode cuidar da criação da string SQL etc. Além disso, é possível que existam ferramentas criadas com essa finalidade na linguagem de programação que você usa.
O exemplo recupera registros do cache ou do banco de dados, e da mesma forma, poderia haver uma função responsável pela persistência de um objeto no banco de dados.
Nos dois exemplos, você usou uma vida útil ou ttl, após o qual o Redis remove a chave. Embora isso seja suficientemente bom na maioria dos casos, talvez seja interessante remover os dados velhos do cache assim que for possível. Se esse for seu caso de uso, não esqueça de verificar outras opções, como a estratégia de gravação no armazenamento em cache. Ao fim do tutorial fornecemos links para mais informações. É importante mencionar, caso esteja curioso: embora os exemplos usem o comando EXPIRE, o Redis também oferece o EXPIREAT, que permite especificar data e hora exatos para a remoção de uma chave. Ele usa um carimbo de data/hora absoluto do Unix como parâmetro (ou seja, segundos decorridos desde 1.º de janeiro de 1970).
Quando a quantidade de dados ultrapassa a configuração maxmemory definida, o Redis tem maneiras diferentes de responder de acordo com a política de remoção selecionada. Por padrão, o ElastiCache para Redis é configurado para remover da memória as chaves menos utilizadas recentemente que tenham uma ttl definida. O parâmetro de política de remoção é chamado de maxmemory-policy e o valor padrão no ElastiCache é volatile-lru. Outra opção interessante para esse caso de uso é a política volatile-ttl, que instrui o Redis a recuperar memória removendo essas chaves com a ttl mais curta.
Após ter implementado essa estratégia, não esqueça de testar seu aplicativo para descobrir o melhor valor para a ttl e a melhor estratégia de remoção. Verifique a performance do seu aplicativo com um cache vazio e com um cache cheio.