Em pouco tempo, o Prometheus se tornou uma das ferramentas de monitoramento mais populares. Obrigado, em particular, e a alta velocidade de seu trabalho. Seu armazenamento local é ótimo para armazenamento de métricas de curto prazo e trabalho com elas. Às vezes, você deseja manter as métricas distribuídas por meses e anos, cortando automaticamente os dados antigos, mas sem alterar a interface para trabalhar com eles.
Sobre isso, a decodificação do relatório de Alexey Palazhchenko no RootConf 2018. No relatório: Prometheus, TSDB de armazenamento local, Prometheus de armazenamento remoto, PromQL, TSDB, Clickhouse, PromHouse, um pouco de InfluxDB.
Quem se importa, por favor, debaixo do gato.
Amigos! Olá pessoal! Meu nome é Alexey Palazhchenko. Eu trabalho na Percona. Gostaria de falar sobre o armazenamento a longo prazo de métricas no Prometheus.

Trabalho na Percona e faço um produto chamado monitoramento e gerenciamento percona. Esta é a solução em caixa que nossos clientes definem para si mesmos. O PMM é totalmente de código aberto. Ele consiste em Prometheus, Grafana para gráficos, software de análise de consultas personalizadas e nosso próprio invólucro que permite que você faça algum gerenciamento. Por exemplo, você pode adicionar um destino de raspar ao Prometheus. Essas são novas fontes de onde ele coletará métricas sem precisar inserir manualmente um contêiner ou máquina virtual e editar o arquivo de configuração.
É importante entender que esses não são SaaS. Nós não temos produção. Nossa produção está localizada com nossos clientes. Experimentar isso não é muito bom. Temos a coisa mais próxima que poderia ser chamada de produção - é https://pmmdemo.percona.com/ . No momento do relatório, o pmmdemo.percona.com precisava ser desligado devido ao RGPD.
Entregamos PMM aos clientes - uma solução in a box: um contêiner de encaixe ou uma máquina virtual. Todos eles gostam de Prometeu. Algumas pessoas que estão olhando para Prometheus pela primeira vez se deparam com um modelo pull. Para iniciantes, isso é inconveniente. Geralmente uma grande conversa separada. Você pode discutir sobre métodos de puxar ou empurrar. Em média, isso é a mesma coisa.
Algumas coisas em Prometeu são muito legais.
A linguagem de consulta do Prometheus é realmente uma coisa interessante que não tem analógico em lugar algum.
A segunda coisa que você gosta é de descoberta de serviço. Se você tiver algum tipo de infraestrutura dinâmica, kubernetes, automaticamente não precisará adicionar todos os destinos para monitoramento com as mãos. Se estático - isso também pode ser feito de maneira simples. Você precisa usar o arquivo de configuração.
Os clientes do Prometheus gostam. Eles querem manter as métricas cada vez mais longas. Alguém usa o Prometheus apenas para monitoramento operacional. Mas alguém quer manter as métricas por mais tempo, observar a dinâmica, comparar com os gráficos de um ano atrás. Ao mesmo tempo, o objetivo do armazenamento de métricas a longo prazo não é o objetivo do projeto Prometheus. Inicialmente, ele foi criado para armazenar métricas por um curto período de tempo. O SoundCloud armazena métricas em apenas alguns dias. Existem mecanismos no Prometheus que permitem fazer isso por mais tempo, mas eles estão dispostos um pouco ao lado. Portanto, podemos tomar uma decisão para o ecossistema do Prometheus sem alterar o núcleo do próprio sistema. Com base neles, podemos tomar nossa própria decisão dentro do mesmo ecossistema.

Este não é um relatório sobre soluções prontas. Este é um relatório sobre nossa experiência, nossa dor, nossas tentativas. Se você esperava que, após este relatório, baixasse o contêiner do repositório ou docker, execute-o e ele funcionará, então não é assim. Mas, ao mesmo tempo, está perto o suficiente para ser assim. Temos algumas bases. Eles são todos de código aberto. Você pode tentar. Eles ainda não estão prontos para produção. Mas com as informações contidas neste relatório, você pode entender o porquê e o que pode ser feito melhor. Você pode tomar sua própria decisão que melhor lhe convier.

Como as métricas são armazenadas no Prometheus? Há armazenamento local. Há armazenamento remoto. Estes são realmente dois mundos diferentes. Eles se cruzam fracamente. Portanto, o relatório também é dividido em 2 partes.

