{"id":80775,"date":"2020-05-08T13:42:47","date_gmt":"2020-05-08T11:42:47","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah"},"modified":"2020-05-08T13:42:47","modified_gmt":"2020-05-08T11:42:47","slug":"clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","title":{"rendered":"ClickHouse para usu\u00e1rios avan\u00e7ados em perguntas e respostas","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Em abril, engenheiros da Avito se reuniram em encontros online com o principal desenvolvedor do ClickHouse, Alexey Milovidov, e Kirill Shvakov, um desenvolvedor Golang da empresa Integros. Discutiram como usamos o sistema de gerenciamento de banco de dados e quais dificuldades enfrentamos. <\/p>\n<p><\/p>\n<p>Com base na reuni\u00e3o, reunimos um artigo com as respostas dos especialistas para nossas perguntas e as perguntas do p\u00fablico sobre backups, resharding de dados, dicion\u00e1rios externos, o driver Golang e a atualiza\u00e7\u00e3o de vers\u00f5es do ClickHouse. Isso pode ser \u00fatil para desenvolvedores que j\u00e1 trabalham ativamente com o DBMS do Yandex e est\u00e3o interessados em seu presente e futuro. As respostas s\u00e3o, por padr\u00e3o, de Alexey Milovidov, a menos que indicado de outra forma. <\/p>\n<p><\/p>\n<p>Cuidado, h\u00e1 muito texto abaixo. Esperamos que o conte\u00fado com as perguntas ajude voc\u00ea a se orientar.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"ClickHouse para usu\u00e1rios avan\u00e7ados em perguntas e respostas\" src=\"\/wp-content\/uploads\/2020\/05\/242b1d8d002fe115614435c242297fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"soderzhanie\">Conte\u00fado<\/h2>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#old-data\">O ClickHouse est\u00e1 em constante atualiza\u00e7\u00e3o, mas nossos dados n\u00e3o. O que fazer a respeito?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#backup-best-practicies\">Quais s\u00e3o as melhores pr\u00e1ticas atualmente para backups de dados do ClickHouse?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#replication\">\u00c9 poss\u00edvel organizar uma defasagem controlada de r\u00e9plicas em streams?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#soooo-changeable\">O que fazer se a estrutura da tabela mudou?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#resharding-best-practices\">Quais s\u00e3o as melhores pr\u00e1ticas atuais em resharding de dados?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#clickhouse-copier\">O ClickHouse tem a ferramenta clickhouse-copier. Voc\u00ea pode nos contar sobre ela?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#resharding-tool\">Voc\u00eas tinham uma ferramenta piloto chamada resharding. O que aconteceu com ela?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#move-to-slow-disk\">\u00c9 poss\u00edvel unir todas as partes dos dados antes de mover para discos lentos?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#up-to-date\">Como migrar para novas vers\u00f5es do ClickHouse sem a possibilidade de verificar a compatibilidade antecipadamente?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#kill-query\">O comando Kill query deve encerr\u00e1-los, mas ele n\u00e3o est\u00e1 fazendo isso. Por qu\u00ea?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#reading-time\">Como calcular o tempo de resposta sob carga de leitura?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#pimp-my-clickhouse\">O que afinar no ClickHouse para que mais dados fiquem em cache?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#storage-configuration\">Como \u00e9 poss\u00edvel configurar storage_configuration para armazenamento na mem\u00f3ria?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#low-cardinality\">At\u00e9 quantos valores \u00fanicos o Low Cardinality \u00e9 eficaz?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#fulltext-search\">Quais s\u00e3o as melhores pr\u00e1ticas para busca de texto completo em uma tabela com cinco bilh\u00f5es de linhas?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#hello-and-welcome\">Como organizar melhor o acesso ao ClickHouse para um grande n\u00famero de usu\u00e1rios?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#smorgasbord\">\u00c9 poss\u00edvel devolver os resultados de uma consulta para dez clientes?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#asynchronous\">Como lidar com opera\u00e7\u00f5es ass\u00edncronas e vis\u00f5es materializadas?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#dashboard\">O ClickHouse gera muitos logs. Como posso ver tudo que acontece com o servidor em tempo real?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#zen\">Como impactar os merges para que o servidor n\u00e3o caia em OOM?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#go\">Como ser\u00e1 feito o desenvolvimento do driver Golang para o ClickHouse?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#lazy-load\">Um dicion\u00e1rio externo n\u00e3o sobe ap\u00f3s a reinicializa\u00e7\u00e3o com a configura\u00e7\u00e3o lazy_load ativada. O que fazer?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#reload-dictionaries\">Como lidar com o fato de que system reload dictionaries n\u00e3o carrega nenhum dos v\u00e1rios dicion\u00e1rios, se pelo menos um deles falhar com erro?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#connection\">H\u00e1 alguma maneira de configurar as credenciais no&nbsp;config do ClickHouse sem exp\u00f4-las em&nbsp;erros?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#zoom-backgrounds\">B\u00f4nus: fundos para Zoom \u00e0&nbsp;partidas<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<blockquote><p>Se voc\u00ea n\u00e3o quiser ler o texto, pode assistir \u00e0 grava\u00e7\u00e3o da reuni\u00e3o <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=n1tm4j4W8ZQ&amp;t=8147s\">no&nbsp;nosso canal do YouTube<\/a><\/noindex>. Os hor\u00e1rios \u2014 no&nbsp;primeiro coment\u00e1rio abaixo do&nbsp;v\u00eddeo.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"anchorold-dataanchorclickhouse-postoyanno-obnovlyaetsya-a-nashi-dannyenbsp-net-chto-snbspetim-delat\"><noindex><a rel=\"nofollow\" name=\"old-data\"><\/a><\/noindex>ClickHouse est\u00e1 constantemente sendo atualizado, mas nossos dados&nbsp;n\u00e3o. O que fazer com&nbsp;isso?<\/h2>\n<p><\/p>\n<blockquote><p>ClickHouse est\u00e1 constantemente sendo atualizado, mas nossos dados que foram otimiza\u00e7\u00e3o final processados n\u00e3o est\u00e3o sendo atualizados e est\u00e3o guardados em&nbsp;backups. <\/p>\n<p>Suponha que tivemos algum problema e os dados foram perdidos. Decidimos restaurar e descobrimos que as antigas parti\u00e7\u00f5es que est\u00e3o salvas nos&nbsp;servidores de backup est\u00e3o muito diferentes da vers\u00e3o do ClickHouse que estamos usando atualmente. O que fazer em&nbsp;tal situa\u00e7\u00e3o e isso \u00e9 poss\u00edvel?<\/p><\/blockquote>\n<p>A situa\u00e7\u00e3o em que voc\u00ea restaurou dados de um&nbsp;backup em um formato antigo e na nova vers\u00e3o eles n\u00e3o se conectam n\u00e3o \u00e9 poss\u00edvel. N\u00f3s garantimos que o formato dos dados no&nbsp;ClickHouse permane\u00e7a sempre retrocompat\u00edvel. Isso \u00e9 muito mais importante do que a retrocompatibilidade em termos de funcionalidade se o comportamento de uma fun\u00e7\u00e3o raramente usada mudar. Os dados armazenados no&nbsp;disco devem sempre ser leg\u00edveis pela nova vers\u00e3o do ClickHouse. Essa \u00e9 a regra. <\/p>\n<p><\/p>\n<h2 id=\"anchorbackup-best-practiciesanchorkakie-luchshie-praktiki-est-nanbspdannyy-moment-ponbsprezervnomu-kopirovaniyu-dannyh-iznbspclickhouse\"><noindex><a rel=\"nofollow\" name=\"backup-best-practicies\"><\/a><\/noindex>Quais s\u00e3o as melhores pr\u00e1ticas atualmente para backups de dados do ClickHouse?<\/h2>\n<p><\/p>\n<blockquote><p>Como fazer backups levando em&nbsp;conta que temos opera\u00e7\u00f5es de otimiza\u00e7\u00e3o final, um banco de dados enorme de v\u00e1rios terabytes, e dados que s\u00e3o atualizados, digamos, nos \u00faltimos tr\u00eas dias, e depois n\u00e3o ocorrem mais procedimentos com eles? <\/p>\n<p>Podemos criar nossa pr\u00f3pria solu\u00e7\u00e3o e escrever um&nbsp;script no&nbsp;bash: colete esses backups de tal e tal maneira. Pode ser que n\u00e3o precisemos inventar nada e que a bicicleta j\u00e1 tenha sido inventada h\u00e1 muito tempo? <\/p><\/blockquote>\n<p>Primeiro, sobre as melhores pr\u00e1ticas. Meus colegas sempre sugerem, em resposta \u00e0s perguntas sobre backups, lembrar do&nbsp;servi\u00e7o \"Yandex.Cloud\", onde essa tarefa j\u00e1 foi resolvida. Portanto, use-o se houver essa possibilidade. <\/p>\n<p><\/p>\n<p>N\u00e3o h\u00e1 uma solu\u00e7\u00e3o completa, cem por cento embutida no&nbsp;ClickHouse, para backups. Existem algumas prepara\u00e7\u00f5es que podem ser usadas. Para obter uma solu\u00e7\u00e3o completa, ser\u00e1 necess\u00e1rio fazer algum trabalho manual ou criar scripts como wrappers.<\/p>\n<p><\/p>\n<p>Come\u00e7arei com as solu\u00e7\u00f5es mais simples e terminarei com as mais sofisticadas, dependendo do volume de dados e do tamanho do cluster. Quanto maior o cluster, mais complexo se torna a solu\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>Se a tabela de dados ocupa apenas alguns gigabytes, o backup pode ser feito assim: <\/p>\n<p><\/p>\n<ol>\n<li>Salvar a defini\u00e7\u00e3o das tabelas, ou seja, os metadados \u2014 <strong>show create table<\/strong>.<\/li>\n<li>Fazer um dump usando o cliente ClickHouse \u2014 <strong>select<\/strong> * <strong>from table<\/strong> para um arquivo. Por padr\u00e3o, voc\u00ea receber\u00e1 um arquivo no formato TabSeparated. Se quiser algo mais eficiente, pode utilizar o formato Native. <\/li>\n<\/ol>\n<p><\/p>\n<p>Se o volume de dados for maior, o backup levar\u00e1 mais tempo e ocupar\u00e1 mais espa\u00e7o. Isso \u00e9 chamado de backup l\u00f3gico, que n\u00e3o est\u00e1 atrelado ao formato de dados do ClickHouse. Se dispon\u00edvel, em caso extremo, voc\u00ea poder\u00e1 pegar o backup e carreg\u00e1-lo no MySQL para recupera\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p>Para casos mais avan\u00e7ados, o ClickHouse possui a capacidade de criar snapshots de parti\u00e7\u00f5es no sistema de arquivos local. Essa funcionalidade est\u00e1 dispon\u00edvel na forma de uma consulta. <strong>alter table freeze partition<\/strong>. Ou simplesmente <strong>alter table freeze<\/strong> \u2014 isso cria um snapshot de toda a tabela. <\/p>\n<p><\/p>\n<p>O snapshot ser\u00e1 criado de maneira consistente para uma tabela em um shard, ou seja, n\u00e3o \u00e9 poss\u00edvel criar um snapshot consistente para todo o cluster dessa forma. Por\u00e9m, para a maioria das tarefas, essa necessidade n\u00e3o existe, e \u00e9 suficiente executar a consulta em cada shard para obter um snapshot consistente. Ele \u00e9 criado na forma de hard links e, portanto, n\u00e3o ocupa espa\u00e7o adicional. Em seguida, voc\u00ea copia esse snapshot para um servidor de backup ou para o armazenamento que utiliza para backups.<\/p>\n<p><\/p>\n<p>Restaurar esse backup \u00e9 bastante f\u00e1cil. Primeiro, voc\u00ea cria as tabelas com as defini\u00e7\u00f5es de tabela existentes. Depois, copia os snapshots de parti\u00e7\u00f5es salvos para o Directory-Detached dos dados dessas tabelas e executa a consulta. <strong>attach partition<\/strong>. Essa solu\u00e7\u00e3o \u00e9 adequada para os volumes de dados mais significativos. <\/p>\n<p><\/p>\n<p>\u00c0s vezes, \u00e9 necess\u00e1rio algo ainda mais robusto \u2014 nos casos em que voc\u00ea tem dezenas ou at\u00e9 centenas de terabytes em cada servidor e centenas de servidores. Nesse caso, existe uma solu\u00e7\u00e3o que eu observei com colegas da \"Yandex.Metrica\". Eu n\u00e3o recomendaria a todos \u2014 leia e decida se \u00e9 adequada para voc\u00ea. <\/p>\n<p><\/p>\n<p>Primeiro, \u00e9 necess\u00e1rio criar v\u00e1rios servidores com grandes prateleiras de disco. Em seguida, nesses servidores, ser\u00e1 necess\u00e1rio configurar v\u00e1rios servidores ClickHouse e ajust\u00e1-los para que funcionem como mais uma r\u00e9plica para os mesmos shards. E ent\u00e3o usar nesses servidores um sistema de arquivos ou alguma ferramenta que permita criar snapshots. Existem duas op\u00e7\u00f5es. A primeira op\u00e7\u00e3o s\u00e3o snapshots LVM, a segunda op\u00e7\u00e3o \u00e9 ZFS no Linux. <\/p>\n<p><\/p>\n<p>Depois disso, \u00e9 preciso criar um snapshot diariamente, que ocupar\u00e1 um espa\u00e7o espec\u00edfico. Naturalmente, se os dados mudarem, ao longo do tempo, o volume de espa\u00e7o aumentar\u00e1. Esse snapshot pode ser acessado a qualquer momento e os dados podem ser restaurados, \u00e9 uma solu\u00e7\u00e3o peculiar. Al\u00e9m disso, \u00e9 necess\u00e1rio limitar essas r\u00e9plicas na configura\u00e7\u00e3o, para que n\u00e3o tentem se tornar l\u00edderes.<\/p>\n<p><\/p>\n<h2 id=\"anchorreplicationanchormozhno-li-budet-organizovat-kontroliruemoe-otstavanie-replik-vnbspvalah\"><noindex><a rel=\"nofollow\" name=\"replication\"><\/a><\/noindex>\u00c9 poss\u00edvel organizar uma defasagem controlada de r\u00e9plicas em streams?<\/h2>\n<p><\/p>\n<blockquote><p>Este ano, voc\u00ea planeja implementar rolls no ClickHouse. Ser\u00e1 poss\u00edvel organizar um atraso controlado das r\u00e9plicas? Gostar\u00edamos de usar isso para nos proteger contra cen\u00e1rios negativos com altera\u00e7\u00f5es e outras mudan\u00e7as. <\/p>\n<p>\u00c9 poss\u00edvel implementar algum tipo de rollback para os alternados? Por exemplo, em um roll existente, dizer que at\u00e9 aquele momento aplique altera\u00e7\u00f5es, e a partir desse momento, pare de aplicar altera\u00e7\u00f5es?<\/p>\n<p>Se uma equipe entrar em nosso cluster e o danificar, temos uma r\u00e9plica condicional com um atraso de uma hora, onde podemos decidir us\u00e1-la no momento, mas n\u00e3o aplicar as \u00faltimas dez minutos de mudan\u00e7as nela? <\/p><\/blockquote>\n<p>Primeiramente, sobre o atraso controlado das r\u00e9plicas. Esse pedido foi feito pelos usu\u00e1rios, e criamos uma issue no GitHub com o pedido: \"Se algu\u00e9m precisar disso, curta ou coloque um cora\u00e7\u00e3o\". Ningu\u00e9m curtiu, e a issue foi fechada. No entanto, j\u00e1 \u00e9 poss\u00edvel obter essa funcionalidade, configurando o ClickHouse. Por\u00e9m, apenas a partir da vers\u00e3o 20.3.<\/p>\n<p><\/p>\n<p>O ClickHouse est\u00e1 constantemente gerando mesclagens de dados em segundo plano. Quando a mesclagem \u00e9 feita, um conjunto de segmentos de dados \u00e9 substitu\u00eddo por um segmento maior. Enquanto isso, os segmentos de dados anteriores continuam permanecendo no disco por um determinado per\u00edodo.<\/p>\n<p><\/p>\n<p>Primeiramente, eles continuam a ser mantidos at\u00e9 que haja consultas select que os utilizem, para garantir um funcionamento n\u00e3o bloqueante. As consultas select leem tranquilamente de partes antigas.<\/p>\n<p><\/p>\n<p>Em segundo lugar, h\u00e1 tamb\u00e9m um limite de tempo \u2014 partes antigas dos dados ficam no disco por oito minutos. Esses oito minutos podem ser configurados e transformados at\u00e9 mesmo em um dia. Isso custar\u00e1 espa\u00e7o no disco: dependendo do fluxo de dados, os dados do \u00faltimo dia podem n\u00e3o apenas dobrar, mas aumentar at\u00e9 cinco vezes. Mas voc\u00ea poder\u00e1, em caso de um problema s\u00e9rio, parar o servidor ClickHouse e resolver tudo.<\/p>\n<p><\/p>\n<p>Agora surge a quest\u00e3o de como isso protege contra alters. Aqui vale a pena olhar mais a fundo, pois nas vers\u00f5es antigas do ClickHouse o alter funcionava de tal maneira que simplesmente mudava diretamente as partes. H\u00e1 uma parte de dados com alguns arquivos, e fazemos, por exemplo, <strong>alter drop column<\/strong>. Ent\u00e3o, essa coluna \u00e9 fisicamente removida de todas as partes.<\/p>\n<p><\/p>\n<p>Mas a partir da vers\u00e3o 20.3, o mecanismo de alters foi completamente modificado, e agora as partes dos dados s\u00e3o sempre imut\u00e1veis. Elas n\u00e3o mudam de modo algum \u2014 os alters agora funcionam de maneira semelhante aos merges. Em vez de alterar uma parte no local, criamos uma nova. Na nova parte, os arquivos que n\u00e3o mudaram se tornam hardlinks, e, se removemos alguma coluna, simplesmente n\u00e3o estar\u00e1 na nova parte. A parte antiga ser\u00e1 deletada por padr\u00e3o ap\u00f3s oito minutos, e aqui voc\u00ea pode ajustar as configura\u00e7\u00f5es mencionadas anteriormente. <\/p>\n<p><\/p>\n<p>O mesmo se aplica a alters do tipo muta\u00e7\u00f5es. Quando voc\u00ea faz <strong>alter delete<\/strong> ou <strong>alter update<\/strong>, ele n\u00e3o altera a parte, mas cria uma nova. E depois remove a antiga.<\/p>\n<p><\/p>\n<h2 id=\"anchorsoooo-changeableanchorkak-byt-esli-struktura-tablicy-pomenyalas\"><noindex><a rel=\"nofollow\" name=\"soooo-changeable\"><\/a><\/noindex>O que fazer se a estrutura da tabela mudou?<\/h2>\n<p><\/p>\n<blockquote><p>Como restaurar um backup que foi feito com a estrutura antiga? E a segunda pergunta \u00e9 sobre o caso com snapshots e ferramentas de sistema de arquivos. O Btrfs serve em vez do ZFS no Linux LVM?<\/p><\/blockquote>\n<p>Se voc\u00ea fizer <strong>attach partition<\/strong> Parti\u00e7\u00f5es com uma estrutura diferente, ent\u00e3o o ClickHouse dir\u00e1 que n\u00e3o \u00e9 permitido. A solu\u00e7\u00e3o \u00e9 a seguinte. Primeiro \u2014 criar uma tabela tempor\u00e1ria do tipo MergeTree com a estrutura antiga, anexar os dados usando attach, fazer a consulta alter. Depois voc\u00ea pode ou copiar ou mover esses dados e fazer attach novamente, ou usar a consulta. <strong>alterar tabela mover parti\u00e7\u00e3o<\/strong>.<\/p>\n<p><\/p>\n<p>Agora, a segunda quest\u00e3o&nbsp;\u2014 \u00e9 poss\u00edvel usar Btrfs. Para come\u00e7ar, se voc\u00ea tiver LVM, os snapshots do LVM s\u00e3o suficientes, e o sistema de arquivos pode ser ext4; isso n\u00e3o importa. Com Btrfs, tudo depende da sua experi\u00eancia na sua utiliza\u00e7\u00e3o. \u00c9 um sistema de arquivos maduro, mas ainda existem algumas d\u00favidas sobre como tudo funcionar\u00e1 na pr\u00e1tica em um cen\u00e1rio espec\u00edfico. Eu n\u00e3o recomendaria us\u00e1-lo se voc\u00ea n\u00e3o tiver Btrfs em produ\u00e7\u00e3o.<\/p>\n<p><\/p>\n<h2 id=\"anchorresharding-best-practicesanchorkakie-seychas-luchshie-praktiki-vnbspreshardinge-dannyh\"><noindex><a rel=\"nofollow\" name=\"resharding-best-practices\"><\/a><\/noindex>Quais s\u00e3o as melhores pr\u00e1ticas atuais em resharding de dados?<\/h2>\n<p><\/p>\n<p>A quest\u00e3o sobre re-sharding \u00e9 complicada e multifacetada. Aqui, podemos responder de v\u00e1rias maneiras. Pode-se abordar de um lado e dizer que no ClickHouse n\u00e3o h\u00e1 uma maneira embutida de re-sharding. Mas temo que essa resposta n\u00e3o satisfa\u00e7a ningu\u00e9m. Portanto, podemos abord\u00e1-lo do outro lado e dizer que existem muitas maneiras de re-shardear dados no ClickHouse. <\/p>\n<p><\/p>\n<p>Se o espa\u00e7o no cluster estiver acabando ou ele n\u00e3o estiver lidando com a carga, voc\u00ea adiciona novos servidores. Mas esses servidores est\u00e3o vazios por padr\u00e3o; n\u00e3o h\u00e1 dados neles e nenhuma carga est\u00e1 fluindo. Voc\u00ea precisa redistribuir os dados para que sejam uniformemente espalhados pelo novo cluster ampliado.<\/p>\n<p><\/p>\n<p>O primeiro m\u00e9todo para fazer isso&nbsp;\u2014 \u00e9 copiar parte das parti\u00e7\u00f5es para novos servidores usando uma consulta. <strong>alterar tabela buscar parti\u00e7\u00e3o<\/strong>. Por exemplo, se voc\u00ea tinha parti\u00e7\u00f5es mensais, voc\u00ea pega o primeiro m\u00eas de 2017&nbsp;e copia para um novo servidor, depois copia o terceiro m\u00eas para outro novo servidor. E voc\u00ea faz isso at\u00e9 que fique mais ou menos equilibrado.<\/p>\n<p><\/p>\n<p>A transfer\u00eancia s\u00f3 pode ser realizada para&nbsp;parti\u00e7\u00f5es que n\u00e3o mudam durante a grava\u00e7\u00e3o. Para parti\u00e7\u00f5es recentes, voc\u00ea ter\u00e1 que desativar a grava\u00e7\u00e3o, pois a transfer\u00eancia n\u00e3o \u00e9 at\u00f4mica. Caso contr\u00e1rio, voc\u00ea pode acabar com duplicatas ou lacunas nos dados. No entanto, este m\u00e9todo \u00e9 pr\u00e1tico e funciona de forma bastante eficiente. Parti\u00e7\u00f5es compactadas j\u00e1 prontas s\u00e3o transmitidas pela rede, ou seja, os dados n\u00e3o s\u00e3o recomprimidos nem reencoderados.<\/p>\n<p><\/p>\n<p>Esse m\u00e9todo tem uma desvantagem, que depende do esquema de sharding, se voc\u00ea projetou para esse esquema de sharding e qual foi sua chave de sharding. No seu exemplo para o caso com m\u00e9tricas, a chave de sharding \u00e9 o hash do caminho. Quando voc\u00ea faz um select na tabela Distributed, ele vai imediatamente para todos os shards do cluster e pega os dados de l\u00e1. <\/p>\n<p><\/p>\n<p>Isso significa que, na verdade, n\u00e3o importa quais dados est\u00e3o em qual shard. O essencial \u00e9 que os dados de um determinado caminho est\u00e3o em um \u00fanico shard, e qual exatamente n\u00e3o \u00e9 uma quest\u00e3o crucial. Nesse caso, mover parti\u00e7\u00f5es prontas \u00e9 uma boa estrat\u00e9gia, porque em consultas select voc\u00ea tamb\u00e9m \u2014 antes e depois do re-sharding \u2014 n\u00e3o afetar\u00e1 o esquema de valores, voc\u00ea receber\u00e1 os dados completos.<\/p>\n<p><\/p>\n<p>Mas h\u00e1 casos mais complexos. Se, no n\u00edvel da l\u00f3gica do aplicativo, voc\u00ea projeta um esquema de sharding especial, onde este cliente est\u00e1 em um determinado shard e a consulta pode ser enviada diretamente para l\u00e1, em vez de para a tabela Distributed. Ou voc\u00ea est\u00e1 usando uma vers\u00e3o relativamente nova do ClickHouse e ativou a configura\u00e7\u00e3o <strong>optimize skip unused shards<\/strong>. Nesse caso, durante a consulta select, a express\u00e3o na se\u00e7\u00e3o where ser\u00e1 analisada e ser\u00e1 calculado quais shards devem ser acessados de acordo com o esquema de sharding. Isso funciona sob a condi\u00e7\u00e3o de que os dados estejam distribu\u00eddos exatamente de acordo com esse esquema de sharding. Se voc\u00ea os organizou manualmente, a conformidade pode mudar.<\/p>\n<p><\/p>\n<p>Portanto, esse \u00e9 o m\u00e9todo n\u00famero um. E estou aguardando sua resposta, se esse m\u00e9todo se adequa ou se devemos prosseguir.<\/p>\n<p><\/p>\n<p><strong>Vladimir Kolobaev, administrador de sistemas l\u00edder na Avito<\/strong>: Alexey, o m\u00e9todo que voc\u00ea mencionou n\u00e3o se encaixa muito bem quando \u00e9 necess\u00e1rio distribuir a carga, incluindo a leitura. Podemos pegar uma parti\u00e7\u00e3o mensal e mover o m\u00eas anterior para outro n\u00f3, mas quando chegar uma solicita\u00e7\u00e3o por esses dados, estaremos sobrecarregando apenas ele. Gostar\u00edamos de sobrecarregar todo o cluster, porque, caso contr\u00e1rio, teremos um per\u00edodo em que toda a carga de leitura ser\u00e1 processada por dois shards.<\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> A resposta aqui \u00e9 estranha \u2014 sim, \u00e9 ruim, mas pode funcionar. Explicarei como. \u00c9 importante olhar o cen\u00e1rio de carga que est\u00e1 por tr\u00e1s dos seus dados. Se forem dados de monitoramento, quase com certeza podemos dizer que a grande maioria das consultas est\u00e1 buscando dados recentes. <\/p>\n<p><\/p>\n<p>Voc\u00ea instalou novos servidores, transferiu as parti\u00e7\u00f5es antigas, mas tamb\u00e9m alterou a forma como os novos dados s\u00e3o gravados. E os novos dados ser\u00e3o distribu\u00eddos por todo o cluster. Assim, ap\u00f3s cinco minutos, as consultas dos \u00faltimos cinco minutos ir\u00e3o sobrecarregar uniformemente o cluster, e ao longo de um dia, as consultas referentes a 24 horas tamb\u00e9m far\u00e3o o mesmo. No entanto, as consultas do m\u00eas anterior, infelizmente, s\u00f3 ocorrer\u00e3o em parte dos servidores do cluster.<\/p>\n<p><\/p>\n<p>Mas muitas vezes voc\u00ea n\u00e3o ter\u00e1 consultas espec\u00edficas de fevereiro de 2019. \u00c9 mais prov\u00e1vel que, se as consultas se referem ao ano de 2019, elas abrangem todo o ano \u2014 um intervalo de tempo grande, e n\u00e3o um pequeno. E tais consultas tamb\u00e9m poder\u00e3o sobrecarregar uniformemente o cluster. Mas, em geral, sua observa\u00e7\u00e3o est\u00e1 absolutamente correta, que se trata de uma solu\u00e7\u00e3o ad hoc, que n\u00e3o distribui os dados de forma completamente uniforme.<\/p>\n<p><\/p>\n<p>Eu ainda tenho alguns pontos para responder \u00e0 pergunta. Um deles trata de como inicialmente projetar o esquema de sharding de forma que a re-sharding cause menos dor. Isso nem sempre \u00e9 poss\u00edvel.<\/p>\n<p><\/p>\n<p>Por exemplo, voc\u00ea tem dados de monitoramento. Os dados de monitoramento crescem por tr\u00eas raz\u00f5es. A primeira \u2014 ac\u00famulo de dados hist\u00f3ricos. A segunda \u2014 aumento de tr\u00e1fego. E a terceira \u2014 maior n\u00famero de itens que est\u00e3o sob monitoramento. Novos microservi\u00e7os e m\u00e9tricas que precisam ser armazenadas est\u00e3o surgindo. <\/p>\n<p><\/p>\n<p>\u00c9 poss\u00edvel que o maior crescimento esteja relacionado \u00e0 terceira raz\u00e3o \u2014 o aumento no uso do monitoramento. E nesse caso, vale a pena observar a natureza da carga, quais s\u00e3o as principais consultas de select. As principais consultas de select provavelmente ir\u00e3o sobre um certo subconjunto de m\u00e9tricas.<\/p>\n<p><\/p>\n<p>Por exemplo, o uso da CPU em alguns servidores por algum servi\u00e7o. Assim, existe um subconjunto de chaves pelo qual voc\u00ea acessa esses dados. E a pr\u00f3pria consulta por esses dados provavelmente \u00e9 bastante simples e \u00e9 executada em dezenas de milissegundos. \u00c9 utilizada para servi\u00e7os de monitoramento, para dashboards. Espero que eu esteja entendendo isso corretamente.<\/p>\n<p><\/p>\n<p><strong>Vladimir Kolobaev:<\/strong> O fato \u00e9 que frequentemente recorremos a dados hist\u00f3ricos, pois comparamos a posi\u00e7\u00e3o atual com o hist\u00f3rico em tempo real. E para n\u00f3s, \u00e9 importante ter acesso r\u00e1pido a um grande volume de dados, e o ClickHouse se sai muito bem nesse aspecto.<\/p>\n<p><\/p>\n<p>Voc\u00ea est\u00e1 absolutamente certo, a maioria das solicita\u00e7\u00f5es de leitura que recebemos ocorre no \u00faltimo dia, como em qualquer sistema de monitoramento. No entanto, a carga sobre os dados hist\u00f3ricos tamb\u00e9m \u00e9 bastante grande. Ela prov\u00e9m principalmente do sistema de alertas, que a cada trinta segundos consulta o ClickHouse: 'Me d\u00ea os dados das \u00faltimas seis semanas. E agora, construa uma m\u00e9dia m\u00f3vel com eles e vamos comparar o valor atual com o hist\u00f3rico.' <\/p>\n<p><\/p>\n<p>Eu gostaria de mencionar que temos uma pequena tabela para essas consultas muito recentes, que armazena dados de apenas dois dias, e as consultas principais v\u00e3o para ela. Para a grande tabela sharded, enviamos apenas consultas hist\u00f3ricas grandes.<\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> Infelizmente, para o seu cen\u00e1rio isso n\u00e3o se aplica bem, mas vou descrever duas schemas de sharding ruins e complexas que n\u00e3o devem ser usadas, mas que s\u00e3o utilizadas no servi\u00e7o de meus amigos. <\/p>\n<p><\/p>\n<p>H\u00e1 um cluster principal com eventos do 'Yandex.Metrics'. Os eventos s\u00e3o visualiza\u00e7\u00f5es de p\u00e1ginas, cliques e transi\u00e7\u00f5es. A maioria das solicita\u00e7\u00f5es vai para um site espec\u00edfico. Voc\u00ea abre o servi\u00e7o 'Yandex.Metrics', tem um site - avito.ru, acessa o relat\u00f3rio e a solicita\u00e7\u00e3o \u00e9 feita com base no seu site.<\/p>\n<p><\/p>\n<p>Mas h\u00e1 tamb\u00e9m outras solicita\u00e7\u00f5es - anal\u00edticas e globais, realizadas por analistas internos. Para constar, os analistas internos fazem solicita\u00e7\u00f5es apenas para os servi\u00e7os do 'Yandex'. No entanto, mesmo os servi\u00e7os do 'Yandex' representam uma parte significativa de todos os dados. Essas s\u00e3o solicita\u00e7\u00f5es n\u00e3o para contadores espec\u00edficos, mas para uma filtragem mais ampla.<\/p>\n<p><\/p>\n<p>Como organizar os dados de forma que funcione eficientemente tanto para um \u00fanico contador quanto para as solicita\u00e7\u00f5es globais? A complexidade reside no fato de que o n\u00famero de solicita\u00e7\u00f5es no ClickHouse para o cluster 'Metrics' \u00e9 de milhares por segundo. Ao mesmo tempo, solicita\u00e7\u00f5es n\u00e3o triviais, por exemplo, milhares por segundo, um \u00fanico servidor ClickHouse n\u00e3o consegue suportar.<\/p>\n<p><\/p>\n<p>O tamanho do cluster&nbsp;\u2014 seiscentos e poucos servidores. Se simplesmente cobrirmos esse cluster com uma tabela distribu\u00edda e enviarmos milhares de solicita\u00e7\u00f5es, ser\u00e1 ainda pior do que envi\u00e1-las para um \u00fanico servidor. Por outro lado, a op\u00e7\u00e3o de que os dados est\u00e3o uniformemente espalhados e n\u00f3s vamos e solicitamos de todos os servidores j\u00e1 descarta imediatamente.<\/p>\n<p><\/p>\n<p>H\u00e1 uma op\u00e7\u00e3o diametralmente oposta. Imagine que se formos fragmentar os dados por sites, e a solicita\u00e7\u00e3o para um site ir\u00e1 para um \u00fanico fragmento. Agora o cluster pode facilmente lidar com dez mil solicita\u00e7\u00f5es por segundo, mas em um fragmento, uma \u00fanica solicita\u00e7\u00e3o funcionar\u00e1 muito lentamente. Ela j\u00e1 n\u00e3o escalaria em capacidade de passagem. Especialmente se este for o site avito.ru. N\u00e3o revelarei nenhum segredo ao dizer que o Avito&nbsp;\u2014 \u00e9 um dos sites mais visitados da Runet. E process\u00e1-lo em um \u00fanico fragmento seria um absurdo.<\/p>\n<p><\/p>\n<p>Portanto, o esquema de fragmenta\u00e7\u00e3o \u00e9 organizado de forma mais engenhosa. Todo o cluster \u00e9 dividido em um certo n\u00famero de microclusters, que chamamos de camadas. Dentro de cada microcluster, h\u00e1 de uma a v\u00e1rias dezenas de fragmentos. E no total h\u00e1 trinta e nove desses microclusters. <\/p>\n<p><\/p>\n<p>Como tudo isso escala? O n\u00famero de microclusters n\u00e3o muda&nbsp;\u2014 como havia trinta e nove alguns anos atr\u00e1s, assim continua. Mas dentro de cada um deles, aumentamos gradualmente o n\u00famero de fragmentos \u00e0 medida que os dados se acumulam. E o esquema de fragmenta\u00e7\u00e3o em geral \u00e9 assim&nbsp;\u2014 a divis\u00e3o nesses microclusters ocorre por websites, e para entender qual site est\u00e1 em qual cluster, usamos uma base de dados separada no MySQL. Um site&nbsp;\u2014 em um microcluster. E dentro dele, a fragmenta\u00e7\u00e3o ocorre por identificadores de visitantes.<\/p>\n<p><\/p>\n<p>Ao gravar, dividimos os dados com base no restante da divis\u00e3o do identificador do visitante. Mas ao adicionar um novo shard, o esquema de sharding muda; continuamos a dividir, mas com o restante da divis\u00e3o por outro n\u00famero. Isso significa que um visitante pode estar localizado em v\u00e1rios servidores, e n\u00e3o podemos contar com isso. Isso foi feito exclusivamente para que os dados fossem melhor compactados. E nas consultas, vamos para a tabela Distributed, que observa o cluster e se conecta a dezenas de servidores. Esse \u00e9 um esquema complicado.<\/p>\n<p><\/p>\n<p>Mas minha narrativa estaria incompleta se eu n\u00e3o mencionasse que abandonamos esse esquema. No novo esquema, mudamos tudo e copiamos todos os dados usando o clickhouse-copier.<\/p>\n<p><\/p>\n<p>No novo esquema, todos os sites s\u00e3o divididos em duas categorias \u2014 grandes e pequenos. Eu n\u00e3o sei como o limite foi escolhido, mas o resultado foi que grandes sites s\u00e3o gravados em um \u00fanico cluster, com 120 shards e tr\u00eas r\u00e9plicas em cada um \u2014 ou seja, 360 servidores. E o esquema de sharding \u00e9 tal que qualquer solicita\u00e7\u00e3o vai diretamente para todos os shards. Se voc\u00ea abrir qualquer p\u00e1gina de relat\u00f3rio para avito.ru no \"Yandex.Metrica\" agora, a solicita\u00e7\u00e3o ir\u00e1 para 120 servidores. H\u00e1 poucos sites grandes no Runet. Assim, as solicita\u00e7\u00f5es n\u00e3o s\u00e3o mil por segundo, mas at\u00e9 menos de cem. Todo esse volume \u00e9 processado confortavelmente pela tabela Distributed, que trata cada um deles com 120 servidores.<\/p>\n<p><\/p>\n<p>E o segundo cluster \u00e9 para sites pequenos. Aqui, o esquema de sharding \u00e9 baseado no identificador do site, e cada solicita\u00e7\u00e3o vai exatamente para um shard.<\/p>\n<p><\/p>\n<h2 id=\"anchorclickhouse-copieranchorv-clickhouse-est-utilita-clickhouse-copier-mozhete-pronbspneyo-rasskazat\"><noindex><a rel=\"nofollow\" name=\"clickhouse-copier\"><\/a><\/noindex>O ClickHouse tem a ferramenta clickhouse-copier. Voc\u00ea pode nos contar sobre ela?<\/h2>\n<p><\/p>\n<p>Devo dizer que essa solu\u00e7\u00e3o \u00e9 mais volumosa e um pouco menos eficiente. A vantagem \u00e9 que ela espalha os dados completamente de acordo com o esquema que voc\u00ea especificar. Mas a desvantagem da ferramenta \u00e9 que ela n\u00e3o realiza o reshaping. Ela copia dados de um esquema de cluster para outro esquema de cluster.<\/p>\n<p><\/p>\n<p>Isso significa que para seu funcionamento voc\u00ea deve ter dois clusters. Eles podem estar localizados nos mesmos servidores, mas, mesmo assim, os dados n\u00e3o ser\u00e3o movidos de forma incremental; em vez disso, ser\u00e3o copiados. <\/p>\n<p><\/p>\n<p>Por exemplo, havia quatro servidores, agora s\u00e3o oito. Voc\u00ea cria uma nova tabela Distributed em todos os servidores, novas tabelas locais e inicia o clickhouse-copier, indicando nele o esquema de trabalho, que deve ler de l\u00e1, aceitar o novo esquema de sharding e mover os dados para l\u00e1. E voc\u00ea precisar\u00e1 de uma vez e meia mais espa\u00e7o nos servidores antigos do que h\u00e1 agora, porque os dados antigos devem permanecer neles, e em cima deles chegar\u00e1 metade desses mesmos dados antigos. Se voc\u00ea pensou de antem\u00e3o que os dados precisariam ser resharded e h\u00e1 espa\u00e7o, ent\u00e3o essa abordagem funcionar\u00e1.<\/p>\n<p><\/p>\n<p>Como o clickhouse-copier funciona internamente? Ele divide todo o trabalho em um conjunto de tarefas para processar uma parti\u00e7\u00e3o de uma tabela em um shard. Todas essas tarefas podem ser executadas em paralelo, e o clickhouse-copier pode ser executado em m\u00e1quinas diferentes em v\u00e1rias inst\u00e2ncias, mas o que ele faz para uma parti\u00e7\u00e3o \u00e9 nada mais que um insert select. Os dados s\u00e3o lidos, descompactados, redistribu\u00eddos, compactados novamente, gravados em algum lugar e reorganizados. Essa \u00e9 uma solu\u00e7\u00e3o mais pesada.<\/p>\n<p><\/p>\n<h2 id=\"anchorresharding-toolanchoru-vas-byla-pilotnaya-shtuka-kotoraya-nazyvalas-resharding-chto-snbspney\"><noindex><a rel=\"nofollow\" name=\"resharding-tool\"><\/a><\/noindex>Voc\u00eas tinham uma ferramenta piloto chamada resharding. O que aconteceu com ela?<\/h2>\n<p><\/p>\n<blockquote><p>Voc\u00ea teve uma experi\u00eancia piloto em 2017 chamada resharding. Existe at\u00e9 uma op\u00e7\u00e3o no ClickHouse. Pelo que entendi, isso n\u00e3o decolou. Voc\u00ea pode contar por que aconteceu isso? Parece ser bastante relevante.<\/p><\/blockquote>\n<p>O problema \u00e9 que, quando h\u00e1 necessidade de reshardar os dados, \u00e9 necess\u00e1ria uma sincroniza\u00e7\u00e3o bastante complexa para que isso seja feito de forma at\u00f4mica. Quando come\u00e7amos a observar como essa sincroniza\u00e7\u00e3o funciona, ficou claro que havia problemas fundamentais. E estes problemas fundamentais n\u00e3o s\u00e3o apenas te\u00f3ricos, mas tamb\u00e9m come\u00e7aram a se mostrar na pr\u00e1tica como algo que pode ser explicado de forma muito simples \u2014 nada funciona.<\/p>\n<p><\/p>\n<h2 id=\"anchormove-to-slow-diskanchormozhno-li-slivat-vse-chasti-dannyh-voedino-perednbspperemescheniem-nanbspmedlennye-diski\"><noindex><a rel=\"nofollow\" name=\"move-to-slow-disk\"><\/a><\/noindex>\u00c9 poss\u00edvel unir todas as partes dos dados antes de mover para discos lentos?<\/h2>\n<p><\/p>\n<blockquote><p>Uma pergunta sobre TTL com a op\u00e7\u00e3o de mover para disco lento no contexto de merges. Existe alguma maneira, al\u00e9m de usar cron, de fundir todas as partes em uma s\u00f3 antes de mov\u00ea-las para discos lentos?<\/p><\/blockquote>\n<p>A resposta para a pergunta se \u00e9 poss\u00edvel automaticamente unir todas as partes em uma antes de seu deslocamento \u00e9 \u2014 n\u00e3o. N\u00e3o vejo necessidade disso. N\u00e3o \u00e9 preciso unir todas as partes em uma, basta contar que elas ser\u00e3o movidas para os discos lentos automaticamente. <\/p>\n<p><\/p>\n<p>Temos dois crit\u00e9rios para a migra\u00e7\u00e3o. O primeiro \u00e9 baseado na capacidade de armazenamento. Se a quantidade de espa\u00e7o livre no n\u00edvel atual de armazenamento for menor que determinada porcentagem, escolhemos um bloco e o transferimos para um armazenamento mais lento. Ou melhor, n\u00e3o um armazenamento mais lento, mas o pr\u00f3ximo \u2014 conforme voc\u00ea configurar.<\/p>\n<p><\/p>\n<p>O segundo crit\u00e9rio \u00e9 baseado no tamanho. Ele se refere \u00e0 migra\u00e7\u00e3o de blocos grandes. Voc\u00ea pode ajustar o limite de espa\u00e7o livre no disco r\u00e1pido, e os dados ser\u00e3o transferidos automaticamente.<\/p>\n<p><\/p>\n<h2 id=\"anchorup-to-dateanchorkak-pereezzhat-nanbspnovye-versii-clickhouse-esli-net-vozmozhnosti-zaranee-proverit-sovmestimost\"><noindex><a rel=\"nofollow\" name=\"up-to-date\"><\/a><\/noindex>Como migrar para novas vers\u00f5es do ClickHouse sem a possibilidade de verificar a compatibilidade antecipadamente?<\/h2>\n<p><\/p>\n<blockquote><p>Este t\u00f3pico \u00e9 discutido regularmente <noindex><a rel=\"nofollow\" href=\"https:\/\/teleg.run\/clickhouse_ru\">no chat do Telegram ClickHouse<\/a><\/noindex> considerando as diferentes vers\u00f5es, mesmo assim. Qu\u00e3o seguro \u00e9 atualizar da vers\u00e3o 19.11 para 19.16 e, por exemplo, de 19.16 para 20.3. Qual \u00e9 a melhor forma de migrar para novas vers\u00f5es, sem ter a possibilidade de verificar a compatibilidade em um ambiente de testes?<\/p><\/blockquote>\n<p>Aqui est\u00e3o algumas regras \"de ouro\". A primeira \u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/ClickHouse\/blob\/master\/CHANGELOG.md\">ler o changelog<\/a><\/noindex>. \u00c9 extensa, mas h\u00e1 se\u00e7\u00f5es espec\u00edficas sobre mudan\u00e7as incompat\u00edveis. N\u00e3o deve-se tratar esses pontos como um sinal vermelho. Normalmente, s\u00e3o pequenas incompatibilidades relacionadas a funcionalidades que, provavelmente, voc\u00ea n\u00e3o utiliza.<\/p>\n<p><\/p>\n<p>A segunda \u00e9 que, se n\u00e3o h\u00e1 como verificar a compatibilidade em um ambiente de testes e voc\u00ea deseja atualizar diretamente na produ\u00e7\u00e3o, a recomenda\u00e7\u00e3o \u00e9 \u2014 n\u00e3o fa\u00e7a isso. Primeiro, crie um ambiente de testes e verifique. Se voc\u00ea n\u00e3o tiver um ambiente de testes, sua empresa provavelmente n\u00e3o \u00e9 muito grande e, portanto, \u00e9 poss\u00edvel copiar uma parte dos dados para o seu laptop e verificar se tudo funciona corretamente. Voc\u00ea pode at\u00e9 levantar algumas r\u00e9plicas localmente na sua m\u00e1quina. Ou pode criar uma nova vers\u00e3o em algum lugar pr\u00f3ximo e carregar l\u00e1 uma parte dos dados \u2014 ou seja, fazer um ambiente de testes improvisado. <\/p>\n<p><\/p>\n<p>Mais uma regra \u00e9 \u2014 n\u00e3o atualizar durante uma semana ap\u00f3s o lan\u00e7amento de uma nova vers\u00e3o, devido \u00e0 detec\u00e7\u00e3o de bugs em produ\u00e7\u00e3o e subsequentes corre\u00e7\u00f5es r\u00e1pidas. Vamos entender a numera\u00e7\u00e3o das vers\u00f5es do ClickHouse, para n\u00e3o nos perdermos. <\/p>\n<p><\/p>\n<p>H\u00e1 uma vers\u00e3o 20.3.4. O n\u00famero 20&nbsp;indica o ano de lan\u00e7amento&nbsp;\u2014 2020. Do ponto de vista do que est\u00e1 dentro, isso n\u00e3o tem import\u00e2ncia, ent\u00e3o n\u00e3o vamos nos atentar a isso. A seguir&nbsp;\u2014 20.3. O segundo d\u00edgito&nbsp;\u2014 neste caso 3 \u2014 aumentamos toda vez que lan\u00e7amos uma vers\u00e3o com alguma nova funcionalidade. Se quisermos adicionar alguma capacidade ao ClickHouse, somos obrigados a aumentar esse n\u00famero. Ou seja, na vers\u00e3o 20.4, o ClickHouse funcionar\u00e1 ainda melhor. O terceiro d\u00edgito&nbsp;\u2014 20.3.4. Aqui, 4 \u00e9 o n\u00famero de lan\u00e7amentos de patch, nos quais n\u00e3o adicionamos novas funcionalidades, mas corrigimos alguns bugs. E 4&nbsp;significa que fizemos isso quatro vezes.<\/p>\n<p><\/p>\n<p>N\u00e3o \u00e9 necess\u00e1rio pensar que isso \u00e9 algo horr\u00edvel. Normalmente, o usu\u00e1rio pode instalar a vers\u00e3o mais recente, e ela funcionar\u00e1 sem qualquer problema por um ano. Mas imagine que, em alguma fun\u00e7\u00e3o para processamento de bitmaps, que foi adicionada pelos nossos colegas chineses, ao passar argumentos incorretos o servidor cai. Precisamos corrigir isso. Lan\u00e7aremos uma nova vers\u00e3o de patch, e o ClickHouse se tornar\u00e1 mais est\u00e1vel.<\/p>\n<p><\/p>\n<p>Se voc\u00ea tem o ClickHouse rodando em produ\u00e7\u00e3o, e uma nova vers\u00e3o do ClickHouse \u00e9 lan\u00e7ada com recursos adicionais \u2014 por exemplo, 20.4.1 \u2014 no primeiro dia, n\u00e3o se apresse para coloc\u00e1-la em produ\u00e7\u00e3o. Para que ela serve, na verdade? Se voc\u00ea ainda n\u00e3o usa o ClickHouse, pode instal\u00e1-lo e, provavelmente, tudo funcionar\u00e1 bem. Mas se o ClickHouse j\u00e1 est\u00e1 funcionando de forma est\u00e1vel, fique de olho nos patches e atualiza\u00e7\u00f5es \u2014 quais problemas estamos corrigindo.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Quero complementar um pouco sobre ambientes de teste. Todos t\u00eam muito medo de ambientes de teste e, por algum motivo, acham que, se voc\u00ea tem um cluster muito grande de ClickHouse, o ambiente de teste deve ser no m\u00ednimo do mesmo tamanho ou pelo menos dez vezes menor. N\u00e3o \u00e9 assim que funciona.<\/p>\n<p><\/p>\n<p>Posso falar pela minha pr\u00f3pria experi\u00eancia. Eu tenho um projeto, e l\u00e1 temos ClickHouse. Nosso ambiente de teste para ele&nbsp;\u2014 \u00e9 uma pequena m\u00e1quina virtual na Hetzner por vinte euros, onde tudo est\u00e1 totalmente implementado. Para fazer isso, temos total automa\u00e7\u00e3o no Ansible, ent\u00e3o, em princ\u00edpio, n\u00e3o faz diferen\u00e7a para onde vamos \u2014 para servidores f\u00edsicos ou apenas para serem executados em m\u00e1quinas virtuais.<\/p>\n<p><\/p>\n<p>O que pode ser feito? Seria bom ter na documenta\u00e7\u00e3o do ClickHouse um exemplo de como implantar um pequeno cluster \u2014 em Docker, em LXC, talvez criar um playbook do Ansible, pois as implanta\u00e7\u00f5es variam entre as pessoas. Isso facilitaria muito. Quando voc\u00ea pode implantar um cluster em cinco minutos, fica muito mais f\u00e1cil tentar entender algo. Assim \u00e9 muito mais conveniente, porque levar para a vers\u00e3o de produ\u00e7\u00e3o algo que voc\u00ea n\u00e3o testou \u2014 \u00e9 um caminho sem volta. \u00c0s vezes funciona, outras vezes n\u00e3o. Portanto, confiar apenas na sorte \u2014 \u00e9 um erro.<\/p>\n<p><\/p>\n<p><strong>Maxim Kotiakov, engenheiro backend s\u00eanior da Avito:<\/strong> Vou adicionar algo sobre ambientes de teste que s\u00e3o problemas comuns em grandes empresas. Temos um cluster ClickHouse de aceita\u00e7\u00e3o, que \u00e9 uma c\u00f3pia exata em termos de esquemas de dados e configura\u00e7\u00f5es do que temos em produ\u00e7\u00e3o. Este cluster est\u00e1 implantado em cont\u00eaineres bastante simples, com recursos m\u00ednimos. Estamos escrevendo uma certa porcentagem dos dados de produ\u00e7\u00e3o, pois temos a capacidade de replicar o fluxo no Kafka. Tudo l\u00e1 est\u00e1 sincronizado e escalonado \u2014 tanto em capacidade quanto em fluxo, e, teoricamente, sob condi\u00e7\u00f5es iguais, deve se comportar como a produ\u00e7\u00e3o em termos de m\u00e9tricas. Todo o potencialmente problem\u00e1tico primeiro vai para este ambiente e fica l\u00e1 por alguns dias at\u00e9 estar pronto. Mas, naturalmente, essa solu\u00e7\u00e3o \u00e9 cara, pesada e custa dinheiro para manuten\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> Vou descrever como \u00e9 o ambiente de teste dos nossos amigos da 'Yandex.Metrica'. Um cluster tinha mais de 600 servidores, outro tinha 360, e h\u00e1 um terceiro e v\u00e1rios outros clusters. O ambiente de teste para um deles \u2014 \u00e9 simplesmente dois shards com duas r\u00e9plicas em cada um. Por que dois shards? Para que n\u00e3o haja apenas um. E as r\u00e9plicas tamb\u00e9m precisam existir. Somente uma quantidade m\u00ednima que se pode permitir.<\/p>\n<p><\/p>\n<p>Esse ambiente de teste permite verificar a funcionalidade das consultas e se algo grande n\u00e3o quebrou. Mas frequentemente, surgem problemas de outra natureza, quando tudo funciona, mas h\u00e1 algumas pequenas mudan\u00e7as na carga.<\/p>\n<p><\/p>\n<p>Vou dar um exemplo. Decidimos instalar uma nova vers\u00e3o do ClickHouse. Ela foi disponibilizada em um ambiente de teste, passando por testes automatizados na pr\u00f3pria 'Yandex.Metrica', que compara os dados da vers\u00e3o antiga e da nova, executando toda a linha de produ\u00e7\u00e3o. E, naturalmente, os testes verdes do nosso CI. Caso contr\u00e1rio, nem ter\u00edamos sugerido essa vers\u00e3o.<\/p>\n<p><\/p>\n<p>Tudo \u00f3timo. Come\u00e7amos a rodar em produ\u00e7\u00e3o. Recebo uma mensagem dizendo que a carga nos gr\u00e1ficos aumentou v\u00e1rias vezes. Revertamos a vers\u00e3o. Olhei para o gr\u00e1fico e vi: a carga realmente aumentou v\u00e1rias vezes durante a implanta\u00e7\u00e3o, e voltou a diminuir quando foi implantada. Depois come\u00e7amos a reverter a vers\u00e3o. E a carga aumentou da mesma maneira e tamb\u00e9m caiu de volta. Portanto, a conclus\u00e3o \u00e9 que a carga aumentou em raz\u00e3o da implanta\u00e7\u00e3o, nada surpreendente.<\/p>\n<p><\/p>\n<p>Depois foi dif\u00edcil convencer os colegas a realmente instalar a nova vers\u00e3o. Eu disse: 'Est\u00e1 tudo bem, fa\u00e7am a implanta\u00e7\u00e3o. Usem os dedos, tudo vai funcionar. Agora a carga aumentou nos gr\u00e1ficos, mas est\u00e1 tudo certo. Segurem-se'. Ent\u00e3o, fizemos isso e pronto \u2014 a vers\u00e3o foi implantada em produ\u00e7\u00e3o. Mas quase a cada implanta\u00e7\u00e3o surgem problemas semelhantes.<\/p>\n<p><\/p>\n<h2 id=\"anchorkill-queryanchorkill-query-dolzhen-ubivat-zaprosy-no-on-etogo-ne-delaet-pochemu\"><noindex><a rel=\"nofollow\" name=\"kill-query\"><\/a><\/noindex>O comando Kill query deve encerr\u00e1-los, mas ele n\u00e3o est\u00e1 fazendo isso. Por qu\u00ea?<\/h2>\n<p><\/p>\n<blockquote><p>Um usu\u00e1rio veio at\u00e9 mim, um analista, e criou uma consulta que derrubou meu cluster ClickHouse. Alguma nod ou o cluster inteiro \u2014 dependendo de qual r\u00e9plica ou shard a consulta atingiu. Eu vejo que todos os recursos de CPU nesse servidor est\u00e3o no limite, tudo vermelho. No entanto, o pr\u00f3prio ClickHouse est\u00e1 respondendo \u00e0s consultas. E eu escrevo: 'Mostre-me, por favor, a lista de processos, qual consulta gerou essa loucura'.<\/p>\n<p>Eu encontro essa consulta e escrevo para matar. E vejo que nada acontece. Meu servidor est\u00e1 no limite, o ClickHouse continua me enviando alguns comandos, mostrando que o servidor est\u00e1 ativo, e tudo est\u00e1 bem. Mas estou enfrentando degrada\u00e7\u00e3o em todas as consultas dos usu\u00e1rios, come\u00e7a a haver degrada\u00e7\u00e3o na escrita no ClickHouse, e meu comando de matar n\u00e3o funciona. Por qu\u00ea? Eu pensei que o comando de matar deveria encerrar as consultas, mas isso n\u00e3o acontece.<\/p><\/blockquote>\n<p>Agora ter\u00e1 uma resposta um tanto estranha. O fato \u00e9 que o comando de matar n\u00e3o encerra consultas. <\/p>\n<p><\/p>\n<p>A consulta Kill query define uma pequena flag chamada \"quero que esta consulta seja encerrada\". A pr\u00f3pria consulta, ao processar cada bloco, verifica essa flag. Se ela estiver ativada, a consulta para de funcionar. Portanto, n\u00e3o se trata de algu\u00e9m matar a consulta; ela mesma deve verificar e interromper. Isso deve funcionar em todos os casos, quando a consulta est\u00e1 processando blocos de dados. Ela processar\u00e1 o pr\u00f3ximo bloco de dados, verificar\u00e1 a flag e parar\u00e1.<\/p>\n<p><\/p>\n<p>Isso n\u00e3o funciona em casos onde a consulta est\u00e1 bloqueada em alguma opera\u00e7\u00e3o. No entanto, provavelmente esse n\u00e3o \u00e9 o seu caso, pois, segundo suas palavras, ela est\u00e1 usando muitos recursos do servidor. Talvez isso n\u00e3o funcione em caso de ordena\u00e7\u00e3o externa e em alguns outros detalhes. Mas, no geral, isso n\u00e3o deveria acontecer; trata-se de um bug. E a \u00fanica coisa que posso sugerir \u00e9 atualizar o ClickHouse.<\/p>\n<p><\/p>\n<h2 id=\"anchorreading-timeanchorkak-rasschitat-vremya-otveta-pri-chitayuschey-nagruzke\"><noindex><a rel=\"nofollow\" name=\"reading-time\"><\/a><\/noindex>Como calcular o tempo de resposta sob carga de leitura?<\/h2>\n<p><\/p>\n<blockquote><p>H\u00e1 uma tabela que armazena agrega\u00e7\u00f5es por item \u2014 diferentes contadores. O n\u00famero de linhas \u00e9 de cerca de cem milh\u00f5es. \u00c9 poss\u00edvel contar com um tempo de resposta previs\u00edvel se forem enviados 1K RPS para 1K itens? <\/p><\/blockquote>\n<p>Pelo contexto, trata-se de carga de leitura, pois n\u00e3o h\u00e1 problemas com grava\u00e7\u00e3o \u2014 \u00e9 poss\u00edvel inserir mil, cem mil ou at\u00e9 mesmo v\u00e1rios milh\u00f5es de linhas. <\/p>\n<p><\/p>\n<p>As consultas de leitura s\u00e3o bem variadas. No select 1, o ClickHouse pode executar cerca de dezenas de milhares de consultas por segundo, portanto at\u00e9 mesmo consultas de uma \u00fanica chave j\u00e1 demandam alguns recursos. E essas consultas pontuais ser\u00e3o mais complexas do que em bancos de dados key-value, pois para cada leitura \u00e9 necess\u00e1rio ler um bloco de dados por meio do \u00edndice. O \u00edndice endere\u00e7a n\u00e3o cada registro, mas cada faixa. Isso significa que ser\u00e1 necess\u00e1rio ler toda a faixa \u2014 que \u00e9 de 8192 linhas por padr\u00e3o. Al\u00e9m disso, ser\u00e1 preciso descompactar um bloco de dados comprimido de 64 KB para 1 MB. Geralmente, essas consultas pontuais levam de alguns milissegundos. Mas essa \u00e9 a vers\u00e3o mais simples.<\/p>\n<p><\/p>\n<p>Vamos tentar fazer uma aritm\u00e9tica simples. Se multiplicarmos alguns milissegundos por mil, teremos alguns segundos. Como se manter mil requisi\u00e7\u00f5es por segundo n\u00e3o fosse poss\u00edvel, mas na verdade \u00e9, porque temos v\u00e1rios n\u00facleos de processador. Portanto, em princ\u00edpio, o ClickHouse pode suportar 1000 RPS \u00e0s vezes, mas em consultas curtas, precisamente as pontuais.<\/p>\n<p><\/p>\n<p>Se precisar escalar um cluster ClickHouse em rela\u00e7\u00e3o ao n\u00famero de consultas simples, recomendo o mais simples \u2014 aumentar o n\u00famero de r\u00e9plicas e enviar consultas para uma r\u00e9plica aleat\u00f3ria. Se uma r\u00e9plica suporta quinhentas requisi\u00e7\u00f5es por segundo, o que \u00e9 completamente realista, ent\u00e3o tr\u00eas r\u00e9plicas suportar\u00e3o mil e quinhentas.<\/p>\n<p><\/p>\n<p>\u00c0s vezes, claro, \u00e9 poss\u00edvel tamb\u00e9m configurar o ClickHouse para o n\u00famero m\u00e1ximo de leituras pontuais. O que \u00e9 necess\u00e1rio para isso? Primeiro \u2014 reduzir a granularidade do \u00edndice. Ao fazer isso, n\u00e3o se deve diminuir para um, mas com base no c\u00e1lculo de que o n\u00famero de registros no \u00edndice ter\u00e1 alguns milh\u00f5es ou dezenas de milh\u00f5es no servidor. Se a tabela tiver cem milh\u00f5es de linhas, pode-se definir a granularidade como 64.<\/p>\n<p><\/p>\n<p>\u00c9 poss\u00edvel reduzir o tamanho do bloco comprimido. Para isso, existem configura\u00e7\u00f5es <strong>tamanho m\u00ednimo do bloco comprimido<\/strong>, <strong>tamanho m\u00e1ximo do bloco comprimido<\/strong>. Elas podem ser reduzidas, os dados podem ser reajustados, e ent\u00e3o as consultas pontuais ser\u00e3o mais r\u00e1pidas. Mas, ainda assim, o ClickHouse n\u00e3o \u00e9 um banco de dados key-value. Um grande n\u00famero de pequenas consultas \u00e9 um antipadr\u00e3o de carga.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Vou dar uma dica caso haja contadores comuns. Esta \u00e9 uma situa\u00e7\u00e3o bastante padr\u00e3o em que o ClickHouse armazena algum contador. Eu tenho um usu\u00e1rio, ele \u00e9 de tal pa\u00eds, com mais um terceiro campo, e precisa aumentar algo de forma incremental. Voc\u00ea pega o MySQL, cria uma chave \u00fanica \u2014 no MySQL \u00e9 uma chave duplicada, no PostgreSQL \u00e9 um conflito \u2014 e adiciona com um sinal de mais. Isso funcionar\u00e1 muito melhor. <\/p>\n<p><\/p>\n<p>Quando voc\u00ea tem poucos dados, n\u00e3o faz sentido usar o ClickHouse, especialmente. Existem bancos de dados comuns que lidam bem com isso. <\/p>\n<p><\/p>\n<h2 id=\"anchorpimp-my-clickhouseanchorchto-podtyunit-v-clickhouse-chtoby-bolshe-dannyh-bylo-vnbspkeshe\"><noindex><a rel=\"nofollow\" name=\"pimp-my-clickhouse\"><\/a><\/noindex>O que afinar no ClickHouse para que mais dados fiquem em cache?<\/h2>\n<p><\/p>\n<blockquote><p>Vamos imaginar uma situa\u00e7\u00e3o \u2014 nos servidores h\u00e1 256 GB de RAM, na rotina di\u00e1ria o ClickHouse consome cerca de 60 a 80 GB, no pico \u2014 at\u00e9 130. O que pode ser ativado e ajustado para que mais dados fiquem em cache e, consequentemente, haja menos acessos ao disco?<\/p><\/blockquote>\n<p>Em geral, o cache de p\u00e1gina do sistema operacional lida bem com essa tarefa. Se voc\u00ea simplesmente abre o top e v\u00ea l\u00e1 cached ou free \u2014 tamb\u00e9m est\u00e1 indicado quanto est\u00e1 cacheado \u2014 voc\u00ea pode notar que toda a mem\u00f3ria livre \u00e9 utilizada para cache. E esses dados, ao serem lidos, ser\u00e3o acessados n\u00e3o do disco, mas da mem\u00f3ria RAM. Posso afirmar que o cache est\u00e1 sendo usado de maneira eficaz, pois os dados compactados s\u00e3o exatamente os que est\u00e3o em cache.<\/p>\n<p><\/p>\n<p>No entanto, se voc\u00ea deseja acelerar ainda mais alguns comandos simples, existe a possibilidade de habilitar o cache de dados descompactados dentro do ClickHouse. Isso \u00e9 chamado de <strong>cache descomprimido<\/strong>. No arquivo de configura\u00e7\u00e3o config.xml, voc\u00ea define o tamanho do cache n\u00e3o compactado para o valor que precisar \u2014 eu aconselho a n\u00e3o ultrapassar metade da mem\u00f3ria RAM livre, pois o restante ser\u00e1 usado para o cache de p\u00e1gina. <\/p>\n<p><\/p>\n<p>Al\u00e9m disso, h\u00e1 duas configura\u00e7\u00f5es no n\u00edvel da consulta. A primeira configura\u00e7\u00e3o \u00e9 <strong>usar cache n\u00e3o compactado<\/strong> \u2014 habilita seu uso. Recomenda-se ativ\u00e1-lo para todas as consultas, exceto as pesadas, que podem ler todos os dados e limpar esse cache. E a segunda configura\u00e7\u00e3o \u00e9 algo como o n\u00famero m\u00e1ximo de linhas para o uso do cache. Ela limita automaticamente grandes consultas para que elas fiquem fora do cache.<\/p>\n<p><\/p>\n<h2 id=\"anchorstorage-configurationanchorkak-mozhno-nastroit-storage_configuration-dlya-hraneniya-v-operativke\"><noindex><a rel=\"nofollow\" name=\"storage-configuration\"><\/a><\/noindex>Como \u00e9 poss\u00edvel configurar storage_configuration para armazenamento na mem\u00f3ria?<\/h2>\n<p><\/p>\n<blockquote><p>Na nova documenta\u00e7\u00e3o do ClickHouse, encontrei uma se\u00e7\u00e3o relacionada <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/single\/#table_engine-mergetree-multiple-volumes\">com armazenamento de dados<\/a><\/noindex>. Na descri\u00e7\u00e3o h\u00e1 um exemplo com SSD r\u00e1pido. <\/p>\n<p>\u00c9 interessante como configurar o mesmo com mem\u00f3ria quente de volume. E outra pergunta. Como funciona o select com essa organiza\u00e7\u00e3o de dados? Ele ir\u00e1 ler todo o conjunto ou apenas o que est\u00e1 no disco, e esses dados s\u00e3o comprimidos na mem\u00f3ria? E como a se\u00e7\u00e3o prewhere funciona com essa organiza\u00e7\u00e3o de dados?<\/p><\/blockquote>\n<p>Essa configura\u00e7\u00e3o afeta o armazenamento de blocos de dados, e seu formato n\u00e3o muda.<br \/>\nVamos examinar isso com mais detalhes. <\/p>\n<p><\/p>\n<p>\u00c9 poss\u00edvel configurar o armazenamento de dados na RAM. Tudo que \u00e9 configurado para o disco \u2014 \u00e9 seu caminho. Voc\u00ea cria uma parti\u00e7\u00e3o tmpfs, que \u00e9 montada em algum caminho no sistema de arquivos. Indica esse caminho como o local de armazenamento dos dados da se\u00e7\u00e3o mais quente, onde os blocos de dados come\u00e7am a ser enviados e gravados, tudo funcionando bem. <\/p>\n<p><\/p>\n<p>Mas eu n\u00e3o recomendo fazer isso devido \u00e0 baixa confiabilidade, embora, se voc\u00ea tiver pelo menos tr\u00eas r\u00e9plicas em diferentes data centers, seja poss\u00edvel. Caso contr\u00e1rio, os dados ser\u00e3o recuperados. Imagine que o servidor foi desligado e ligado novamente. A parti\u00e7\u00e3o foi montada novamente, mas est\u00e1 vazia. O servidor ClickHouse, ao iniciar, percebe que essas partes est\u00e3o ausentes, embora, de acordo com os metadados do ZooKeeper, deveriam estar presentes. Ele verifica em quais r\u00e9plicas elas existem, solicita-as e as baixa. Assim, os dados ser\u00e3o restaurados. <\/p>\n<p><\/p>\n<p>Nesse sentido, o armazenamento de dados na mem\u00f3ria \u00e9 fundamentalmente n\u00e3o diferente do armazenamento em disco, porque, ao gravar dados em disco, eles tamb\u00e9m s\u00e3o inicialmente enviados para o cache de p\u00e1ginas e gravados fisicamente de forma ass\u00edncrona. Isso depende da variante de montagem do sistema de arquivos. Mas, por precau\u00e7\u00e3o, digo que o ClickHouse n\u00e3o executa fsync ao fazer um insert.<\/p>\n<p><\/p>\n<p>Os dados na mem\u00f3ria s\u00e3o armazenados exatamente no mesmo formato que em disco. A consulta select escolhe as partes que precisam ser lidas da mesma forma, selecionando os intervalos necess\u00e1rios de dados nas partes e os l\u00ea. E o prewhere funciona exatamente da mesma maneira, independentemente de os dados estarem na mem\u00f3ria ou no disco.<\/p>\n<p><\/p>\n<h2 id=\"anchorlow-cardinalityanchordo-kakogo-kolichestva-unikalnyh-znacheniy-effektiven-low-cardinality\"><noindex><a rel=\"nofollow\" name=\"low-cardinality\"><\/a><\/noindex>At\u00e9 quantos valores \u00fanicos o Low Cardinality \u00e9 eficaz?<\/h2>\n<p><\/p>\n<p>Low Cardinality \u00e9 inteligentemente projetado. Ele cria dicion\u00e1rios de dados, mas eles s\u00e3o locais. Em primeiro lugar, h\u00e1 dicion\u00e1rios pr\u00f3prios para cada parte, e, em segundo lugar, mesmo dentro de uma \u00fanica parte, eles podem ser diferentes para cada intervalo. Quando o n\u00famero de valores \u00fanicos atinge um n\u00famero cr\u00edtico \u2014 que eu acho ser um milh\u00e3o \u2014 o dicion\u00e1rio \u00e9 simplesmente delegado, e um novo \u00e9 criado.<\/p>\n<p><\/p>\n<p>A resposta geral: para cada intervalo local \u2014 digamos, para cada dia \u2014 com at\u00e9 um milh\u00e3o de valores \u00fanicos, o Low Cardinality \u00e9 eficaz. Ap\u00f3s isso, haver\u00e1 um fallback, onde muitos dicion\u00e1rios diferentes ser\u00e3o usados, em vez de um \u00fanico. Ele funcionar\u00e1 aproximadamente da mesma forma que uma coluna comum do tipo string, talvez com um pouco menos de efici\u00eancia, mas n\u00e3o haver\u00e1 uma degrada\u00e7\u00e3o significativa no desempenho. <\/p>\n<p><\/p>\n<h2 id=\"anchorfulltext-searchanchorkakie-luchshie-praktiki-ponbsppolnotekstovomu-poisku-ponbsptablice-snbsppyatyu-milliardami-strok\"><noindex><a rel=\"nofollow\" name=\"fulltext-search\"><\/a><\/noindex>Quais s\u00e3o as melhores pr\u00e1ticas para busca de texto completo em uma tabela com cinco bilh\u00f5es de linhas?<\/h2>\n<p><\/p>\n<p>Existem diferentes op\u00e7\u00f5es de resposta. A primeira \u00e9 dizer que o ClickHouse n\u00e3o \u00e9 um sistema para busca de texto completo. Para isso, existem sistemas especiais, por exemplo, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/enterprise-search\">Elasticsearch<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"http:\/\/sphinxsearch.com\/\">Sphinx<\/a><\/noindex>. No entanto, encontro cada vez mais pessoas dizendo que est\u00e3o migrando do Elasticsearch para o ClickHouse.<\/p>\n<p><\/p>\n<p>Por que isso acontece? Eles explicam que o Elasticsearch deixa de lidar com a carga em certos volumes, come\u00e7ando pela constru\u00e7\u00e3o de \u00edndices. Os \u00edndices tornam-se muito pesados e, se simplesmente transferirmos os dados para o ClickHouse, eles ser\u00e3o armazenados de forma muito mais eficiente em termos de volume. Al\u00e9m disso, as consultas de pesquisa muitas vezes n\u00e3o precisavam encontrar uma frase em todo o volume de dados, mas eram completamente diferentes. Por exemplo, encontrar, nas \u00faltimas horas, nos logs, alguma subsequ\u00eancia de bytes.<\/p>\n<p><\/p>\n<p>Nesse caso, voc\u00ea cria um \u00edndice no ClickHouse, onde o primeiro campo ser\u00e1 a data e hora. E o maior corte de dados ser\u00e1 exatamente pelo intervalo de datas. Dentro do intervalo de datas selecionado, muitas vezes \u00e9 poss\u00edvel realizar uma busca de texto completo, mesmo com o m\u00e9todo brute force usando like. O operador like no ClickHouse \u00e9 o operador like mais eficiente que voc\u00ea pode encontrar. Se voc\u00ea encontrar algo melhor, me avise. <\/p>\n<p><\/p>\n<p>Mas, ainda assim, like \u00e9 um full scan. E full scan pode ser lento n\u00e3o apenas por causa da CPU, mas tamb\u00e9m do disco. Se voc\u00ea tiver um terabyte de dados por dia e estiver procurando alguma palavra em um \u00fanico dia, ter\u00e1 que escanear um terabyte. E ele certamente estar\u00e1 em discos r\u00edgidos comuns, e, no final, eles estar\u00e3o t\u00e3o sobrecarregados que voc\u00ea n\u00e3o conseguir\u00e1 acessar esse servidor via SSH.<\/p>\n<p><\/p>\n<p>Nesse caso, estou disposto a oferecer mais um truque pequeno. Ele \u00e9 experimental \u2014 pode funcionar, mas pode n\u00e3o funcionar. O ClickHouse possui \u00edndices de texto completo na forma de filtros de Bloom trigramas. Nossos colegas da empresa Arenadata j\u00e1 testaram esses \u00edndices e, muitas vezes, eles funcionam exatamente como deveriam.<\/p>\n<p><\/p>\n<p>Para utiliz\u00e1-los corretamente, \u00e9 preciso entender bem como exatamente eles funcionam: o que \u00e9 um filtro de Bloom trigramas e como escolher seu tamanho. Posso dizer que eles ser\u00e3o \u00fateis para consultas sobre algumas frases raras, substrings que ocorrem com pouca frequ\u00eancia nos dados. Nesse caso, os \u00edndices selecionar\u00e3o subintervalos, e menos dados ser\u00e3o lidos.<\/p>\n<p><\/p>\n<p>Recentemente, o ClickHouse recebeu ainda mais funcionalidades avan\u00e7adas para busca de texto completo. Isso inclui, em primeiro lugar, a busca de v\u00e1rias substrings de uma s\u00f3 vez, incluindo op\u00e7\u00f5es que consideram a capitaliza\u00e7\u00e3o, sem considerar a capitaliza\u00e7\u00e3o, com suporte a UTF-8 ou apenas para ASCII. Escolha a mais eficiente que voc\u00ea precisa. <\/p>\n<p><\/p>\n<p>Agora tamb\u00e9m \u00e9 poss\u00edvel buscar v\u00e1rias express\u00f5es regulares de uma s\u00f3 vez. Voc\u00ea n\u00e3o precisa escrever X like uma substring ou X like outra substring. Basta escrever tudo de uma vez e tudo ser\u00e1 executado da forma mais eficiente poss\u00edvel.<\/p>\n<p><\/p>\n<p>O terceiro ponto \u00e9 que agora existe busca aproximada para express\u00f5es regulares e busca aproximada de substrings. Se algu\u00e9m escreveu uma palavra com erro de digita\u00e7\u00e3o, ela ser\u00e1 buscada com a melhor correspond\u00eancia poss\u00edvel.<\/p>\n<p><\/p>\n<h2 id=\"anchorhello-and-welcomeanchorkak-luchshe-organizovat-dostup-vnbspclickhouse-dlyanbspbolshogo-kolichestva-polzovateley\"><noindex><a rel=\"nofollow\" name=\"hello-and-welcome\"><\/a><\/noindex>Como organizar melhor o acesso ao ClickHouse para um grande n\u00famero de usu\u00e1rios?<\/h2>\n<p><\/p>\n<blockquote><p>Conte-nos como organizar melhor o acesso para um grande n\u00famero de consumidores e analistas. Como formar uma fila, priorizar as solicita\u00e7\u00f5es de max concurrent queries e quais ferramentas utilizar?<\/p><\/blockquote>\n<p>Se o cluster for grande o suficiente, uma boa solu\u00e7\u00e3o seria adicionar mais dois servidores que servir\u00e3o como ponto de entrada para os analistas. Ou seja, n\u00e3o permitindo que os analistas acessem shards espec\u00edficos do cluster, mas apenas criando dois servidores vazios, sem dados, e ent\u00e3o configurar os direitos de acesso neles. Nesse caso, as configura\u00e7\u00f5es de usu\u00e1rios em consultas distribu\u00eddas s\u00e3o passadas para servidores remotos. Isso significa que voc\u00ea configura tudo nesses dois servidores, e as configura\u00e7\u00f5es t\u00eam efeito em todo o cluster.<\/p>\n<p><\/p>\n<p>Esses servidores n\u00e3o possuem dados, mas a quantidade de RAM neles \u00e9 bastante importante para a execu\u00e7\u00e3o das consultas. O disco tamb\u00e9m pode ser usado para dados tempor\u00e1rios, se a agrega\u00e7\u00e3o externa ou ordena\u00e7\u00e3o externa estiver ativada.<\/p>\n<p><\/p>\n<p>\u00c9 importante olhar para as configura\u00e7\u00f5es relacionadas a todos os poss\u00edveis limites. Se eu agora acessar o cluster 'Yandex.Metrics' como analista e fizer uma solicita\u00e7\u00e3o <strong>select count from hits<\/strong>, eu imediatamente receberei uma exce\u00e7\u00e3o informando que n\u00e3o posso executar a consulta. O n\u00famero m\u00e1ximo de linhas que me \u00e9 permitido escanear \u00e9 cem bilh\u00f5es, enquanto no cluster h\u00e1 cinquenta trilh\u00f5es em uma \u00fanica tabela. Esta \u00e9 a primeira limita\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p>Supondo que eu remova a limita\u00e7\u00e3o do n\u00famero de linhas e execute a consulta novamente. Ent\u00e3o verei a seguinte exce\u00e7\u00e3o \u2014 a configura\u00e7\u00e3o est\u00e1 ativada. <strong>force index by date<\/strong>N\u00e3o posso executar a solicita\u00e7\u00e3o se eu n\u00e3o indicar o intervalo de datas. N\u00e3o se deve contar que os analistas ir\u00e3o inserir isso manualmente. Um caso t\u00edpico \u00e9 que o intervalo de datas \u00e9 escrito onde a data do evento est\u00e1 entre uma semana. E ent\u00e3o, em algum lugar, simplesmente colocaram o par\u00eantese errado, e em vez de 'e' acabou sendo 'ou' \u2014 ou a correspond\u00eancia da URL. Se n\u00e3o houver restri\u00e7\u00f5es, ele come\u00e7ar\u00e1 a escanear a coluna de URL e consumir\u00e1 muitos recursos.<\/p>\n<p><\/p>\n<p>Al\u00e9m disso, no ClickHouse, existem duas configura\u00e7\u00f5es de prioridade. Infelizmente, s\u00e3o muito primitivas. Uma delas \u00e9 chamada simplesmente <strong>priority<\/strong>. Se prioridade \u2260 0, e solicita\u00e7\u00f5es com alguma prioridade est\u00e3o sendo executadas, mas ao mesmo tempo \u00e9 executada uma solicita\u00e7\u00e3o com prioridade que tem um valor menor, o que significa uma prioridade mais alta, a solicita\u00e7\u00e3o com um valor de prioridade maior, que indica uma prioridade mais baixa, simplesmente ser\u00e1 suspensa e n\u00e3o funcionar\u00e1 durante esse tempo.<\/p>\n<p><\/p>\n<p>Essa \u00e9 uma configura\u00e7\u00e3o muito grosseira, e n\u00e3o \u00e9 adequada para casos em que h\u00e1 carga constante no cluster. Mas se voc\u00ea tiver solicita\u00e7\u00f5es curtas e importantes e a maior parte do tempo o cluster estiver ocioso, essa configura\u00e7\u00e3o ser\u00e1 adequada.<\/p>\n<p><\/p>\n<p>A pr\u00f3xima configura\u00e7\u00e3o de prioridades \u00e9 chamada de <strong>prioridade de thread do SO<\/strong>. Ela simplesmente define para todos os threads de execu\u00e7\u00e3o de solicita\u00e7\u00f5es o valor de 'nice' para o agendador Linux. Funciona relativamente bem, mas ainda assim funciona. Se definir o valor mais baixo de 'nice' \u2014 que \u00e9 o maior em magnitude, e significa a prioridade mais baixa \u2014 e para solicita\u00e7\u00f5es com alta prioridade definir -19, a CPU consumir\u00e1 solicita\u00e7\u00f5es de baixa prioridade cerca de quatro vezes menos do que as de alta prioridade. <\/p>\n<p><\/p>\n<p>Al\u00e9m disso, \u00e9 preciso configurar o tempo m\u00e1ximo de execu\u00e7\u00e3o da solicita\u00e7\u00e3o \u2014 digamos, cinco minutos. A velocidade m\u00ednima de execu\u00e7\u00e3o da solicita\u00e7\u00e3o \u2014 isso \u00e9 o mais importante. Essa configura\u00e7\u00e3o existe h\u00e1 muito tempo, e \u00e9 necess\u00e1ria para n\u00e3o apenas afirmar que o ClickHouse n\u00e3o desacelera, mas para for\u00e7ar isso.<\/p>\n<p><\/p>\n<p>Imagine, voc\u00ea est\u00e1 configurando: se alguma solicita\u00e7\u00e3o processa menos de um milh\u00e3o de linhas por segundo \u2014 isso n\u00e3o pode ser feito. Isso envergonha nosso bom nome, nosso bom banco de dados. Vamos simplesmente proibir isso. Na verdade, existem duas configura\u00e7\u00f5es. Uma delas \u00e9 chamada de <strong>velocidade m\u00ednima de execu\u00e7\u00e3o<\/strong> \u2014 em&nbsp;linhas por&nbsp;segundo, e a segunda \u00e9 chamada de tempo limite antes de verificar a velocidade m\u00ednima de execu\u00e7\u00e3o&nbsp;\u2014 por padr\u00e3o, quinze segundos. Ou seja, quinze segundos s\u00e3o poss\u00edveis, e depois, se estiver lento, simplesmente lan\u00e7ar uma exce\u00e7\u00e3o \u2014 interromper a solicita\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>Tamb\u00e9m \u00e9 necess\u00e1rio configurar as quotas. No&nbsp;ClickHouse, h\u00e1 uma funcionalidade embutida de quotas que contabiliza o consumo de recursos. Mas, infelizmente, n\u00e3o recursos f\u00edsicos como CPU, discos, mas sim l\u00f3gicos&nbsp;\u2014 o n\u00famero de solicita\u00e7\u00f5es processadas, linhas e bytes lidos. E pode-se configurar, por exemplo, um m\u00e1ximo de cem solicita\u00e7\u00f5es em&nbsp;cinco minutos e mil solicita\u00e7\u00f5es por&nbsp;hora.<\/p>\n<p><\/p>\n<p>Por que isso \u00e9 importante? Porque parte das solicita\u00e7\u00f5es de an\u00e1lise ser\u00e1 executada manualmente diretamente do&nbsp;cliente ClickHouse. E tudo estar\u00e1 bem. Mas se voc\u00ea tiver analistas avan\u00e7ados na&nbsp;empresa, eles v\u00e3o escrever um script, e no&nbsp;script pode haver um erro. E esse erro levar\u00e1 a que a solicita\u00e7\u00e3o seja executada em um&nbsp;ciclo infinito. \u00c9 disso que precisamos nos proteger.<\/p>\n<p><\/p>\n<h2 id=\"anchorsmorgasbordanchormozhno-li-otdat-rezultaty-odnogo-zaprosa-desyati-klientam\"><noindex><a rel=\"nofollow\" name=\"smorgasbord\"><\/a><\/noindex>\u00c9 poss\u00edvel devolver os resultados de uma consulta para dez clientes?<\/h2>\n<p><\/p>\n<blockquote><p>Temos alguns usu\u00e1rios que gostam de fazer solicita\u00e7\u00f5es muito grandes ao mesmo tempo. A solicita\u00e7\u00e3o \u00e9 grande, \u00e9, em princ\u00edpio, r\u00e1pida, mas devido \u00e0 quantidade de solicita\u00e7\u00f5es ao mesmo tempo, torna-se muito doloroso. \u00c9 poss\u00edvel executar a mesma solicita\u00e7\u00e3o que chegou dez vezes seguidas uma vez s\u00f3 e devolver o resultado a dez clientes?<\/p><\/blockquote>\n<p>O problema \u00e9 que n\u00e3o temos resultados em cache ou cache de dados intermedi\u00e1rios. Existe o cache de p\u00e1gina do sistema operacional, que permitir\u00e1 n\u00e3o ler os dados do disco novamente, mas, infelizmente, os dados ainda precisar\u00e3o ser descompactados, desserializados e processados novamente. <\/p>\n<p><\/p>\n<p>Gostar\u00edamos de evitar isso de alguma forma, seja armazenando dados intermedi\u00e1rios em cache, seja organizando solicita\u00e7\u00f5es semelhantes em uma fila e adicionando um cache de resultados. Atualmente, temos um pull request em desenvolvimento que adiciona cache de solicita\u00e7\u00f5es, mas apenas para subconsultas nas se\u00e7\u00f5es in e join&nbsp;\u2014 ou seja, a solu\u00e7\u00e3o n\u00e3o \u00e9 completa.<\/p>\n<p><\/p>\n<p>No entanto, tamb\u00e9m temos essa situa\u00e7\u00e3o. Um exemplo can\u00f4nico \u00e9 o de requisi\u00e7\u00f5es com pagina\u00e7\u00e3o. H\u00e1 um relat\u00f3rio com v\u00e1rias p\u00e1ginas, e a requisi\u00e7\u00e3o \u00e9 limit 10. Depois, o mesmo, mas limit 10,10. Em seguida, passa para a pr\u00f3xima p\u00e1gina. E a pergunta \u00e9: por que contamos tudo isso toda vez? Mas atualmente n\u00e3o h\u00e1 solu\u00e7\u00e3o, e n\u00e3o \u00e9 poss\u00edvel evitar isso.<\/p>\n<p><\/p>\n<p>H\u00e1 uma solu\u00e7\u00e3o alternativa que \u00e9 instalada como um sidecar ao lado do ClickHouse \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Vertamedia\/chproxy\">ClickHouse Proxy<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> No ClickHouse Proxy, existe um limitador de taxa embutido e um cache de resultados integrado. Muitas configura\u00e7\u00f5es foram feitas, pois um problema semelhante estava sendo resolvido. O Proxy permite limitar requisi\u00e7\u00f5es, organizando-as em uma fila, e configurar quanto tempo o cache das requisi\u00e7\u00f5es permanece. Se as requisi\u00e7\u00f5es forem realmente id\u00eanticas, o Proxy as entregar\u00e1 v\u00e1rias vezes, mas far\u00e1 a chamada ao ClickHouse apenas uma vez.<\/p>\n<p><\/p>\n<p>O Nginx tamb\u00e9m tem cache na vers\u00e3o gratuita, e isso tamb\u00e9m funcionar\u00e1. O Nginx at\u00e9 possui configura\u00e7\u00f5es que, se as requisi\u00e7\u00f5es chegarem ao mesmo tempo, ele atrasar\u00e1 as outras at\u00e9 que uma seja conclu\u00edda. Mas, especificamente no ClickHouse Proxy, a configura\u00e7\u00e3o \u00e9 feita de forma muito melhor. Ele foi projetado especificamente para o ClickHouse, para essas requisi\u00e7\u00f5es, ent\u00e3o se adapta melhor. E \u00e9 f\u00e1cil de instalar. <\/p>\n<p><\/p>\n<h2 id=\"anchorasynchronousanchorkak-byt-snbspasinhronnymi-operaciyami-i-materializovannymi-predstavleniyami\"><noindex><a rel=\"nofollow\" name=\"asynchronous\"><\/a><\/noindex>Como lidar com opera\u00e7\u00f5es ass\u00edncronas e vis\u00f5es materializadas?<\/h2>\n<p><\/p>\n<blockquote><p>H\u00e1 um problema em que as opera\u00e7\u00f5es com o motor de replay s\u00e3o ass\u00edncronas \u2014 primeiro os dados s\u00e3o gravados, depois ocorre a condensa\u00e7\u00e3o. Se houver uma tabela materializada sob a tabela principal com alguns agregados, duplicatas ser\u00e3o registradas nela. E se n\u00e3o houver uma l\u00f3gica complexa, os dados ser\u00e3o duplicados. O que pode ser feito a respeito?<\/p>\n<p>H\u00e1 uma solu\u00e7\u00e3o \u00f3bvia \u2014 implementar um gatilho em uma determinada classe de views materiais durante a opera\u00e7\u00e3o ass\u00edncrona de condensa\u00e7\u00e3o. Existem \"balas de prata\" ou planos para implementar funcionalidades semelhantes?<\/p><\/blockquote>\n<p>\u00c9 importante entender como funciona a deduplica\u00e7\u00e3o. O que vou explicar agora n\u00e3o est\u00e1 relacionado \u00e0 pergunta, mas \u00e9 bom lembrar disso, por precau\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>Ao inserir em uma tabela replicada, h\u00e1 a deduplica\u00e7\u00e3o de blocos inteiros inseridos. Se voc\u00ea reinserir o mesmo bloco, contendo o mesmo n\u00famero de linhas na mesma ordem, os dados ser\u00e3o deduplicados. Voc\u00ea receber\u00e1 \u201cOk\u201d como resposta ao insert, mas na verdade apenas um conjunto de dados ser\u00e1 gravado, e ele n\u00e3o ser\u00e1 duplicado.<\/p>\n<p><\/p>\n<p>Isso \u00e9 necess\u00e1rio para defini\u00e7\u00e3o. Se durante a inser\u00e7\u00e3o voc\u00ea recebeu \u201cOk\u201d, significa que seus dados foram inseridos. Se voc\u00ea recebeu um erro do ClickHouse, significa que eles n\u00e3o foram inseridos, e a inser\u00e7\u00e3o deve ser repetida. Mas se a conex\u00e3o foi interrompida durante a inser\u00e7\u00e3o, ent\u00e3o voc\u00ea n\u00e3o sabe se os dados foram inseridos ou n\u00e3o. A \u00fanica op\u00e7\u00e3o \u00e9 repetir a inser\u00e7\u00e3o novamente. Se os dados foram realmente inseridos, e voc\u00ea os inseriu novamente, h\u00e1 deduplica\u00e7\u00e3o de blocos. Isso \u00e9 necess\u00e1rio para evitar duplicatas. <\/p>\n<p><\/p>\n<p>E \u00e9 importante tamb\u00e9m como isso funciona para visualiza\u00e7\u00f5es materializadas. Se os dados foram deduplicados ao serem inseridos na tabela principal, eles tamb\u00e9m n\u00e3o ir\u00e3o para a visualiza\u00e7\u00e3o materializada.<\/p>\n<p><\/p>\n<p>Agora sobre a quest\u00e3o. Voc\u00ea tem uma situa\u00e7\u00e3o mais complexa, porque est\u00e1 registrando duplicatas de linhas individuais. Ou seja, n\u00e3o um lote inteiro duplicado, mas especificamente linhas concretas que se acumulam em background. De fato, os dados ser\u00e3o acumulados na tabela principal, enquanto na visualiza\u00e7\u00e3o materializada ir\u00e3o as linhas n\u00e3o acumuladas, e durante os merges nada acontecer\u00e1 com as visualiza\u00e7\u00f5es materializadas. Porque a visualiza\u00e7\u00e3o materializada \u00e9 nada mais do que um gatilho para inserts. Nas outras opera\u00e7\u00f5es, nada adicional acontece com ela.<\/p>\n<p><\/p>\n<p>E aqui eu n\u00e3o posso trazer boas not\u00edcias. \u00c9 necess\u00e1rio apenas buscar uma solu\u00e7\u00e3o espec\u00edfica para este caso. Por exemplo, se tamb\u00e9m \u00e9 poss\u00edvel fazer o substituto na visualiza\u00e7\u00e3o materializada, e talvez o m\u00e9todo de deduplica\u00e7\u00e3o funcione da mesma forma. Mas, infelizmente, nem sempre. Se for agregadora, n\u00e3o ser\u00e1 poss\u00edvel. <\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Nosso sistema de contabilidade tamb\u00e9m era bem complicado na \u00e9poca. Havia um problema com a exibi\u00e7\u00e3o de an\u00fancios e havia alguns dados que pod\u00edamos mostrar em tempo real \u2014 eram apenas as exibi\u00e7\u00f5es. Elas raramente se duplicam, mas, se isso acontecer, ainda assim n\u00f3s as consolidamos depois. E havia informa\u00e7\u00f5es que n\u00e3o podiam ser duplicadas \u2014 cliques e toda essa hist\u00f3ria. Mas quer\u00edamos exibi-las praticamente imediatament.<\/p>\n<p><\/p>\n<p>Como foram feitas as visualiza\u00e7\u00f5es materializadas? Havia visualiza\u00e7\u00f5es que eram preenchidas diretamente \u2014 os dados crus eram gravados nas visualiza\u00e7\u00f5es. Em determinado momento, os dados n\u00e3o estavam muito corretos, se duplicavam e assim por diante. E havia uma segunda parte da tabela, onde apareciam exatamente da mesma forma que as visualiza\u00e7\u00f5es materializadas, ou seja, estruturalmente eram id\u00eanticas. Periodicamente, recalculamos os dados, completamos os dados sem duplicatas e escrevemos nessas tabelas. <\/p>\n<p><\/p>\n<p>N\u00f3s utilizamos a API \u2014 manualmente, isso n\u00e3o funcionaria no ClickHouse. E a API verifica: quando tenho uma data de \u00faltima adi\u00e7\u00e3o na tabela, onde os dados j\u00e1 s\u00e3o garantidamente corretos e calculados, e ela faz uma consulta a uma tabela e \u00e0 outra. De uma tabela, ela seleciona at\u00e9 um determinado ponto no tempo, e da outra tabela, ela adiciona o que ainda n\u00e3o foi calculado. Isso funciona, mas n\u00e3o com os recursos de um \u00fanico ClickHouse.<\/p>\n<p><\/p>\n<p>Se voc\u00ea tem uma API \u2014 para analistas, para usu\u00e1rios \u2014 isso \u00e9 uma op\u00e7\u00e3o. Voc\u00ea sempre completa, sempre recalcula. Isso pode ser feito uma vez ao dia ou em outro intervalo de tempo. Voc\u00ea mesmo escolhe o intervalo que n\u00e3o \u00e9 necess\u00e1rio e n\u00e3o cr\u00edtico.<\/p>\n<p><\/p>\n<h2 id=\"anchordashboardanchorv-clickhouse-mnogo-logov-kak-ya-mogu-videt-vsyo-chto-proishodit-s-serverom-vnbspmomente\"><noindex><a rel=\"nofollow\" name=\"dashboard\"><\/a><\/noindex>No ClickHouse, h\u00e1 muitos logs. Como posso ver tudo o que est\u00e1 acontecendo com o servidor no momento?<\/h2>\n<p><\/p>\n<blockquote><p>No ClickHouse, h\u00e1 um grande n\u00famero de logs diferentes, e essa quantidade est\u00e1 crescendo. Em novas vers\u00f5es, alguns deles v\u00eam ativados por padr\u00e3o, enquanto nas vers\u00f5es anteriores, voc\u00ea precisa ativ\u00e1-los durante a atualiza\u00e7\u00e3o. No entanto, eles est\u00e3o se tornando cada vez mais numerosos. Eu gostaria de ver, no final das contas, o que est\u00e1 acontecendo atualmente com o meu servidor, talvez em algum painel de controle consolidado. <\/p>\n<p>Voc\u00ea tem alguma equipe de ClickHouse, ou equipes de seus amigos, que suporte alguma funcionalidade de dashboards pronto, que mostre esses logs na forma de um produto acabado? No final das contas, ver logs apenas no ClickHouse \u00e9 \u00f3timo. Mas seria incr\u00edvel se isso j\u00e1 estivesse preparado na forma de um dashboard. Eu ficaria muito satisfeito com isso. <\/p><\/blockquote>\n<p>Existem dashboards, embora n\u00e3o sejam padronizados. Em nossa empresa, cerca de 60 equipes usam ClickHouse, e o mais estranho \u00e9 que muitas delas t\u00eam dashboards que elas mesmas criaram, e s\u00e3o um pouco diferentes. Algumas equipes utilizam a instala\u00e7\u00e3o interna da 'Yandex.Cloud'. H\u00e1 alguns relat\u00f3rios prontos l\u00e1, embora n\u00e3o todos os necess\u00e1rios. Outras t\u00eam os seus pr\u00f3prios. <\/p>\n<p><\/p>\n<p>Meus colegas do 'Metrics' t\u00eam seu pr\u00f3prio dashboard no Grafana, e eu tenho o meu pelo mesmo cluster deles. Eu olho para m\u00e9tricas como hits no cache para as marca\u00e7\u00f5es. E ainda mais complicado \u00e9 que usamos ferramentas diferentes. Meu dashboard eu criei com uma ferramenta muito antiga chamada Graphite-web. Ele \u00e9 completamente feio. E eu ainda o uso, embora o Grafana provavelmente seria mais conveniente e bonito. <\/p>\n<p><\/p>\n<p>A coisa b\u00e1sica nos dashboards \u00e9 a mesma. S\u00e3o m\u00e9tricas sist\u00eamicas do cluster: CPU, mem\u00f3ria, disco, rede. Outras incluem o n\u00famero de requisi\u00e7\u00f5es simult\u00e2neas, o n\u00famero de mesclagens simult\u00e2neas, o n\u00famero de requisi\u00e7\u00f5es por segundo, a quantidade m\u00e1xima de pe\u00e7as para parti\u00e7\u00f5es de tabelas MergeTree, o lag de replica\u00e7\u00e3o, o tamanho da fila de replica\u00e7\u00e3o, o n\u00famero de linhas inseridas por segundo, o n\u00famero de blocos inseridos por segundo. Isso tudo \u00e9 obtido n\u00e3o dos logs, mas das m\u00e9tricas.<\/p>\n<p><\/p>\n<p><strong>Vladimir Kolobaev:<\/strong> Alexey, eu gostaria de fazer uma pequena corre\u00e7\u00e3o. Existe o Grafana. O Grafana possui uma fonte de dados que \u00e9 o ClickHouse. Ou seja, posso fazer consultas no ClickHouse diretamente do Grafana. No ClickHouse h\u00e1 uma tabela com logs que todos t\u00eam igual. Eu quero que, no resultado, eu acesse essa tabela de logs pelo Grafana e veja as requisi\u00e7\u00f5es que meu servidor faz. Seria \u00f3timo ter um dashboard assim.<\/p>\n<p><\/p>\n<p>Eu mesmo fiz isso. Mas tenho uma pergunta - se tudo \u00e9 padronizado, e o Grafana \u00e9 usado por todos, por que no 'Yandex' n\u00e3o h\u00e1 um dashboard oficial assim?<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Na verdade, o datasource que se conecta ao ClickHouse \u00e9 atualmente suportado pela Altinity. E eu s\u00f3 quero indicar para onde cavar e quem empurrar. Voc\u00ea pode perguntar a eles, porque o \"Yandex\" na verdade faz o ClickHouse, e n\u00e3o a hist\u00f3ria ao seu redor. A Altinity \u00e9 a principal empresa que atualmente promove o ClickHouse. Eles n\u00e3o v\u00e3o abandon\u00e1-lo, mas continuar\u00e3o a suport\u00e1-lo. Porque, em princ\u00edpio, para carregar o dashboard no site do Grafana, voc\u00ea s\u00f3 precisa se registrar e envi\u00e1-lo \u2014 n\u00e3o h\u00e1 muitos problemas. <\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> No \u00faltimo ano, muitas funcionalidades de profiling de consultas foram adicionadas ao ClickHouse. Existem m\u00e9tricas para cada consulta quanto ao uso de recursos. E recentemente foi adicionado um profiler de consultas de n\u00edvel ainda mais baixo, para ver onde cada consulta gasta cada milissegundo. Mas para usar essa funcionalidade, eu preciso abrir o cliente de console e digitar a consulta que sempre esque\u00e7o. Eu a salvei em algum lugar e sempre esque\u00e7o onde exatamente. <\/p>\n<p><\/p>\n<p>Eu gostaria que houvesse uma ferramenta onde estivesse simplesmente escrito \u2014 aqui est\u00e3o suas consultas pesadas, agrupadas por classes de consulta. Eu clico em alguma e me dizem que ela \u00e9 pesada por isso. Atualmente n\u00e3o h\u00e1 tal solu\u00e7\u00e3o. E \u00e9 realmente bastante estranho que, quando as pessoas me perguntam: \"Diga, existem dashboards prontos para o Grafana?\", eu digo: \"V\u00e1 ao site do Grafana, l\u00e1 tem a comunidade de 'Dashboards', e l\u00e1 tem um dashboard do Dima, tem um dashboard do Kostya. O que isso \u00e9, eu n\u00e3o sei, eu mesmo n\u00e3o usei.\"<\/p>\n<p><\/p>\n<h2 id=\"anchorzenanchorkak-vozdeystvovat-na-merdzhi-chtoby-server-ne-padal-vnbspoom\"><noindex><a rel=\"nofollow\" name=\"zen\"><\/a><\/noindex>Como influenciar nos merges, para que o servidor n\u00e3o caia em OOM?<\/h2>\n<p><\/p>\n<blockquote><p>Eu tenho uma tabela, que tem apenas uma parti\u00e7\u00e3o, \u00e9 um ReplacingMergeTree. Estou escrevendo dados nela h\u00e1 quatro anos. Eu precisava fazer um alter nela e deletar alguns dados.<\/p>\n<p>Eu fiz isso, e durante o processamento dessa consulta, toda a mem\u00f3ria em todos os servidores do cluster foi consumida, e todos os servidores do cluster ca\u00edram em OOM juntos. Depois, todos eles se reergueram, come\u00e7aram a realizar o merge dessa mesma opera\u00e7\u00e3o, desse bloco de dados, e ca\u00edram novamente em OOM. Ent\u00e3o eles se levantaram de novo e ca\u00edram novamente. E essa situa\u00e7\u00e3o n\u00e3o parou.<\/p>\n<p>Depois, descobri que na verdade era um bug que a equipe corrigiu. Isso \u00e9 muito bom, muito obrigado. Mas a sensa\u00e7\u00e3o ruim ainda permanece. E agora, quando penso em fazer algum merge na tabela, surge a pergunta \u2014 por que n\u00e3o posso de alguma forma controlar esses merges? Por exemplo, limit\u00e1-los em termos de quantidade de mem\u00f3ria RAM necess\u00e1ria, ou mesmo pela quantidade total que ser\u00e1 processada nessa tabela.<\/p>\n<p>Eu tenho uma tabela chamada \"M\u00e9tricas\", por favor, processe-a em dois threads. N\u00e3o crie dez ou cinco merges em paralelo, fa\u00e7a em dois. Eu acho que em dois eu tenho mem\u00f3ria suficiente, enquanto para processar dez pode n\u00e3o ser o suficiente. Por que o medo persiste? Porque a tabela est\u00e1 crescendo, e em algum momento eu vou me deparar com uma situa\u00e7\u00e3o em que, fundamentalmente, n\u00e3o ser\u00e1 por causa de um bug, mas porque os dados mudar\u00e3o em um volume t\u00e3o grande que simplesmente n\u00e3o terei mem\u00f3ria suficiente no servidor. E ent\u00e3o o servidor vai cair em OOM durante o merge. E eu posso cancelar a muta\u00e7\u00e3o, mas os merges n\u00e3o.<\/p><\/blockquote>\n<p>Voc\u00ea sabe, durante os merges o servidor n\u00e3o vai cair em OOM, porque no merge \u00e9 utilizado apenas uma quantidade de RAM para um pequeno intervalo de dados. Ent\u00e3o tudo ficar\u00e1 bem, independentemente do volume de dados.<\/p>\n<p><\/p>\n<p><strong>Vladimir Kolobaev:<\/strong> Certo. Tem um detalhe, que depois que fiz a corre\u00e7\u00e3o do bug, eu baixei a nova vers\u00e3o, e em outra tabela, menor, onde h\u00e1 muitas parti\u00e7\u00f5es, fiz uma opera\u00e7\u00e3o semelhante. E durante o merge no servidor foram consumidos cerca de 100 GB de mem\u00f3ria RAM. Eu tinha 150 ocupados, 100 foram consumidos, e sobrou espa\u00e7o para 50 GB, portanto, n\u00e3o ca\u00ed em OOM.<\/p>\n<p><\/p>\n<p>O que me protege nesse momento de cair em OOM se realmente est\u00e1 consumindo cerca de 100 GB de mem\u00f3ria RAM? Como lidar com a situa\u00e7\u00e3o se, de repente, a mem\u00f3ria RAM acabar nos merges?<\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> H\u00e1 um problema em que o uso de mem\u00f3ria RAM n\u00e3o se limita apenas \u00e0s merges. E o segundo problema \u00e9 que, se alguma merge foi programada, ela precisa ser executada, pois est\u00e1 registrada no log de replica\u00e7\u00e3o. O log de replica\u00e7\u00e3o envolve as a\u00e7\u00f5es necess\u00e1rias para trazer a r\u00e9plica a um estado consistente. Se n\u00e3o forem realizadas as manipula\u00e7\u00f5es manuais que reverter\u00e3o esse log de replica\u00e7\u00e3o, a merge ter\u00e1 que ser feita, de uma forma ou de outra.<\/p>\n<p><\/p>\n<p>Claro que n\u00e3o seria demais ter uma limita\u00e7\u00e3o de RAM que \"por precau\u00e7\u00e3o\" protegesse especificamente contra OOM. Isso n\u00e3o ajudar\u00e1 a merge a ser executada, ela come\u00e7ar\u00e1 novamente, chegar\u00e1 a algum limite, lan\u00e7ar\u00e1 uma exce\u00e7\u00e3o e ent\u00e3o come\u00e7ar\u00e1 de novo \u2014 nada bom sair\u00e1 disso. Mas, em princ\u00edpio, seria \u00fatil implementar essa limita\u00e7\u00e3o.<\/p>\n<p><\/p>\n<h2 id=\"anchorgoanchorkak-budet-proishodit-razrabotka-golang-drayvera-dlya-clickhouse\"><noindex><a rel=\"nofollow\" name=\"go\"><\/a><\/noindex>Como ser\u00e1 o desenvolvimento do driver Golang para ClickHouse?<\/h2>\n<p><\/p>\n<blockquote><p>O driver Golang, que foi escrito por Kirill Shvakov, agora est\u00e1 oficialmente, aparentemente, sendo suportado pela equipe do ClickHouse. Ele <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/clickhouse-go\">est\u00e1 no reposit\u00f3rio ClickHouse<\/a><\/noindex>, ele agora \u00e9 grande e verdadeiro.<\/p>\n<p>Uma pequena observa\u00e7\u00e3o. H\u00e1 um maravilhoso e adorado armazenamento de formas normais de ordem infinita \u2014 \u00e9 o Vertica. Eles tamb\u00e9m t\u00eam seu pr\u00f3prio driver oficial para Python, que \u00e9 mantido pelos desenvolvedores do Vertica. E v\u00e1rias vezes aconteceu que as vers\u00f5es do armazenamento e do driver se desincronizavam bastante, resultando na interrup\u00e7\u00e3o do funcionamento do driver. E a segunda quest\u00e3o. A manuten\u00e7\u00e3o desse driver oficial, me parece, \u00e9 feita atrav\u00e9s do sistema de \"nipples\" \u2014 voc\u00ea escreve um issue e isso fica pendente para sempre.<\/p>\n<p>Eu tenho duas perguntas. Atualmente, o driver Golang do Kirill \u00e9 quase o m\u00e9todo padr\u00e3o para comunicar entre Golang e ClickHouse. A n\u00e3o ser que algu\u00e9m ainda use a interface http, porque prefere assim. Como ser\u00e1 o desenvolvimento desse driver? Ele ir\u00e1 se sincronizar com algumas mudan\u00e7as dr\u00e1sticas no pr\u00f3prio armazenamento? E qual \u00e9 o procedimento para revis\u00e3o de issues? <\/p><\/blockquote>\n<p><strong>Kirill Shvakov:<\/strong> Primeiro \u2014 como tudo \u00e9 organizado burocraticamente. Esse ponto n\u00e3o foi discutido, ent\u00e3o n\u00e3o tenho nada a responder.<\/p>\n<p><\/p>\n<p>Para responder \u00e0 pergunta sobre a quest\u00e3o, \u00e9 necess\u00e1ria uma pequena hist\u00f3ria do driver. Eu trabalhei em uma empresa que lidava com muitos dados. Era uma plataforma publicit\u00e1ria com um enorme n\u00famero de eventos que precisavam ser armazenados. E em algum momento, apareceu o ClickHouse. N\u00f3s enviamos os dados para l\u00e1, e no come\u00e7o tudo estava bem, mas depois o ClickHouse falhou. Naquele momento, decidimos que n\u00e3o precis\u00e1vamos mais dele. <\/p>\n<p><\/p>\n<p>Um ano depois, retornamos \u00e0 ideia de usar o ClickHouse, e precis\u00e1vamos de uma forma de escrever dados l\u00e1. A condi\u00e7\u00e3o era a seguinte \u2014 o hardware era muito fraco, os recursos eram limitados. Mas sempre trabalhamos assim, e por isso olhamos na dire\u00e7\u00e3o do protocolo nativo.<\/p>\n<p><\/p>\n<p>Como n\u00f3s trabalh\u00e1vamos em Go, estava claro que precis\u00e1vamos de um driver em Go. Eu trabalhei nele praticamente em tempo integral \u2014 essa era a minha tarefa de trabalho. At\u00e9 certo ponto, conseguimos desenvolv\u00ea-lo, e, em princ\u00edpio, ningu\u00e9m imaginava que algu\u00e9m al\u00e9m de n\u00f3s o usaria. Depois, a CloudFlare chegou com exatamente o mesmo problema, e por algum tempo trabalhamos com eles de maneira muito constante, porque eles tinham as mesmas demandas. E fizemos isso tanto no ClickHouse em si, quanto no driver. <\/p>\n<p><\/p>\n<p>Em algum momento, eu simplesmente parei de trabalhar com isso, porque minha atividade em rela\u00e7\u00e3o ao ClickHouse e meu trabalho mudaram um pouco. Por isso, os problemas n\u00e3o s\u00e3o resolvidos. De vez em quando, pessoas que precisam de algo fazem commits no reposit\u00f3rio. Ent\u00e3o, eu olho o pull request e \u00e0s vezes at\u00e9 fa\u00e7o corre\u00e7\u00f5es, mas isso acontece raramente.<\/p>\n<p><\/p>\n<p>Quero voltar ao driver. Alguns anos atr\u00e1s, quando tudo isso come\u00e7ou, o ClickHouse era diferente e tinha outras capacidades. Agora, h\u00e1 uma compreens\u00e3o de como reformular o driver para que funcione bem. Se isso acontecer, a vers\u00e3o 2 ser\u00e1 de qualquer maneira incompat\u00edvel devido \u00e0s solu\u00e7\u00f5es improvisadas acumuladas. <\/p>\n<p><\/p>\n<p>N\u00e3o sei como organizar isso. Eu mesmo n\u00e3o tenho muito tempo. Se algumas pessoas puderem trabalhar no desenvolvimento do driver, poderei ajud\u00e1-las e explicar o que fazer. Mas a participa\u00e7\u00e3o ativa da \"Yandex\" no desenvolvimento do projeto ainda n\u00e3o foi discutida. <\/p>\n<p><\/p>\n<p><strong>Alexey Milovidov:<\/strong> Na verdade, ainda n\u00e3o h\u00e1 burocracia em rela\u00e7\u00e3o a esses drivers. A \u00fanica coisa \u00e9 que foram transferidos para uma organiza\u00e7\u00e3o oficial, ou seja, esse driver \u00e9 reconhecido como a solu\u00e7\u00e3o oficial por padr\u00e3o para Go. Existem outros drivers, mas eles s\u00e3o tratados separadamente. <\/p>\n<p><\/p>\n<p>N\u00e3o temos nenhum desenvolvimento interno para esses drivers. A quest\u00e3o \u00e9 se conseguimos contratar uma pessoa espec\u00edfica, n\u00e3o para este driver em particular, mas para o desenvolvimento de todos os drivers da comunidade, ou se conseguiremos encontrar algu\u00e9m de fora. <\/p>\n<p><\/p>\n<h2 id=\"anchorlazy-loadanchorvneshniy-slovar-ne-podnimaetsya-posle-perezagruzki-snbspvklyuchennoy-nastroykoy-lazy_load-chto-delat\"><noindex><a rel=\"nofollow\" name=\"lazy-load\"><\/a><\/noindex>O dicion\u00e1rio externo n\u00e3o est\u00e1 sendo carregado ap\u00f3s a reinicializa\u00e7\u00e3o com a configura\u00e7\u00e3o lazy_load ativada. O que fazer?<\/h2>\n<p><\/p>\n<blockquote><p>Temos a configura\u00e7\u00e3o lazy_load ativada, e ap\u00f3s a reinicializa\u00e7\u00e3o do servidor, o dicion\u00e1rio n\u00e3o \u00e9 carregado automaticamente. Ele s\u00f3 \u00e9 carregado quando o usu\u00e1rio acessa esse dicion\u00e1rio. E na primeira tentativa, gera um erro. Existe alguma forma de carregar dicion\u00e1rios automaticamente com os recursos do ClickHouse, ou precisamos sempre controlar sua prontid\u00e3o para que os usu\u00e1rios n\u00e3o recebam erros?<\/p>\n<p>Talvez tenhamos uma vers\u00e3o antiga do ClickHouse, por isso o dicion\u00e1rio n\u00e3o foi carregado automaticamente. Isso pode ser verdade?<\/p><\/blockquote>\n<p>Em primeiro lugar, os dicion\u00e1rios podem ser carregados for\u00e7adamente com a ajuda de uma consulta. <strong>system reload dictionaries<\/strong>. Em segundo lugar, sobre o erro \u2014 se o dicion\u00e1rio j\u00e1 estiver carregado, as solicita\u00e7\u00f5es funcionar\u00e3o com os dados que foram carregados. Se o dicion\u00e1rio ainda n\u00e3o tiver sido carregado, ele ser\u00e1 carregado durante a solicita\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>Para dicion\u00e1rios grandes, isso n\u00e3o \u00e9 muito conveniente. Por exemplo, \u00e9 necess\u00e1rio puxar um milh\u00e3o de linhas do MySQL. Algu\u00e9m faz um simples select, mas esse select vai esperar aquelas milh\u00f5es de linhas. Aqui existem duas solu\u00e7\u00f5es. A primeira \u2014 desativar o lazy_load. A segunda \u2014 quando o servidor \u00e9 iniciado, antes de colocar carga nele, fazer <strong>system reload dictionary<\/strong> ou simplesmente executar a consulta que utiliza o dicion\u00e1rio. Assim, o dicion\u00e1rio ser\u00e1 carregado. \u00c9 necess\u00e1rio controlar a disponibilidade dos dicion\u00e1rios com a configura\u00e7\u00e3o lazy_load ativada, pois o ClickHouse n\u00e3o os puxa automaticamente.<\/p>\n<p><\/p>\n<p>A resposta para a \u00faltima pergunta \u00e9 \u2014 ou a vers\u00e3o \u00e9 antiga, ou \u00e9 necess\u00e1rio depurar. <\/p>\n<p><\/p>\n<h2 id=\"anchorreload-dictionariesanchorkak-byt-snbsptem-chto-system-reload-dictionaries-ne-podgruzhaet-ni-odin-iznbspmnozhestva-slovarey-esli-hotya-by-odin-iznbspnih-padaet-snbsposhibkoy\"><noindex><a rel=\"nofollow\" name=\"reload-dictionaries\"><\/a><\/noindex>Como lidar com o fato de que system reload dictionaries n\u00e3o carrega nenhum dos v\u00e1rios dicion\u00e1rios, se pelo menos um deles falhar com erro?<\/h2>\n<p><\/p>\n<blockquote><p>H\u00e1 mais uma quest\u00e3o sobre o reload system dictionaries. Temos dois dicion\u00e1rios \u2014 um n\u00e3o carrega, o outro carrega. O comando system reload dictionaries, nesse caso, n\u00e3o carrega nenhum dicion\u00e1rio, e \u00e9 necess\u00e1rio carregar um espec\u00edfico pela sua nomea\u00e7\u00e3o usando system reload dictionary. Isso tamb\u00e9m est\u00e1 relacionado \u00e0 vers\u00e3o do ClickHouse?<\/p><\/blockquote>\n<p>Quero tranquiliz\u00e1-lo. Esse comportamento mudou. Portanto, se voc\u00ea atualizar o ClickHouse, isso tamb\u00e9m mudar\u00e1. Se voc\u00ea n\u00e3o est\u00e1 satisfeito com o comportamento atual <strong>system reload dictionaries<\/strong>, atualize-se e vamos esperar que isso mude para melhor.<\/p>\n<p><\/p>\n<h2 id=\"anchorconnectionanchorest-li-sposob-konfigurirovat-rekvizity-vnbspkonfige-clickhouse-no-ne-svetit-ih-prinbsposhibkah\"><noindex><a rel=\"nofollow\" name=\"connection\"><\/a><\/noindex>H\u00e1 alguma maneira de configurar as credenciais no&nbsp;config do ClickHouse sem exp\u00f4-las em&nbsp;erros?<\/h2>\n<p><\/p>\n<blockquote><p>A pr\u00f3xima pergunta \u00e9 sobre erros relacionados ao dicion\u00e1rio, especificamente sobre as credenciais. N\u00f3s escrevemos as credenciais de conex\u00e3o na configura\u00e7\u00e3o do ClickHouse para o dicion\u00e1rio, e em caso de erro recebemos essas credenciais e a senha na resposta. <\/p>\n<p>Resolvemos esse erro movendo as credenciais para a configura\u00e7\u00e3o do driver ODBC. Existe alguma maneira de configurar as credenciais na configura\u00e7\u00e3o do ClickHouse, mas sem expor essas credenciais em caso de erros?<\/p><\/blockquote>\n<p>Aqui a solu\u00e7\u00e3o realmente \u00e9 \u2014 indicar essas credentials no odbc.ini, e no pr\u00f3prio ClickHouse indicar apenas o ODBC Data Source Name. Para outras fontes de dicion\u00e1rios isso n\u00e3o ocorrer\u00e1 \u2014 nem para o dicion\u00e1rio com MySQL, nem para os outros voc\u00ea deve ver a senha ao receber uma mensagem de erro. Para ODBC eu tamb\u00e9m vou verificar \u2014 se isso existe, \u00e9 necess\u00e1rio apenas remov\u00ea-lo.<\/p>\n<p><\/p>\n<h2 id=\"anchorzoom-backgroundsanchorbonus-fony-dlya-zuma-snbspposidelok\"><noindex><a rel=\"nofollow\" name=\"zoom-backgrounds\"><\/a><\/noindex>B\u00f4nus: fundos para Zoom \u00e0&nbsp;partidas<\/h2>\n<p><\/p>\n<p>Ao clicar na&nbsp;imagem, os leitores mais persistentes ter\u00e3o acesso a fundos b\u00f4nus de&nbsp;reuni\u00f5es. Apagamos o fogo juntos com&nbsp;os mascotes da tecnologia do Avito, nos reunimos com&nbsp;os colegas da sala do administrador de sistema ou do antigo clube de computadores e realizamos o daily debaixo da&nbsp;ponte em&nbsp;frente a grafites.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/amp.gs\/KvUr\"><img decoding=\"async\" alt=\"ClickHouse para usu\u00e1rios avan\u00e7ados em perguntas e respostas\" src=\"\/wp-content\/uploads\/2020\/05\/38b2ea076283285d934913c395863eb1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/avito\/blog\/500678\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430&nbsp;\u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437&nbsp;\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros. \u041e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438, \u043a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043a\u0430\u043a\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443&nbsp;\u043d\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442. \u041f\u043e&nbsp;\u043c\u043e\u0442\u0438\u0432\u0430\u043c \u0432\u0441\u0442\u0440\u0435\u0447\u0438 \u043c\u044b \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u0441&nbsp;\u043e\u0442\u0432\u0435\u0442\u0430\u043c\u0438 \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u043e\u0432 \u043d\u0430&nbsp;\u043d\u0430\u0448\u0438 \u0438 \u0437\u0440\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u043e&nbsp;\u0431\u044d\u043a\u0430\u043f\u044b, \u0440\u0435\u0448\u0430\u0440\u0434\u0438\u043d\u0433 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u0438, Golang-\u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u0441\u0438\u0439 ClickHouse. \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80776,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47ClickHouse \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-08T11:42:47+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-08T11:42:47+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47ClickHouse para usu\u00e1rios avan\u00e7ados em perguntas e respostas | ProHoster","description":"Em abril, os engenheiros da Avito se reuniram em um encontro online com o principal desenvolvedor do ClickHouse, Alexey Milovidov, e Kirill Shvakov, desenvolvedor Golang da empresa Integros.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47ClickHouse \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430\u0445 | ProHoster","og:description":"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-08T11:42:47+00:00","article:modified_time":"2020-05-08T11:42:47+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80775","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:11:22","updated":"2022-09-28 05:48:13","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/80775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=80775"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/80775\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/80776"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=80775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=80775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=80775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}