Como conseguimos reduzir nosso cluster de Redshift e aumentar a performance?

Compartilhe

Compartilhar no facebook
Compartilhar no google
Compartilhar no twitter
Compartilhar no linkedin

Usamos o Redshift aqui na Movile há mais de 4 anos e, em meados de Fevereiro do ano passado, decidimos fazer uma reestruturação total de nosso cluster.

Queríamos reduzir em 60% nosso cluster, porém manter um volume de dados semelhante e também uma performance igual ou superior à que tínhamos. 

O Redshift era usado, na época, como a fonte de todas as análises que fazíamos, ou seja, perder performance não era algo que poderia acontecer.

Ousado, não?

A minha ideia aqui é consolidar, em um único artigo, quais foram os principais conceitos e técnicas que aplicamos para atingir nosso objetivo. E ah, sim, nós o alcançamos ! 

Fazendo um review da Arquitetura do Redshift

Captura de Tela 2018-04-24 às 17.57.39

É muito importante conhecer como o Redshift funciona internamente para conseguir fazer as otimizações. O Redshift possui dois tipos de nodes, o Leader Node e o Compute Node.

O primeiro é responsável por receber e coordenar as queries e armazenar os metadados, enquanto o segundo é o que de fato trabalha na execução da sua consulta.

 

 

Captura de Tela 2018-04-24 às 17.59.20

Além dos dois tipos de nodes, o Redshift também possui dois tipos de hardware. Um é otimizado para processamento, o Dense Computing (DC), e o Dense Storage (DS) é otimizado para o armazenamento de dados.

Cada node é dividido internamente em slices, que por sua vez  possui memória e CPU dedicados. Essa configuração também é variável de acordo com o tipo do node e do cluster.

No DC, temos 2 slices em um servidor large e 32 em um x-large, enquanto que no DS temos apenas 2 slices em um x-large.

Cada slice processa paralelamente uma parte do workload, também conhecido como Massive Parallel Processing (MPP).

Por isso, é muito importante você já saber para qual finalidade está criando o seu cluster. Aqui nós utilizamos o DC porque nossa prioridade é aproveitar toda a performance para consolidar nossos dados.

  • E como nós atingimos nosso objetivo?

    Agora explicarei conceitos de performance e tuning que utilizamos para atingir nosso objetivo. 

    Antes de iniciarmos esta task-force, foi muito importante parar e entender como o Redshift funciona internamente, como os dados são distribuídos e ordenados, quais são as melhores práticas e rotinas de manutenção  indicadas.

    Conhecendo os nossos dados e sabendo quais buscas e análises são as mais frequentes, conseguimos reduzir o tamanho das tabelas, em média, 60% e ter uma performance superior de, em média, 40%.

    Começarei falando de distribuição dos dados, depois sobre ordenação e por fim compressão.

    Distribuição dos dados

    O Redshift replica os dados entre seus nodes de acordo com algumas regras, porém você precisa tomar um certo cuidado ao definir essas regras, pois elas estão diretamente ligadas à performance do seu cluster

    O objetivo aqui é minimizar a movimentação de dados e distribuí-los uniformemente para termos ganhos efetivos no processamento paralelo. Existem 3 tipos de distribuição no Redshift:

    • Distribution Style All: Aqui a tabela é replicada em todo node, sempre no primeiro slice. É indicado para tabelas de lookup que sempre são usadas em joins;
    • Distribution Style Even: Neste estilo os dados são distribuídos entre os nodes utilizando o round-robin. Não existe uma regra na distribuição dos dados, é de certa maneira aleatória;
    • Distribution Key: Neste estilo utiliza-se uma coluna para distribuir os dados. É importante levar alguns pontos para defini-la: alta cardinalidade, frequentemente usada em joins e também com os dados uniformes em tamanho.

 

Captura de Tela 2018-04-24 às 18.02.37.png

Ordenação dos dados

Sem dúvida, se você ordenar sua tabela pela(s) coluna(s) que mais usa, você terá um ganho muito grande na performance. 

Existe um conceito chamado Zone-Map, que é algo que o Redshift usa quando seu dado está ordenado de maneira correta dentro dos slices. 

Ele lê o metadado de cada um e verifica o range de max e min dos dados, além de fazer a checagem para ver se precisa ler o dado de fato. Isso te dá um ganho muito grande em performance. Existem três tipos de ordenação:

  • Single: este é o tipo usado quando você define apenas uma coluna. Você deve usar uma coluna que é comumente usada em cláusulas where. É muito importante isso, porque definindo de maneira correta, o Redshift vai conseguir usar, de verdade, as zone-maps..Captura de Tela 2018-04-24 às 18.04.11
  • Compound: aqui você consegue definir até 400 colunas. Fazendo um paralelo com o banco relacional, pense em um índice composto, ou seja, a coluna à esquerda sempre tem precedência em relação às da direita. É assim também que funciona esse tipo de ordenação. É muito bom quando você utiliza group by e/ou order by com as colunas