Se você estava em um relatório anterior no salão principal, onde houve uma boa introdução no Prometheus, você sabe que o armazenamento local é uma biblioteca separada chamada TSDB. O TSDB não tem nada a ver com o OpenTSDB. O TSDB é um pacote Go separado que você pode usar no seu programa Go. No nível da biblioteca TSDB, não há cliente ou servidor.
Essa biblioteca é otimizada para trabalhar com dados de séries temporais. Por exemplo, o TSDB possui codificação delta, que permite armazenar não os números em si, mas as alterações entre esses números. Isso permite que você armazene 1 byte em vez de 16 bytes. 1 byte por hora e 1 byte por valor. Ou seja, você armazena em média 1 ou 2 bytes precisamente devido a essa boa compactação.
O TSDB é otimizado para modelos pull. Os dados são adicionados apenas lá. Prometheus não pode gravar dados históricos. Não há API para isso. O delta máximo é de aproximadamente 5 minutos. Se os dados forem mais antigos, eles não serão aceitos.
Não há downsampling embutido tsdb # 313 no TSDB. Existe uma questão em aberto na qual houve uma discussão sobre o fato de que, em geral, existem projetos que prometem algo e que há uma redução de amostragem lá. Até agora, a solução é que o TSDB não adicionará downsampling.

Como obteríamos dados do TSDB? TSDB é um banco de dados em disco. Você pode trabalhar com ele se estiver escrevendo um programa Go. Mas se você não escrever um programa no Go, haverá uma API JSON que permite fazer consultas. Se você já usou o Prometheus e pelo menos uma vez criou um gráfico, conhece a API de consulta padrão, na qual existe um parâmetro de consulta no qual é possível executar qualquer consulta do PromQL e, opcionalmente, o tempo. Se não houver tempo, a hora atual é tomada.
Uma consulta específica é destacada no slide, que você raramente vê na vida real. Isso é um truque. Isso nos permite extrair todas as métricas que o Prometheus possui. Como isso funciona? No nível do PromQL, diz-se que é impossível escrever uma expressão que capte seriados o tempo todo. Isso está escrito diretamente nas regras. Outra regra diz que você não pode fazer um comparador em que todos os valores estejam vazios. Se você simplesmente escrever chaves, isso não funcionará. Se você escrever o nome não for igual a nada (não um valor vazio), ele não funcionará. Mas este é um truque real que permite que você faça isso. No entanto, isso nem é particularmente documentado. Existem comentários no próprio código de que isso funciona.
A segunda consulta é query_range, que faz a mesma coisa, mas retorna os dados em um intervalo e com alguma etapa. Essencialmente, ele faz uma consulta várias vezes para cada etapa, do começo ao fim. Esta é a API usada para desenhar gráficos. A primeira API usa para obter valores instantâneos.

Temos uma API para recuperar metadados. Se queremos obter todos os nomes das métricas, fazemos uma consulta como esta, em que match é uma matriz de métricas. Pode haver vários argumentos, mas, neste caso, passamos a mesma correspondência, que tudo retorna para nós.
A segunda meta API, que retorna o valor de todos os rótulos. Se queremos ver uma lista de todos os trabalhos, em vez de label_name, escrevemos job e obtemos essa lista. Essas APIs retornam JSON para nós.

Há outra API que retorna todas as métricas do próprio Prometheus em um formato nativo dos exportadores. O formato é chamado expfmt. No próprio Prometheus, há uma API de federação que permite fazer essa solicitação. Para que é isso? A opção mais fácil, se você tiver algum código que já funcione com expfmt, não será necessário treiná-lo novamente para trabalhar com alguma API JSON customizada. Esse formato é muito mais fácil de transmitir, porque se você tiver o JSON em algum lugar no nível superior do objeto, geralmente precisará analisar esse objeto como um todo. Aqui pode ser feito linha por linha.
O mais importante é que é uma API separada. Funciona como uma exportação real. Você pode pegar o outro Prometeu para raspar. Este é um trabalho regular com os parâmetros usuais. Você precisa passar o parâmetro - URL da consulta. Se você fizer uma solicitação de ondulação, obterá o mesmo aqui. Obtemos todas as métricas para o valor de tempo atual. A única ressalva: você deve definir honor_labels para que o Prometheus, que eliminará outro Prometheus por meio dessa API, não atrapalhe o valor do trabalho e do rótulo da instância. Usando esta API de federação, você pode carregar todos os dados de um Prometheus para outro.

Como isso pode ser usado?
Primeiro, a coisa mais importante a dizer é que você não precisa fazer isso. O TSDB é otimizado para diferentes modos de operação. Se você tem um Prometheus que coleta muitos dados, ele realiza muitas E / S. Se você usar a API de federação, a quantidade de saída de entrada aumentará cerca de 2 vezes. Existem nuances. Dependendo da frequência com que você raspa no federado e da frequência com que raspa os destinos. Se o tempo não foi alterado, isso realmente dobra a carga. Portanto, se você quiser escalar seu Prometheus e ativar a federação, você o matará. A carga dobrará.
Segundo momento. Você estará pulando dados. Você terá um conflito de dados. Porque Essa API, como quase qualquer API do Prometheus, não é atômica. Se novos dados chegarem, uma nova raspagem será finalizada no momento em que sua solicitação de federação ainda estiver em andamento, você poderá obter um dado para uma série temporal e novos para outro. Se é uma série temporal não relacionada, geralmente não é assustador. Mas se você tiver um resumo ou um histograma, que no nível expfmt é representado por várias métricas básicas, haverá inconsistência entre elas.

Como podemos resolver esse problema atômico? O Prometheus possui regras de gravação que permitem criar uma nova série temporal a partir de uma série temporal existente. Isso pode ser feito com menos frequência. Essa é uma maneira de reduzir a amostragem. Por exemplo, descarte o destino a cada segundo, mas queremos fazer a agregação node_cpu em um minuto. O agrupamento no Prometheus 2.0 permite que você faça essas agregações sequencialmente. As regras que estão no mesmo grupo são executadas estritamente em sequência. Neste ponto, não há problema de atomicidade, não há problema de que os dados serão alterados no processo. Mas isso não resolve o problema do fato de que são admissíveis alguns outros dados que estão logicamente conectados com isso, mas não estão conectados do ponto de vista do modelo de dados. Ainda não existe atomicidade pura. Há uma questão em aberto sobre esse tópico. Você pode fazer instantâneos. Você pode fazer uma consulta PromQL ao banco de dados TSDB e eliminar todas as amostras com menos de algum valor do tempo iniciado na avaliação a partir dos valores obtidos. Essa seria a maneira mais fácil, mas até agora não foi feita.
É importante entender que as regras de gravação precisam ser feitas no Prometheus inferior, e não no que a federação faz. Caso contrário, você pulará picos, seu monitoramento não funcionará corretamente.

Como podemos usar essa combinação dessas coisas para reduzir a amostragem e o armazenamento a longo prazo.
O primeiro. Acabamos de configurar a federação e baixar todos os dados desse Prometheus. Essa estranha expressão regular é como um zoidberg - na verdade, é apenas dois pontos. Um asterisco à esquerda e à direita do cólon. Usamos o nome padrão para regras de gravação, o que adiciona dois pontos ao meio. Ao dividir o nome original, haverá um nível de agregação à esquerda e uma função à direita. Uma métrica normal de dois pontos não. Se houver dois pontos, isso é um sinal de que é agregação. Depois disso, usamos esse nome de métrica em nosso gráfico. Se quisermos que nossa programação, nosso painel em grafana funcione com o Prometheus principal e com os mais altos, podemos usar a expressão ou . Adotamos uma métrica ou outra, dependendo de qual seja. Podemos trapacear e usar a remarcação para renomear a nova métrica para o nome antigo. Esta é uma abordagem bastante perigosa. Você pode soletrar anexos regulares incorretamente e terá um conflito de séries temporais. Prometeu gravará muitos avisos no log. Você verá isso, mas encontrar o motivo pode ser bastante difícil. Mas, se feito com cuidado, por exemplo, gerando essas expressões regulares programaticamente, isso funcionará. Em seguida, você terá um painel regular em que apenas o node_cpu é usado. Dependendo de qual Prometheus é usado, você receberá dados brutos ou dados agregados.

Como eu disse, as regras de gravação podem ser geradas de maneira bastante simples. Acabamos de receber todas as séries temporais através da API que eu já mostrei. Criamos regras e essas regras devem usar as funções e operadores corretos. Não há necessidade de usar a taxa com medidor lá. Isso não funcionará corretamente. Deve ser usado apenas com contagem. No nível em que você trabalha, você pode não ter informações sobre tipos de dados. Por exemplo, se você usar expfmt. Há informações sobre os tipos. Se a API JSON não estiver lá. Como resultado, a expressão que você gera automaticamente pode não ter nenhum significado físico. Portanto, você pode usar uma lista branca ou uma lista negra lá. Dependendo disso, gere a regra que você precisa ou jogue fora as regras que não fazem sentido. Existe uma ferramenta promtool que permite verificar se as regras que você gerou, a configuração que você gerou, faz sentido. Tem a sintaxe correta.

Se temos Grafana e existem vários Prometheus, precisamos saber para qual Prometheus enviar a solicitação. Como faríamos isso?
Uma maneira é colocar um proxy especial que analise o horário da solicitação e, dependendo disso, selecione Prometheus. As consultas têm um horário de início e um horário de término. Dependendo disso, você pode fazer o roteamento com as mãos. Alguém poderia escrever algum tipo de programa que faça isso. Na prática, isso é feito pelo nginx com o módulo lua ou um pequeno programa.

Nós realmente precisamos de uma API? Podemos trabalhar diretamente com o TSDB? Há uma nuance. Primeiro, se tentarmos usar o TSDB, que agora é usado pelo Prometheus, não conseguiremos fazer isso. Há um arquivo de bloqueio especial que impede isso. Se escrevermos um código que ignorará isso e tentarmos ler ou gravar dados, estamos garantidos para danificá-los. Além disso, mesmo lendo. O que pode ser feito? Podemos ler dados através da API e criar TSDB lado a lado. Em seguida, pare o Prometheus e substitua-o pelo TSDB. Mas, ao mesmo tempo, podemos prejudicar o desempenho se lermos todos os dados por meio da API. Eu vou falar sobre isso um pouco mais tarde.
A segunda opção Você pode copiar (fazer backup a quente) desses arquivos, ou seja, copiar como está. Sim, eles serão danificados. Ao abrir, você receberá um aviso de que os dados estão corrompidos. Eles precisam ser consertados. Você pode perder novos dados. Mas isso não importa para nós. Queremos reduzir a amostragem de dados antigos. A redução da amostragem pode ser feita usando o PromQL. Mas há uma nuance. É muito mais difícil retirá-lo do Prometheus do que o TSDB. Se você está um pouco familiarizado com o Go e o gerenciamento de dependências, o fornecedor PromQL é uma grande dor. Eu não aconselharia você. Evite isso, se possível.

Passamos para o armazenamento remoto. Alguém já trabalhou com armazenamento remoto no Prometheus? Algumas mãos. O armazenamento remoto é uma API que existe há muito tempo. Agora na versão 2.2 Armazenamento Remoto - marcado como experimental. Além disso, sabe-se que a API de armazenamento remoto mudará definitivamente.
O armazenamento remoto permite que você trabalhe apenas com dados brutos. Não há PromQL na entrada ou na saída. Quando você lê, não pode usar todo o poder do PromQL. Essencialmente, ele bombeia todos os dados do armazenamento remoto que correspondem à condição. Além disso, o PromQL já trabalha com eles. Isso tem uma sobrecarga bastante grande. Você precisa bombear muitos dados pela rede. Portanto, no Prometheus 2.3, que ainda não foi lançado, mas já foi adiado, haverá uma dica de leitura. Falaremos sobre isso um pouco mais tarde.
Ainda não há API para metadados. Você não pode criar uma API que retorne todas as séries temporais do Armazenamento Remoto. Se você fizer uma solicitação à API do Prometheus, ela não será direcionada ao armazenamento remoto. Ele retornará a série temporal, que está em seu banco de dados local. Se seu banco de dados local estiver desativado, ele retornará 0. O que pode ser um pouco inesperado. Agora, essa API usa o ProtoBuf e, definitivamente, será alterada para gRPC no futuro. Eles ainda não o fizeram, porque o gRPC requer HTTP2. E na prática eles tiveram problemas com ele.

A API de gravação se parece com isso. A solicitação possui um conjunto de rótulos. O conjunto de rótulos identifica exclusivamente as séries temporais. __name__
é realmente apenas um rótulo com um nome especial. E as amostras são um conjunto de tempo e valores - int64 e float64. Ao gravar, o pedido não é importante. Supõe-se que o banco de dados que escreve isso sozinho fará tudo certo. Prometeu pode fazer alguma otimização e não classificá-la novamente. Assim, uma solicitação de gravação é apenas algumas séries temporais.

A configuração de gravação possui uma configuração bastante flexível. Existem muitas opções para configurar a simultaneidade de gravação. O que Prometheus chama de shards são essencialmente solicitações competitivas. Você pode limitar o número máximo de amostras em uma solicitação, o máximo de solicitações paralelas, tempo limite, como repetir, qual retorno. Para muitos bancos de dados, 100 amostras de cada vez - isso pode ser muito pequeno. Se você usa o ClickHouse, como nós, é claro que o valor precisa ser bastante aumentado. Caso contrário, será muito ineficiente.

A API de leitura remota se parece com isso. É apenas um intervalo de tempo do início ao fim e um conjunto de partidas.

A correspondência é essencialmente uma coleção de pares de nome e valor - um tipo regular de rótulo e condição. Em comparação, existem igualdades, desigualdades ou expressões regulares. Este é o seletor de séries temporais usual que você vê no PromQL. Não há recursos aqui.

A resposta é algumas séries temporais que correspondem a essa consulta. Aqui as amostras devem ser classificadas por tempo. mais uma vez, isso ajuda Prometheus a economizar um pouco de CPU - não é necessário classificar. Mas supõe-se que seu banco de dados faça isso. Na maioria dos casos, será assim, porque, muito provavelmente, haverá um índice no prazo.

Prometheus 2.3 introduziu dica de leitura. O que é isso Esta é uma oportunidade de informar ao Prometheus qual função interna que trabalha com a série temporal que está sendo solicitada será aplicada. Isso pode ser uma função ou um operador de agregação. Pode ser taxa. Ou seja, é chamado de func, mas na verdade pode ser uma soma, que, do ponto de vista do PromQL, na verdade não é uma função. Este é o operador. E um passo. No exemplo anterior, houve uma taxa de 1 minuto. Aqui a taxa é uma função e um minuto em milissegundos como uma etapa. Essa dica pode ser ignorada pelo banco de dados remoto. Ao mesmo tempo, não há indicação na resposta se foi ou não ignorada.

Qual é a configuração de leitura?
Em primeiro lugar, existe essa configuração required_matchers. Isso permite que você envie uma solicitação de armazenamento remoto que corresponda à expressão. Para ler dados agregados do armazenamento remoto, você deve usar uma consulta que contenha dois pontos.
Existe uma opção que permite ler ou não dados recentes do armazenamento remoto, que está no TSDB. Geralmente, na configuração padrão, há um pequeno TSDB local que é gravado no disco local. Ela armazena lá por várias horas ou vários dias. Os dados que você usa agora, que são usados para alertas, que são usados para criar o painel, são somente leitura do TSDB local. É rápido, mas não nos permite armazenar muitos dados.
Dados históricos antigos serão lidos no Armazenamento Remoto. Isso deixa claro como o armazenamento local e o armazenamento remoto se comunicam. Não há desduplicação.
Essencialmente o que está acontecendo. Os dados são obtidos do armazenamento local, dados são obtidos do armazenamento remoto se o read_recent estiver ativado. Eles simplesmente se fundem. Parece que isso não é um problema. Se for assumido que não reduzimos a amostra dos dados recentes, esses são exatamente os mesmos dados, eles coincidem completamente com os dados locais, teremos o dobro de amostras, não devemos afetar nenhuma função. Na verdade não. Há uma função irate () e um par para ela para medidor, que nos retorna a diferença entre os dois últimos valores. Ela olha para o intervalo de tempo indicado, mas usa apenas os dois últimos valores. Se os dois últimos valores tiverem o mesmo tempo, a diferença será zero. Isso é um bug e é quase impossível encontrá-lo. Foi reparado há apenas quatro dias. Este é um ingresso para qualquer pessoa interessada.

Curiosamente, a leitura remota foi implementada pelo Prometheus desde a versão 1.8. É dessa maneira que você pode ler os dados do Prometheus antigo ao migrar para a versão 2.x. A maneira oficial aconselha conectá-lo como leitura remota. Os dados serão subtraídos conforme necessário.
A leitura remota pode ser usada para fazer o roteamento de consultas sem um proxy. Em um dos slides anteriores, mostrei que, dependendo do tempo, podemos fazer o roteamento em um Prometheus ou outro. Da mesma maneira, podemos evitar isso. Basta conectar o Prometheus abaixo da leitura remota - e os dados serão lidos a partir daí. Mas há uma alteração no fato de que, é claro, muitos dados serão bombeados. Especialmente se você não estiver usando a dica de consulta.

Porquê clickhouse?
Para nossa solução de pesquisa, escolhemos o ClickHouse, porque já o analisamos há muito tempo. Temos pessoas que estão constantemente envolvidas no desempenho do banco de dados, verificando constantemente novos bancos de dados. Nossa empresa está envolvida em bancos de dados de código aberto.
Nós realmente gostamos do seu desempenho bruto. Seu poder em termos de CPU, tempo e assim por diante, é muito bom. A maioria desses sistemas fala sobre escalabilidade infinita, mas fala pouco sobre eficiência para um único servidor. Muitos de nossos clientes armazenam métricas em um par de servidores.
Replicação interna, sharding.
O GraphiteMergeTree é um mecanismo especial para armazenar dados de grafite. No começo, ele estava muito interessado em nós.

O mecanismo é destinado ao rollup (afinamento e agregação / média) dos dados de grafite.
O Graphite armazena os dados completos no ClickHouse, e pode recebê-los, e afirma ainda que, com o desbaste GraphiteMergeTree é usado, o MergeTree é usado sem desbaste. A sensação é de que os dados estão sempre cheios, eles não são substituídos, é apenas uma otimização da leitura. Mas no geral não é ruim. Quando fazemos a leitura, não coletamos os dados, eles são agregados automaticamente, obtemos poucos dados - isso é bom. A desvantagem para nós é que todos os dados são armazenados.
Eu estava me preparando no começo do mês para o relatório. Alguém entra em um bate-papo por telegrama e pergunta: "Dados menores do GraphiteMergeTree"? Eu já escrevo não. A documentação diz que não. Mas a outra pessoa no bate-papo responde "sim, você precisa ligar para otimizar". Corra, verifique - sim a verdade. A documentação é essencialmente um bug. Então eu li o código fonte, verificado, verifica-se lá é otimizar, otimizar final. O Optimize Optimize foi originalmente criado especificamente para o GraphiteMergeTree. Na verdade, ele reduz a amostragem. Mas deve ser chamado com as mãos.
GraphiteMergeTree tem um modelo de dados diferente. Ele não tem rótulos. Escrever tudo de forma eficaz em nome das métricas não funciona muito bem.
As métricas de nome são armazenadas em uma tabela. O nome das métricas tem um comprimento diferente. Isso leva ao fato de que, se fizermos uma pesquisa de índice pelo nome da métrica, porque o comprimento é diferente, esse índice não será tão eficaz como se esse índice tivesse um valor de comprimento fixo. Porque você precisa fazer uma pesquisa de arquivo. É impossível especificar exatamente onde pousar para fazer uma pesquisa binária.

Portanto, eles fizeram seu próprio esquema. O slide mostra como armazenamos séries temporais no banco de dados. A data que o ClickHouse precisa é de uma impressão digital. Se você consultou as fontes do Prometheus ou do TSDB, sabe que a impressão digital é essencialmente uma soma de verificação rápida e curta da série temporal do nome completo. Impressão digital é uma combinação de todas as etiquetas, chaves e valores. Um nome é um rótulo comum. Usamos o mesmo algoritmo para compatibilidade. Debitar algo pode ser conveniente. A impressão digital é a mesma e pode ser verificada no TSDB e em nosso armazenamento que são iguais. Os rótulos são armazenados em um JSON especial, que permite ao ClickHouse trabalhar com ele com suas funções padrão. Este é um JSON compacto, sem espaços, com nomes levemente simplificados. Esta tabela não é usada durante a operação. Ele é sempre armazenado na memória da nossa solução real, chamada PromHouse. É usado apenas quando iniciamos o servidor para descobrir quais são as séries temporais. Ela é subtraída. À medida que novas séries temporais chegam, as gravamos lá. Todas as várias instâncias do PromHouse podem ler a mesma tabela. ReplacingMergeTree nos diz que essas séries temporais - existem várias instâncias diferentes - escrevem as mesmas séries temporais. Eles vão lutar - e não haverá nenhum problema aqui.

Armazenamos amostras em uma tabela separada com muita eficiência. Com um valor de comprimento fixo, essa impressão digital é a mesma, tempo e valor. Temos 24 bytes por amostra. Tem um comprimento estritamente fixo. Cada coluna é armazenada separadamente. Uma pesquisa de impressões digitais é eficaz porque sabemos que o tamanho é fixo. Não existe um problema como o GraphitmergeTree quando é uma string. Usamos particionamento personalizado. Índice primário de impressões digitais e por tempo.
24 bytes é uma versão simplificada. De fato, comprime bem. De fato, usa menos espaço. Em nossos testes mais recentes, a taxa de compactação é de aproximadamente 1 a 42.

Como podemos reduzir a amostragem manual se tivermos o GraphiteMergeTree, mas não o mesmo que gostaríamos. De fato, podemos fazê-lo manualmente. Como fragmentação feita anteriormente, particionamento, quando não havia nada embutido. Fazemos uma nova mesa com as mãos. Quando uma amostra de tempo chega até nós, determinamos em qual tabela estamos escrevendo.
Selecionamos o horário da consulta na qual tabela ler. Se a leitura ocorrer na borda, lemos várias tabelas. Em seguida, mantemos esses dados. Pode-se usar o view para isso. Por exemplo, faça uma visualização de várias tabelas, o que permite que ela seja lida em uma única consulta. Mas há um erro no ClickHouse: o predicado da visualização não é substituído nas consultas. Portanto, se você fizer uma solicitação em exibição, ela será exibida em todas as tabelas. Vista que não podemos usar.
Como fazemos downsampling? Criamos uma tabela temporária. Copie a inserção nos dados selecionados usando as funções corretas.
Renomeamos o que é atômico sob o bloqueio global. Estamos renomeando a tabela existente para a antiga. Novo no existente. Largamos a mesa velha. Já temos dados de 148 dias para redução da amostra. Qual é o problema aqui? Inserir em parece bonito. De fato, precisamos aplicar as funções corretas, a agregação correta a ser executada. Na prática, isso não pode ser feito com uma grande solicitação. Mesmo alguns pedidos grandes não podem ser feitos. Isso tem que ser feito a partir do código. O código envia um grande número de solicitações pequenas. Tentamos o nosso melhor para fazer isso com grandes solicitações, mas isso não é muito eficaz. A redução da amostragem de dados de um dia até o momento leva menos de um dia. Dependendo da quantidade de dados, pode demorar muito tempo.

O ClickHouse terá atualização / exclusão. Excluir já recebeu a primeira versão. Se a atualização / exclusão funcionar, nosso esquema de dados de amostragem reduzida poderá ser simplificado.
Em segundo lugar, o ClickHouse tem a tarefa de fazer a compactação personalizada (delta, delta para delta). É isso que o TSDB faz. Isso é adequado para dados de séries temporais. Isso é especialmente útil se pudermos escolher o tipo de compactação, dependendo dos tipos de dados. Por exemplo, o contador, que está crescendo apenas - para isso, a compactação delta-delta é adequada. Um medidor que flutua em torno da magnitude, para que o delta funcione bem.

Existem outros armazenamentos que funcionam. Existe o InfluxDB que funciona imediatamente. É costume repreendê-lo por velocidade, mas o que funciona imediatamente e você não precisa fazer nada é bom.
Existem OpenTSDB e Graphite, que são somente gravação. O adaptador padrão do Prometheus realmente não funciona.
Existe um CrateDB. Existe um TimescaleDB que bifurca o PostgreSQL para bancos de dados de séries temporais. Dizem que funciona bem, mas nós mesmos ainda não tentamos.
Existe o Cortex, também conhecido como projeto Frankenstein. Isso o descreve muito bem. Este é o pessoal que está tentando tomar uma decisão com base na federação de Prometheus. Eles armazenam dados no S3.
Há Thanos.
- Ele tem uma arquitetura muito interessante. Há o Prometheus que usa o TSDB local. Um cluster é criado entre eles. Ao lado de cada Prometheus, há um carro lateral especial, que aceita solicitações via API de leitura e gravação remota. Ele redireciona esses pedidos para o Prometheus. O Prometheus pode usar suas APIs de leitura e gravação remotas. Todos os carros laterais são interconectados e, entre mestres de API personalizados via gRPC, a replicação está disponível, há re-shading.
- Arquitetura sofisticada.
- Está bem úmido. Alguns meses atrás, ele estava se desfazendo de meio chute quando começou.

O uso do modelo pull não grava muitos dados. Você precisa esperar um ano inteiro para preencher os dados anuais. Estamos tentando escrevê-los de alguma forma lá.
Não há gravação remota no Prometheus; portanto, a gravação de muitos dados no TSDB local não funcionará.
O segundo problema. Se gerarmos dados para testes de estresse, eles geralmente tremem bem. Por exemplo, se pegarmos os dados existentes e gerarmos 100 instâncias, e esses forem os mesmos, o coeficiente de compactação será tão bonito que, na realidade, eles não acontecem.

Escrevemos um exportador falso que se parece com um exportador regular que Prometheus pode manter:
- Quando a sucata chega, ele vai a algum exportador a montante. Obtém dados dele.
- Gera muitas instâncias. Digamos que 1 seja um scrapie e recebemos 100 na saída.
- Altera ligeiramente os dados: mais menos 10% para o contador e o medidor.
- Ele não altera os valores simples 0 ou 1. Porque, se houver uma métrica UP que responda, ela mostra se o serviço está em execução: sim - 1 ou não - 0. E não está muito claro o que 098 UP significa.
- Não mudamos números inteiros para reais e vice-versa.
- Apenas fornece dados no formato expfmt usual.

Uma ferramenta de promload que carrega dados. Lendo dados:
- Pode ler arquivos em seu próprio formato
- Talvez a partir da leitura remota
- Pode ler de algum exportador
Grava em diferentes formatos. Incluindo em / dev / null, se quisermos testar exatamente como a leitura funciona rapidamente.
Agora é uma ferramenta de teste de carga, não apenas para o PromHouse, mas também para qualquer solução que use leitura remota ou Prometheus.

Queremos adicionar o cache de leitura, porque em nossos testes o gargalo costumava ser o exportador falso, que gerava dados por um longo tempo. Nós poderíamos armazená-los em cache. Que eles sejam irrealisticamente bons. Mas não vamos desacelerar. Não tivemos que esperar dias pelo teste de estresse.
Algum tipo de filtragem em tempo real, algum tipo de modificação em tempo real.
Suporte nativo para TSDB. Para trabalhar com o banco de dados em disco, e não através da API.
Concentre-se na precisão da migração. Uma vez eu pmmdemo.percona.com colocar: conectado, recebeu todas as métricas. Se você fizer isso de uma maneira nativa, o Prometheus abrirá o TSDB, aumentará todas as séries temporais do disco, aumentará índices e depois rastreará para arquivos de partes, e perceberá que eles realmente existem. Neste ponto, tudo pode simplesmente se deitar.
A abordagem ingênua é levar toda a série temporal e ler os dados antigos para os novos. Nesse momento ele se deitará. Você precisa fazer o oposto. Primeiro, você precisa obter a lista de séries temporais com algumas consultas com expressões regulares. Por exemplo, uma série temporal que começa em A. Em seguida, me dê uma série temporal que começa em B. Em seguida, carregue-as exatamente por métricas, não por tempo. Isso é ilógico, mas é assim que funciona. Esta é uma nuance se você fizer algo assim. Se você perceber que o OOM Killer aconteceu lá, saberá que é por sua causa.

Os resultados do teste de carga, não haverá gráficos. O teste de carga leva muito tempo e, infelizmente, devido a um erro de configuração, tudo deu errado. Portanto, os resultados não deram certo.
Escreveremos no blog da Percona quando fizermos o teste de carregamento.
Eu posso dizer os resultados sem gráficos. A gravação foi linear. A leitura saltou e não foi muito rápida. Ler os dados atuais não é muito importante para nós. Eles podem ser acelerados através de dicas de leitura. Você pode ativar o read_recent para melhorar a leitura. E para dados antigos, isso funciona bem.

As pessoas querem armazenamento a longo prazo. Existe essa demanda. Conversamos sobre a PromHouse na PromCon. Lá estava um tópico muito quente. Thanos está se desenvolvendo ativamente.
Já é possível agora. Existe uma solução para isso. Existe uma API. Existem algumas integrações. Mas tudo isso precisa ser finalizado com um arquivo. Não há soluções prontas para produção.

Links para onde procurar. O primeiro link é o repositório PromHouse. O segundo link é para onde ele provavelmente se moverá. Agora em um repositório há várias coisas diferentes? não muito estreitamente relacionado. Portanto, você precisará transferi-los.
Nosso blog conterá informações sobre desempenho e algumas novidades.
Perguntas:
Pergunta: Você checou os rumores sobre o InfluxDB?
Resposta: Ele não era muito bom. Ele ficou muito melhor. Todas essas histórias sobre o fato de o InfluxDB ser lento e desmoronar - são sobre a versão antiga. A versão atual é estável. Eu não diria? que funciona rápido. Mas funciona de forma estável. Profissionais do InfluxDB na minha opinião:
- Primeiro, não há necessidade de fazer algo próximo, porque o InfluxDB funciona imediatamente.
- Em segundo lugar, no ClickHouse, como em outras soluções baseadas em banco de dados, mas não no TSDB, você pode usar uma linguagem de consulta mais familiar para você. A linguagem de consulta do InfluxDB é semelhante ao SQL. Você pode fazer análises, o que é difícil de fazer no PromQL. Se você usar o TimeScaleDB - há SQL real.
Pergunta: O mecanismo GraphiteMergeTree apenas para gravação funciona? Se quisermos mostrar gráficos, o Grafana precisa ser configurado no Graphite para mostrar armazenamento a longo prazo?
Resposta: Sim. A integração que está no próprio Prometheus funciona apenas para gravação. Ele escreve apenas dados. Então, da Grafana, você vai para a Grafite.
Pergunta: E ele perde rótulos quando escreve?
Resposta: Há uma configuração que diz o que fazer com eles, como inseri-los, onde inseri-los.
Informações da platéia: Avito disse que está escrevendo sua solução para gravações de Prometheus a Graphite.
Pergunta: houve uma conclusão de que, com a gravação, tudo está bem em um servidor de armazenamento de longo prazo.
(5- 15-). raid 6 sata ?
: PMM — . downsampling c 14 1 . , . . . .
: IOPS ?
: .
:
: . , . , , .
: InfluxDB, InfluxDB?
: read_recent. , remote storage. InfluxDB . . read_recent , .
: , Prometheus. InfluxDB. Grafana Prometheus. Prometheus PromQL , InfluxDB?
: .
: Prometheus InfluxDB Grafana?
: . Prometheus 2.2 , .
PS : valyala gecube
, .