Armazenamento de métricas: como mudamos de Graphite+Whisper para Graphite+ClickHouse

Olá a todos! No dele último artigo Escrevi sobre como organizar um sistema de monitoramento modular para arquitetura de microsserviços. Nada fica parado, nosso projeto está em constante crescimento e o número de métricas armazenadas também. Como organizamos a transição de Graphite+Whisper para Graphite+ClickHouse sob condições de alta carga, leia sobre as expectativas e os resultados da migração sob o corte.

Armazenamento de métricas: como mudamos de Graphite+Whisper para Graphite+ClickHouse

Antes de contar como organizamos a transição do armazenamento de métricas em Graphite+Whisper para Graphite+ClickHouse, gostaria de dar informações sobre os motivos para tomar tal decisão e sobre as desvantagens do Whisper com as quais convivemos por muito tempo.

Problemas de grafite + sussurro

1. Alta carga no subsistema de disco

No momento da transição, aproximadamente 1.5 milhão de métricas chegavam até nós por minuto. Com esse fluxo, a utilização do disco nos servidores era de aproximadamente 30%. Em geral, isso era bastante aceitável - tudo funcionava de forma estável, era escrito rapidamente, lido rapidamente... Até que uma das equipes de desenvolvimento lançou um novo recurso e começou a nos enviar 10 milhões de métricas por minuto. Foi quando o subsistema de disco ficou mais rígido e vimos 100% de utilização. O problema foi rapidamente resolvido, mas permaneceu um resíduo.

2. Falta de replicação e consistência

Muito provavelmente, como todos que usam/usaram Graphite+Whisper, despejamos o mesmo fluxo de métricas em vários servidores Graphite de uma só vez para criar tolerância a falhas. E não houve problemas especiais com isso - até o momento em que um dos servidores travou por algum motivo. Às vezes, conseguimos recuperar um servidor caído com rapidez suficiente, e o carbon-c-relay conseguiu carregar métricas de seu cache nele, mas às vezes não. E então houve uma lacuna nas métricas, que preenchemos com rsync. O procedimento foi bastante longo. A única graça salvadora foi que isso acontecia muito raramente. Também pegamos periodicamente um conjunto aleatório de métricas e as comparamos com outras do mesmo tipo em nós vizinhos do cluster. Em cerca de 5% dos casos vários valores eram diferentes, o que não nos deixou muito satisfeitos.

3. Grande pegada

Como escrevemos em Graphite não apenas infraestrutura, mas também métricas de negócios (e agora também métricas do Kubernetes), muitas vezes nos deparamos com uma situação em que a métrica contém apenas alguns valores e o arquivo .wsp é criado levando em consideração toda a retenção período e ocupa uma quantidade de espaço pré-alocada, que para nós era de aproximadamente 2 MB. O problema é ainda agravado pelo fato de que muitos arquivos semelhantes aparecem ao longo do tempo e, ao criar relatórios sobre eles, a leitura de pontos vazios consome muito tempo e recursos.

Gostaria de observar imediatamente que os problemas descritos acima podem ser resolvidos por meio de vários métodos e com diversos graus de eficácia, mas quanto mais dados você começa a receber, mais eles pioram.

Tendo todos os itens acima (tendo em conta o anterior artigos), bem como um aumento constante no número de métricas recebidas, o desejo de transferir todas as métricas para um intervalo de armazenamento de 30 segundos. (até 10 segundos se necessário), decidimos experimentar Graphite+ClickHouse como uma alternativa promissora ao Whisper.

Grafite+ClickHouse. Expectativas

Tendo visitado vários encontros da galera do Yandex, tendo lido alguns artigos sobre Habré, tendo examinado a documentação e encontrado componentes sensatos para vincular o ClickHouse ao Graphite, decidimos agir!

Gostaria de receber o seguinte:

  • reduzir a utilização do subsistema de disco de 30% para 5%;
  • reduzir a quantidade de espaço ocupado de 1 TB para 100 GB;
  • ser capaz de receber 100 milhões de métricas por minuto no servidor;
  • replicação de dados e tolerância a falhas prontas para uso;
  • não fique parado neste projeto por um ano e faça a transição dentro de um prazo razoável;
  • mudar sem tempo de inatividade.

Bastante ambicioso, certo?

Grafite+ClickHouse. Componentes

Para receber dados via protocolo Graphite e posteriormente gravá-los no ClickHouse, selecionei carbono-clickhouse (golang).

A última versão do ClickHouse, versão estável 1.1.54253, foi escolhida como banco de dados para armazenamento de séries temporais. Houve problemas ao trabalhar com ele: uma montanha de erros caiu nos logs e não estava totalmente claro o que fazer com eles. Em discussão com Roman Lomonosov (autor de carbon-clickhouse, graphite-clickhouse e muitos, muitos mais) o mais antigo foi escolhido versão 1.1.54236. Os erros desapareceram - tudo começou a funcionar com força.

Selecionado para ler dados do ClickHouse grafite-сlickhouse (golang). Como uma API para Graphite - carbonapi (golang). ClickHouse foi usado para organizar a replicação entre tabelas funcionário do zoológico. Para métricas de roteamento, deixamos nosso querido relé carbono-c (C) (ver artigo anterior).

Grafite+ClickHouse. Estrutura da tabela

“grafite” é um banco de dados que criamos para monitorar tabelas.

“graphite.metrics” - tabela com mecanismo ReplicatedReplacingMergeTree (replicado Substituindo MergeTree). Esta tabela armazena os nomes das métricas e os caminhos para elas.

CREATE TABLE graphite.metrics ( Date Date, Level UInt32, Path String, Deleted UInt8, Version UInt32 ) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.metrics', ‘r1’, Date, (Level, Path), 8192, Version);

“graphite.data” - tabela com mecanismo ReplicatedGraphiteMergeTree (replicado GrafiteMergeTree). Esta tabela armazena valores de métricas.

CREATE TABLE graphite.data ( Path String, Value Float64, Time UInt32, Date Date, Timestamp UInt32 ) ENGINE = ReplicatedGraphiteMergeTree('/clickhouse/tables/replicator/graphite.data', 'r1', Date, (Path, Time), 8192, 'graphite_rollup')

“graphite.date_metrics” é uma tabela preenchida condicionalmente com o mecanismo ReplicatedReplacingMergeTree. Esta tabela registra os nomes de todas as métricas encontradas durante o dia. Os motivos de sua criação estão descritos na seção "Problemas" no final deste artigo.

CREATE MATERIALIZED VIEW graphite.date_metrics ( Path String,  Level UInt32,  Date Date) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.date_metrics', 'r1', Date, (Level, Path, Date), 8192) AS SELECT toUInt32(length(splitByChar('.', Path))) AS Level, Date, Path FROM graphite.data

“graphite.data_stat” - uma tabela preenchida de acordo com a condição, com o mecanismo ReplicatedAggregatingMergeTree (replicado AgregandoMergeTree). Esta tabela registra o número de métricas recebidas, divididas em 4 níveis de aninhamento.

CREATE MATERIALIZED VIEW graphite.data_stat ( Date Date,  Prefix String,  Timestamp UInt32,  Count AggregateFunction(count)) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/replicator/graphite.data_stat', 'r1', Date, (Timestamp, Prefix), 8192) AS SELECT toStartOfMonth(now()) AS Date, replaceRegexpOne(Path, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Prefix, toUInt32(toStartOfMinute(toDateTime(Timestamp))) AS Timestamp, countState() AS Count FROM graphite.data  GROUP BY Timestamp, Prefix

Grafite+ClickHouse. Diagrama de interação de componentes

Armazenamento de métricas: como mudamos de Graphite+Whisper para Graphite+ClickHouse

Grafite+ClickHouse. Migração de dados

Como lembramos das expectativas deste projeto, a transição para ClickHouse deveria ocorrer sem interrupções; portanto, tivemos que de alguma forma mudar todo o nosso sistema de monitoramento para o novo armazenamento da forma mais transparente possível para nossos usuários.
Foi assim que fizemos.

  • Uma regra foi adicionada ao carbon-c-relay para enviar um fluxo adicional de métricas para o carbon-clickhouse de um dos servidores participantes da replicação das tabelas ClickHouse.

  • Escrevemos um pequeno script em python que, usando a biblioteca Whisper-dump, lê todos os arquivos .wsp de nosso armazenamento e envia esses dados para o carbon-clickhouse descrito acima em 24 threads. O número de valores métricos aceitos no carbono-clickhouse atingiu 125 milhões/min, e o ClickHouse nem suava a camisa.

  • Criamos um DataSource separado no Grafana para depurar funções usadas em painéis existentes. Identificamos uma lista de funções que utilizamos, mas elas não foram implementadas no carbonapi. Adicionamos essas funções e enviamos PRs aos autores do carbonapi (agradecimentos especiais a eles).

  • Para mudar a carga de leitura nas configurações do balanceador, alteramos os endpoints de graphite-api (interface API para Graphite+Whisper) para carbonapi.

Grafite+ClickHouse. resultados

  • redução da utilização do subsistema de disco de 30% para 1%;

    Armazenamento de métricas: como mudamos de Graphite+Whisper para Graphite+ClickHouse

  • reduziu a quantidade de espaço ocupado de 1 TB para 300 GB;
  • temos capacidade de receber 125 milhões de métricas por minuto no servidor (picos no momento da migração);
  • transferiu todas as métricas para um intervalo de armazenamento de trinta segundos;
  • replicação de dados recebidos e tolerância a falhas;
  • comutado sem tempo de inatividade;
  • Demorou cerca de 7 semanas para concluir tudo.

Grafite+ClickHouse. Problemas

No nosso caso, houve algumas armadilhas. Isto é o que encontramos após a transição.

  1. ClickHouse nem sempre relê as configurações rapidamente; às vezes ele precisa ser reinicializado. Por exemplo, no caso da descrição do cluster zookeeper na configuração do ClickHouse, ele não foi usado até que o servidor clickhouse fosse reinicializado.
  2. Grandes solicitações do ClickHouse não foram processadas, portanto, no graphite-clickhouse, nossa string de conexão do ClickHouse se parece com esta:
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. ClickHouse frequentemente lança novas versões de versões estáveis; elas podem conter surpresas: tenha cuidado.
  4. Contêineres criados dinamicamente em kubernetes enviam um grande número de métricas com um tempo de vida curto e aleatório. Não há muitos pontos para essas métricas e não há problemas de espaço. Mas ao criar consultas, ClickHouse coleta um grande número dessas mesmas métricas da tabela de 'métricas'. Em 90% dos casos, não há dados sobre eles além da janela (24 horas). Mas é gasto tempo procurando esses dados na tabela de 'dados' e, em última análise, atinge o tempo limite. Para solucionar esse problema, passamos a manter uma visão separada com informações das métricas encontradas durante o dia. Assim, ao construir relatórios (gráficos) para containers criados dinamicamente, consultamos apenas as métricas que foram encontradas dentro de uma determinada janela, e não para todo o tempo, o que agilizou significativamente a construção de relatórios sobre eles. Para a solução descrita acima, coletei grafite-clickhouse (garfo), que inclui a implementação do trabalho com a tabela date_metrics.

Grafite+ClickHouse. Tag

Com a versão 1.1.0 o Graphite tornou-se oficial tags de suporte. E estamos pensando ativamente sobre o que e como fazer para apoiar esta iniciativa na pilha grafite+clickhouse.

Grafite+ClickHouse. Detector de anomalia

Com base na infraestrutura descrita acima, implementamos um protótipo de detector de anomalias e funciona! Mas mais sobre ele no próximo artigo.

Inscreva-se, aperte a seta para cima e seja feliz!

Fonte: habr.com

Adicionar um comentário