Captura de Tela 2018-04-24 às 18.05.06

 

Interleaved: você consegue definir até 8 colunas neste estilo. É indicado para quando você tem várias colunas com a mesma importância/frequência de uso. O custo de manutenção deste estilo é um pouco maior do que o compound, mas você acaba tendo ganhos maiores quanto maior for sua tabela.

 

  • Captura de Tela 2018-04-24 às 18.07.28

    Compressão dos dados

    Por ser um banco colunar, a compressão de dados pode ser muito melhor do que um banco relacional. Isso porque existem tipos específicos de compressão para cada tipo de dado.

    Fazendo a compressão dos mesmos você tem ganhos de espaço, de memória e de I/O. Ano passado a AWS lançou o tipo zstd de compressão, que deu um salto muito grande na liberação de espaço. 

    É bem importante olhar os tipos de cada coluna e quais tipos de compressão são indicados para ela. Caso você não tenha certeza de qual tipo de compressão usar, você pode criar a tabela sem nenhuma e após ela ter 1MM de registros, rodar o comando ANALYZE COMPRESSION, onde o próprio Redshift irá sugerir um tipo de compressão para cada coluna.

Entendendo bem quais serão suas chaves de ordenação, estilos e chaves de distribuição você já conseguirá um ganho muito alto no desempenho. Aliando isso à compressão correta dos dados, você não ganhará somente em desempenho, mas também reduzirá em muito o I/O.

Melhores práticas

Conforme os dados são inseridos nas tabelas, ela acaba perdendo a ordenação e distribuição, suas estatísticas vão ficando defasadas e a performance acaba caindo. 

Para controlar isso é sempre importante ter rotinas de VACUUM agendadas nessas tabelas, elas garantirão que os dados sejam rearranjados e distribuídos/ordenados de maneira correta. 

É muito importante também rodar rotinas de ANALYZE, elas garantem que as estatísticas da tabela sempre permaneçam atualizadas. Assim, é possível sempre ter um ótimo plano de execução da query.

Captura de Tela 2018-04-24 às 18.10.12.png

Captura de Tela 2018-04-24 às 18.11.24Evite colunas grandes: O indicado é sempre mantê-las com o menor tamanho possível, isso porque colunas grandes são sinônimos de desperdício de memória, já que a alocação do buffer é baseada no tamanho dela. 

Além disso, desta maneira você acaba armazenando menos registros na memória, podendo recorrer ao disco, o que acaba se tornando um gargalo.

Workload management (WLM)

outro

 

 

É onde você controla as filas de execução, definindo shares do hardware para cada uma delas, bem como o tempo de execução. 

Você pode definir até 8 filas de execução. Só tenha cuidado porque a porcentagem de hardware que você define para cada uma é dedicada, ou seja, imagine que você definiu 4 filas, cada uma com 25%. Se apenas uma fila estiver com queries em execução, ela só  poderá/conseguirá usar os 25% dela, mesmo que 75% esteja “disponível”. 

Uma recomendação é definir 4 filas com 20% cada para query e outras duas filas com 10% cada para processos de ETL.

Uso de temp tables

Captura de Tela 2018-04-24 às 18.14.12

O recurso de criação de tabelas temporárias é algo amplamente usado e de fato muito bom! Só que deve-se tomar um cuidado ao criá-las. 

Quando ela é criada como “CREATE TEMP TABLE … AS SELECT …” o Redshift utiliza por default o estilo Even de distribuição, ou seja, se você utilizar uma coluna para filtro, todos os slices serão lidos. 

Além disso, ele cria a tabela sem nenhuma compressão. Por isso, é recomendado criar primeiro a estrutura da tabela temporária “CREATE TEMP TABLE table-name (field1 datatype encode, ….) DISTKEY(field) SORTKEY(field)”, desta maneira você consegue não somente definir as chaves e estilo de distribuição, como também as chaves de ordenação. Por default o Redshift aplica o encoding zstd, mas você também consegue definir.

Conclusão

Tentei colocar aqui tudo o que vimos e percebemos que é essencial para conseguir, não só fazer um tuning em seu Redshift, mas também mantê-lo com esta performance constante.

Aliando as boas práticas, o tuning e o conhecimento da sua base, sem dúvida é possível ter ganhos significativos de performance.

Espero que essa troca de aprendizado ajude quem estiver passando por situações similares às quais passamos aqui.

Fontes:

Guilherme Brunhole

Guilherme Brunhole

Guilherme Brunhole trabalha com dados há mais de 4 anos e hoje é o responsável por essa área no Rapiddo Vision, um marketplace da Movile. Além disso é um dos fundadores da UAUBox, um clube de assinaturas de produtos de beleza que utiliza data science para encontrar os produtos ideais para cada perfil.

Deixe um comentário

Categorias

Posts relacionados

Siga-nos

Baixe nosso e-book!

%d blogueiros gostam disto: