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

Buscando Dados do DynamoDb via ElasticSearch em Tempo Real

Buscando Dados do DynamoDb via ElasticSearch em Tempo Real

Nesta apresentação, eu faço um overview de uma arquitetura criada para fazer buscas em tempo real via Elasticsearch no DynamoDB.
Você vai ver:
Snippets de Código!
Dicas para o desenvolvimento!
Como resolver problemas comuns!

Claudio Davi Souza

April 17, 2019
Tweet

Other Decks in Programming

Transcript

  1. Claudio Davi • Engenheiro de Software ◦ Softexpert (2 anos)

    ◦ Universidade (6 anos) • Especialização em Big Data & Data Science ◦ PUC (2 Anos) • Machine Learning Aplicado ◦ Hobby (2 anos) ◦ Profissional (6 meses) • Python ◦ Hobby (2 anos) ◦ Profissional (6 meses) Cientista de Dados e Engenheiro de Machine Learning @ Gofind
  2. O PROBLEMA Descrição Tornar acessível via busca alguns dados da

    nossa plataforma com alta disponibilidade e alto potencial de personalização nas buscas. Requisitos • Novos dados devem ficar disponíveis em Near Real Time • É necessário fazer buscas por Latitude Longitude • É necessário filtrar elementos por características
  3. ARQUITETURA - OVERVIEW DynamoDb • NoSQL Wide Column • Rápido

    • Preço On Demand • Escalável • Serverless Python • Serverless • Suporte Oficial • Boto3 • Dev Friendly ElasticSearch • Robusto • Barato • GeoSearch • Fácil de Criar Queries • Nativo na AWS
  4. PYTHON • Serverless Frameworks: ◦ Chalice ◦ Zappa ◦ Serverless

    Framework • Serverless Framework: ◦ Time já usa com JS ◦ Fácil Customização de Configuração ◦ Teste local da função ◦ Minimização de pacote
  5. Setting Up • Primeiro: Mapeamento dos dados no ElasticSearch ◦

    Pensar sempre nas queries que serão executadas, não na estrutura dos dados existentes ◦ Pense: Como serão as consultas? Quais os dados precisam ser retornados? Faz sentido trazer isso dessa forma? ◦ É muito provável que haverá bastante processamento antes de subir os dados do Dynamo para o ES ◦ É ainda necessário via Kibana ou outra interface, criar o mapeamento e o index. Nossa sorte que isso é bem simples em python!
  6. Conectando no ES def connect(): service = 'es' credentials =

    boto3.Session().get_credentials() awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, os.environ.get( 'region'), service) es = Elasticsearch( hosts=[{'host': os.environ.get( 'host'), 'port': 443}], http_auth=awsauth, use_ssl=True, verify_certs=True, connection_class =RequestsHttpConnection, timeout=60, retry_on_timeout =True, max_retries=10 ) return es
  7. Criando Mapeamento! def create_index(es_client: Elasticsearch, path_to_mapping: str) -> dict: with

    open(path_to_mapping) as file: mapping = json.loads(file.read()) return es_client.indices.create( index='stores', body=mapping)
  8. Setting Up • Depois de arrumar o ES e escolher

    os dados, no DynamoDb é necessário ativar Stream da tabela que será assistida. ◦ Recomendação, criar uma função e fazer upload dela vazia que retorna o event pra teste, pra saber os tipos de dados que entram.
  9. Setting Up • Nessa função, vamos ler os dados do

    dynamodb e decidir o tipo de operação. ◦ REMOVE ◦ MODIFY ◦ INSERT • Cada operação necessita da sua própria implementação. ◦ É importante lembrar que o evento do Dynamo apenas retorna a chave do registro, então você vai ter que fazer a consulta de novo!
  10. Função de Criação e Remoção de Itens def create_item(es: Elasticsearch,

    key: str) -> None: table = dynamodb.Table( 'table_name') item = table.get_item( KEY={'key':key}).get('Item') item_mapped = map_to_es(item) #Implementação sua es.index(index='index_name', doc_type='_doc', body =item_mapped, id=item['id']) def map_to_es(item: dict) -> dict: return item def delete_item(es: Elasticsearch, key: str) -> None: es.delete(index='index_name', doc_type='_doc', id=key, refresh=True)
  11. Função de Atualização de Itens def update_item(es: Elasticsearch, key: str)

    -> None: table = dynamodb.Table( 'table_name') item = table.get_item( KEY={'key':key}).get('Item') res = es.search(index='index_name', doc_type='_doc', body=query(key=key)) es_item = res.get('hits').get('hits')[0].get('_source') new_item = map_to_es(item) updated = {**es_item, **new_item} es.index(index='index_name', doc_type='_doc', body=updated, id=item['id']) def query(key: str) -> dict: return {"query": {"match": {"id": key}}}
  12. Conectando Tudo! • Publicar a função serverless no lambda. ◦

    sudo sls deploy • No console do Lambda ativar a trigger do DynamoDb e selecionar a stream • Assistir os logs do lambda e verificar no elasticsearch. • Vai falhar algumas vezes!
  13. Problemas no caminho... • Documentação da Amazon! • Mapeamento dos

    campos do Elasticsearch • Documentação da Amazon. • O Logger do lambda não te diz nada! Use o Logging nativo. • Documentação da Amazon. • Os tipos de processamento podem variar muito!