Rrd Moving Average


A grafite 1 executa duas tarefas muito simples: armazenar números que mudam ao longo do tempo e graficando-os. Houve muitos programas escritos ao longo dos anos para fazer essas mesmas tarefas. O que torna o Graphite exclusivo é que ele fornece essa funcionalidade como um serviço de rede que é fácil de usar e altamente escalável. O protocolo para alimentar dados em grafite é simples o suficiente para que você possa aprender a fazê-lo manualmente em alguns minutos (não que você realmente quisesse, mas é um teste decisivo para simplicidade). Renderizar gráficos e recuperar pontos de dados são tão fáceis quanto buscar um URL. Isso torna muito natural a integração de grafite com outros softwares e permite aos usuários criar aplicativos poderosos em cima do Graphite. Um dos usos mais comuns do Graphite é a construção de painéis baseados na web para monitoramento e análise. O grafite nasceu em um ambiente de comércio eletrônico de alto volume e seu design reflete isso. A escalabilidade e o acesso em tempo real aos dados são objetivos fundamentais. Os componentes que permitem que Graphite atinjam esses objetivos incluem uma biblioteca de banco de dados especializada e seu formato de armazenamento, um mecanismo de cache para otimizar as operações de IO e um método simples e eficaz de agrupamento de servidores de grafite. Ao invés de simplesmente descrever como o Grafite funciona hoje, vou explicar como o Graphite foi inicialmente implementado (de forma bastante ingenua), quais problemas eu encontrei e como eu planejei soluções para eles. 7.1. Biblioteca de banco de dados: armazenamento de dados de série de tempo A grafite é escrita inteiramente em Python e consiste em três componentes principais: uma biblioteca de banco de dados chamada sussurro. Um daemon back-end chamado carbono. E um webapp front-end que processa gráficos e fornece uma UI básica. Enquanto o sussurro foi escrito especificamente para Graphite, ele também pode ser usado de forma independente. É muito similar em design ao banco de dados round-robin usado pelo RRDtool, e apenas armazena dados numéricos da série temporal. Geralmente, pensamos em bancos de dados como processos de servidor que os aplicativos do cliente falam sobre sockets. No entanto, sussurro. Muito parecido com RRDtool, é uma biblioteca de banco de dados usada por aplicativos para manipular e recuperar dados armazenados em arquivos especialmente formatados. As operações de sussurro mais básicas são criadas para criar um novo arquivo sussurro, atualizar para escrever novos pontos de dados em um arquivo e buscar para recuperar pontos de dados. Figura 7.1: Anatomia básica de um arquivo de sussurro Como mostrado na Figura 7.1. Os arquivos de sussurro consistem em uma seção de cabeçalho contendo vários metadados, seguido de uma ou mais seções de arquivo. Cada arquivo é uma seqüência de pontos de dados consecutivos que são pares (timestamp, value). Quando uma operação de atualização ou busca é realizada, o sussurro determina o deslocamento no arquivo onde os dados devem ser gravados ou lidos, com base no timestamp e na configuração do arquivo. 7.2. The Back End: Um serviço de armazenamento de serviços simples O fim de semana de grafites é um processo do daemon chamado carbono-cache. Geralmente simplesmente referido como carbono. É construído em Twisted, uma estrutura IO altamente orientada para eventos escalonada para Python. Twisted permite que o carbono converse eficientemente com um grande número de clientes e manipule uma grande quantidade de tráfego com baixa sobrecarga. A Figura 7.2 mostra o fluxo de dados entre o carbono. Sussurro e webapp: os aplicativos do cliente coletam dados e enviam para o fundo da grafite, carbono. Que armazena os dados usando sussurro. Esses dados podem então ser usados ​​pelo webapp grafite para gerar gráficos. Figura 7.2: Fluxo de dados A principal função do carbono é armazenar pontos de dados para as métricas fornecidas pelos clientes. Na terminologia de grafite, uma métrica é qualquer quantidade mensurável que pode variar ao longo do tempo (como a utilização da CPU de um servidor ou o número de vendas de um produto). Um ponto de dados é simplesmente um par (timestamp, value) correspondente ao valor medido de uma métrica específica em um ponto no tempo. As métricas são identificadas de maneira exclusiva por seu nome e o nome de cada métrica, bem como seus pontos de dados, são fornecidos por aplicativos cliente. Um tipo comum de aplicativo cliente é um agente de monitoramento que coleciona métricas de sistema ou aplicativo e envia seus valores coletados para carbono para fácil armazenamento e visualização. As métricas na grafite têm nomes hierárquicos simples, semelhantes aos caminhos do sistema de arquivos, exceto que um ponto é usado para delimitar a hierarquia em vez de uma barra ou barra invertida. O carbono respeitará qualquer nome legal e criará um arquivo sussurro para cada métrica para armazenar seus pontos de dados. Os arquivos de sussurros são armazenados dentro do diretório de dados de carbono s em uma hierarquia de sistema de arquivos que reflete a hierarquia delimitada por pontos em cada nome de métricas, de modo que (por exemplo) servers. www01.cpuUsage mapeia para hellipserverswww01cpuUsage. wsp. Quando um aplicativo cliente deseja enviar pontos de dados para Graphite, ele deve estabelecer uma conexão TCP ao carbono. Geralmente na porta 2003 2. O cliente faz todo o carbono que fala não envia nada sobre a conexão. O cliente envia pontos de dados em um formato simples de texto simples enquanto a conexão pode ser deixada aberta e reutilizada conforme necessário. O formato é uma linha de texto por ponto de dados em que cada linha contém o nome da métrica pontilhada, o valor e um carimbo de data / hora Unix separados por espaços. Por exemplo, um cliente pode enviar: em um nível alto, todo o carbono é ouvir dados nesse formato e tentar armazená-lo no disco o mais rápido possível usando sussurro. Mais tarde, vamos discutir os detalhes de alguns truques usados ​​para garantir a escalabilidade e obter o melhor desempenho que podemos obter de um disco rígido típico. 7.3. O Front End: Gráficos On-Demand O webapp grafite permite aos usuários solicitar gráficos personalizados com uma API simples baseada em URL. Os parâmetros de representação gráfica são especificados na seqüência de consulta de uma solicitação HTTP GET, e uma imagem PNG é retornada em resposta. Por exemplo, o URL: solicita um gráfico 500times300 para a métrica servers. www01.cpuUsage e as últimas 24 horas de dados. Na verdade, apenas o parâmetro alvo é necessário, todos os outros são opcionais e usam seus valores padrão se forem omitidos. O grafite suporta uma grande variedade de opções de exibição, bem como funções de manipulação de dados que seguem uma sintaxe funcional simples. Por exemplo, podemos representar uma média móvel de 10 pontos da métrica em nosso exemplo anterior, como este: as funções podem ser aninhadas, permitindo expressões e cálculos complexos. Aqui está outro exemplo que dá o total de vendas do dia usando métricas por produto de vendas por minuto: a função SumSeries calcula uma série de tempo que é a soma de cada métrica correspondente aos produtos de padrão..salesPerMinute. Então, o integral calcula um total em execução em vez de uma contagem por minuto. A partir daqui, não é muito difícil imaginar como se pode construir uma UI da Web para visualizar e manipular gráficos. O grafite vem com sua própria UI compositor, mostrada na Figura 7.3. Isso faz isso usando o Javascript para modificar os parâmetros de URL dos gráficos à medida que o usuário clica nos menus dos recursos disponíveis. Figura 7.3: Interface do Compositor Graphites 7.4. Dashboards Desde a sua criação Graphite tem sido usado como uma ferramenta para criar painéis baseados na web. A URL API torna este um caso de uso natural. Fazer um painel é tão simples como fazer uma página HTML cheia de tags como esta: no entanto, nem todos gostam de criar URLs manualmente, portanto Graphites Composer UI fornece um método de apontar e clicar para criar um gráfico a partir do qual você pode simplesmente copiar e Cole o URL. Quando combinado com outra ferramenta que permite a criação rápida de páginas da web (como um wiki), isso torna-se fácil o suficiente para que os usuários não técnicos possam criar facilmente seus próprios painéis de controle. 7.5. Um gargalo obvio Uma vez que meus usuários começaram a criar painéis, Graphite rapidamente começou a ter problemas de desempenho. Eu investiguei os logs do servidor web para ver quais pedidos estavam atrapalhando. Era bem óbvio que o problema era a grande quantidade de solicitações gráficas. O webapp estava ligado à CPU, renderizando gráficos constantemente. Notei que havia muitos pedidos idênticos, e os painéis eram culpados. Imagine que você tenha um painel com 10 gráficos e a página atualiza uma vez por minuto. Cada vez que um usuário abre o painel em seu navegador, grafite tem que lidar com mais 10 pedidos por minuto. Isso rapidamente se torna caro. Uma solução simples é renderizar cada gráfico apenas uma vez e depois enviar uma cópia para cada usuário. A estrutura da Web do Django (que o Graphite é construído) fornece um excelente mecanismo de cache que pode usar vários back-ends como o memcached. O Memcached 3 é essencialmente uma tabela hash fornecida como um serviço de rede. Os aplicativos de cliente podem obter e definir pares de valores-chave como uma tabela de hash comum. O principal benefício do uso do memcached é que o resultado de uma solicitação cara (como renderizar um gráfico) pode ser armazenado muito rapidamente e recuperado posteriormente para lidar com pedidos subsequentes. Para evitar retornar os mesmos gráficos obsoletos para sempre, o memcached pode ser configurado para expirar os gráficos em cache após um curto período. Mesmo que isso seja apenas alguns segundos, o peso que tira a grafite é tremendo porque os pedidos duplicados são tão comuns. Outro caso comum que cria muitos pedidos de renderização é quando um usuário está ajustando as opções de exibição e aplicando funções na interface do usuário Composer. Cada vez que o usuário muda algo, Graphite deve redesenhar o gráfico. Os mesmos dados estão envolvidos em cada solicitação, então faz sentido colocar os dados subjacentes no memcache também. Isso mantém a UI responsiva ao usuário porque a etapa de recuperar dados é ignorada. 7.6. Otimizando o IO Imagine que você possui 60.000 métricas que você envia para o seu servidor de grafite e cada uma dessas métricas tem um ponto de dados por minuto. Lembre-se de que cada métrica tem seu próprio arquivo sussurro no sistema de arquivos. Isso significa que o carbono deve fazer uma operação de gravação para 60.000 arquivos diferentes por minuto. Enquanto o carbono pode escrever em um arquivo cada milissegundo, ele deve poder continuar. Isso não é muito extravagante, mas dizemos que você tem 600.000 métricas atualizando cada minuto, ou suas métricas estão atualizando a cada segundo, ou talvez você simplesmente não possa pagar o armazenamento rápido e suficiente. Seja qual for o caso, suponha que a taxa de pontos de dados recebidos exceda a taxa de operações de gravação que seu armazenamento pode acompanhar. Como essa situação deve ser tratada A maioria dos discos rígidos atualmente tem um tempo de busca lento 4. isto é, o atraso entre as operações de IO em dois locais diferentes, em comparação com a escrita de uma seqüência contígua de dados. Isso significa a escrita mais contígua que fazemos, quanto mais taxa de transferência obtemos. Mas se tivermos milhares de arquivos que precisam ser escritos com freqüência, e cada gravação é muito pequena (um ponto de dados de sussurro é de apenas 12 bytes), então nossos discos definitivamente passarão a maior parte do tempo buscando. Trabalhando sob o pressuposto de que a taxa de operações de gravação tem um teto relativamente baixo, a única maneira de aumentar nossa taxa de transferência de dados além dessa taxa é escrever múltiplos pontos de dados em uma única operação de gravação. Isso é viável porque o sussurro organiza pontos de dados consecutivos contiguos no disco. Então eu adicionei uma atualização de função para sussurrar. Que leva uma lista de pontos de dados para uma única métrica e compacta pontos de dados contíguos em uma única operação de gravação. Mesmo que isso tenha feito cada gravação maior, a diferença de tempo necessário para escrever dez pontos de dados (120 bytes) versus um ponto de dados (12 bytes) é insignificante. Demora mais alguns pontos de dados antes que o tamanho de cada escrita comece a afetar significativamente a latência. Em seguida, implementei um mecanismo de buffer em carbono. Cada ponto de dados recebido é mapeado para uma fila com base em seu nome de métrica e, em seguida, é anexado a essa fila. Outro segmento repetidamente itera através de todas as filas e para cada um que puxa todos os dados aponta e os grava no arquivo de sussurro apropriado com updatemany. Voltando ao nosso exemplo, se tivermos 600.000 métricas atualizando a cada minuto e nosso armazenamento só pode acompanhar 1 gravação por milissegundo, então as filas acabarão segurando aproximadamente 10 pontos de dados em média. O único recurso que isso nos custa é a memória, que é relativamente abundante, pois cada ponto de dados é apenas alguns bytes. Essa estratégia protege dinamicamente tantos pontos de dados quanto necessário para manter uma taxa de datapoints recebidos que podem exceder a taxa de operações de IO que seu armazenamento pode acompanhar. Uma boa vantagem desta abordagem é que ele acrescenta um grau de resiliência para lidar com desacelerações temporárias de IO. Se o sistema precisar fazer outros trabalhos de IO fora do Graphite, é provável que a taxa de operações de gravação diminua, caso em que as filas de carbono simplesmente crescerão. Quanto maiores as filas, maiores as gravações. Uma vez que o rendimento global dos pontos de dados é igual à taxa de tempos de operações de gravação, o tamanho médio de cada escrita, o carbono pode manter-se enquanto haja memória suficiente para as filas. O mecanismo de enfileiramento do carbono s é representado na Figura 7.4. Figura 7.4: Mecanismo de enfileiramento de carvões 7.7. Mantendo-o em tempo real, os pontos de dados de buffer foram uma ótima maneira de otimizar o carbono s IO, mas não demorou muito para que meus usuários percebessem um efeito colateral bastante preocupante. Revisando nosso exemplo novamente, obtivemos 600 mil métricas que atualizamos a cada minuto e assumimos que nosso armazenamento só pode acompanhar 60 mil operações de gravação por minuto. Isso significa que teremos aproximadamente 10 minutos de dados sentados em filas de Carbono a qualquer momento. Para um usuário, isso significa que os gráficos que eles solicitem do web site Graphite perderão os 10 minutos mais recentes de dados: Não é bom. Afortunadamente, a solução é bem direta. Simplesmente adicionei um ouvinte de soquete ao carbono que fornece uma interface de consulta para acessar os pontos de dados armazenados e, em seguida, modifica o webapp grafite para usar essa interface sempre que precisa recuperar dados. O webapp então combina os pontos de dados que recupera do carbono com os pontos de dados recuperados do disco e voila, os gráficos são em tempo real. Concedido, no nosso exemplo, os pontos de dados são atualizados ao minuto e, portanto, não exatamente em tempo real, mas o fato de que cada ponto de dados é acessível instantaneamente em um gráfico uma vez que é recebido pelo carbono é em tempo real. 7.8. Núcleos, caches e falhas catastróficas Como provavelmente é óbvio, a característica chave do desempenho do sistema que o próprio desempenho de Grafites depende é latência de IO. Até agora, assumimos que o nosso sistema tem consistentemente baixa latência de IO com uma média de cerca de 1 milisegundo por gravação, mas essa é uma grande hipótese que exige uma análise um pouco mais profunda. A maioria dos discos rígidos simplesmente não é rápido, mesmo com dezenas de discos em uma matriz RAID, é muito provável que tenha mais de 1 milissegundo de latência para acesso aleatório. No entanto, se você tentasse testar a rapidez com que até um laptop antigo pudesse escrever um kilobyte inteiro no disco, você acharia que a chamada do sistema de gravação retorna em muito menos de 1 milissegundo. Por que, sempre que o software possui características de desempenho incoerentes ou inesperadas, geralmente o armazenamento em buffer ou o armazenamento em cache são culpados. Nesse caso, lidavam com ambos. A chamada do sistema de gravação não técnico escreve seus dados no disco, ele simplesmente o coloca em um buffer que o kernel então grava no disco mais tarde. É por isso que a chamada de gravação geralmente retorna tão rapidamente. Mesmo após o buffer ter sido gravado no disco, ele geralmente permanece em cache para leituras subseqüentes. Ambos os comportamentos, armazenamento em buffer e cache, exigem memória, é claro. Os desenvolvedores do Kernel, sendo as pessoas inteligentes que são, decidiram que seria uma boa idéia usar qualquer memória de espaço do usuário atualmente livre ao invés de alocar a memória de forma definitiva. Isso acaba por ser um impulsionador de desempenho tremendamente útil e também explica por que, não importa a quantidade de memória que você adiciona a um sistema, geralmente acabará por ter uma memória livre quase zero depois de fazer uma quantidade modesta de IO. Se as suas aplicações de espaço de usuário não estão usando essa memória, provavelmente o seu kernel. A desvantagem dessa abordagem é que essa memória livre pode ser removida do kernel no momento em que um aplicativo de espaço de usuário decide que precisa alocar mais memória para si. O kernel não tem escolha senão renunciá-lo, perdendo quaisquer tampões que haja estado lá. Então, o que tudo isso significa para a grafite. Nós simplesmente destacamos a dependência do carbono em uma latência de IO consistentemente baixa e também sabemos que a chamada do sistema de gravação apenas retorna rapidamente porque os dados estão apenas sendo copiados para um buffer. O que acontece quando não há memória suficiente para o kernel para continuar as gravações de buffer. As gravações se tornam síncronas e, portanto, terrivelmente lentas Isso causa uma queda dramática na taxa de operações de gravação de carbono, o que faz com que as filas de carbono s cresçam, o que come ainda mais Memória, morrendo de fome o kernel ainda mais. No final, esse tipo de situação geralmente resulta em carbono sem memória ou sendo morto por um sysadmin irritado. Para evitar esse tipo de catástrofe, adicionei vários recursos ao carbono, incluindo limites configuráveis ​​de quantos pontos de dados podem ser enfileirados e limites de taxa de velocidade com que várias operações de sussurro podem ser executadas. Essas características podem proteger o carbono de fora de controle e, ao invés, impõem efeitos tão adversos como deixar alguns pontos de dados ou se recusar a aceitar mais pontos de dados. No entanto, os valores adequados para essas configurações são específicos do sistema e exigem uma quantidade razoável de testes para sintonizar. Eles são úteis, mas eles não resolvem o problema de forma fundamental. Para isso, bem, precisa de mais hardware. 7.9. Clustering Fazer múltiplos servidores de grafite parece ser um sistema único, do ponto de vista do usuário, não é extremamente difícil, pelo menos para uma implementação naiumlve. A interação do usuário do webapps consiste principalmente em duas operações: encontrar métricas e buscar pontos de dados (geralmente na forma de um gráfico). As operações de busca e busca do webapp estão escondidas em uma biblioteca que abstrai sua implementação do resto da base de código e também são expostas através de manipuladores de solicitação HTTP para chamadas remotas fáceis. A operação find procura o sistema de arquivos local de dados de sussurro para coisas que correspondem a um padrão especificado pelo usuário, assim como um sistema de arquivos glob como. txt corresponde a arquivos com essa extensão. Sendo uma estrutura de árvore, o resultado retornado pelo achado é uma coleção de objetos de nó, cada um derivado das sub-classes de filial ou Folha de Nó. Os diretórios correspondem a nós de ramificação e os arquivos de sussurros correspondem a nós de folha. Esta camada de abstração facilita o suporte a diferentes tipos de armazenamento subjacente, incluindo arquivos RRD 5 e arquivos de sussurros gzip. A interface Leaf define um método de busca cuja implementação depende do tipo de nó da folha. No caso de arquivos de sussurro é simplesmente um invólucro fino em torno da própria função de busca da biblioteca do sussurro. Quando o suporte ao cluster foi adicionado, a função de busca foi estendida para poder fazer chamadas de busca remota via HTTP para outros servidores de grafite especificados na configuração do webapps. Os dados do nó contidos nos resultados dessas chamadas HTTP são envolvidos como objetos RemoteNode que estão em conformidade com o Nó usual. Ramo. E Folhas. Isso torna o cluster transparente para o resto da base de código do webapps. O método de busca para um nó de folha remota é implementado como outra chamada HTTP para recuperar os pontos de dados do servidor Graphite dos nós. Todas essas chamadas são feitas entre os webapps da mesma forma que um cliente os chamaria, exceto com um parâmetro adicional especificando que a operação só deveria ser realizada localmente e não seria redistribuída em todo o cluster. Quando o webapp é solicitado a renderizar um gráfico, ele executa a operação de busca para localizar as métricas solicitadas e as chamadas buscarem em cada uma para recuperar seus pontos de dados. Isso funciona se os dados estão no servidor local, servidores remotos ou ambos. Se um servidor for desligado, o controle remoto efetua o tempo limite bastante rápido e o servidor está marcado como fora de serviço por um período curto durante o qual nenhuma outra chamada será feita. Do ponto de vista do usuário, qualquer um dos dados no servidor perdido estará faltando nos seus gráficos, a menos que esses dados sejam duplicados em outro servidor no cluster. 7.9.1. Uma Breve Análise da Eficiência em Clustering A parte mais cara de uma solicitação gráfica está representando o gráfico. Cada renderização é executada por um único servidor para que adicionar mais servidores efetivamente aumenta a capacidade de renderização de gráficos. No entanto, o fato de que muitos pedidos acabam distribuindo encontrar chamadas para qualquer outro servidor no cluster significa que nosso esquema de agrupamento compartilha muito da carga frontal, em vez de dispersá-lo. O que conseguimos neste momento, no entanto, é uma maneira eficaz de distribuir a carga back-end, pois cada instância de carbono opera de forma independente. Este é um bom primeiro passo, já que a maior parte do tempo o back-end é um gargalo muito antes do front-end, mas claramente o front-end não escalará horizontalmente com essa abordagem. Para tornar a escala da frente mais eficaz, o número de chamadas de localização remota feitas pelo webapp deve ser reduzido. Mais uma vez, a solução mais fácil é o cache. Assim como o memcached já é usado para armazenar em cache pontos de dados e gráficos renderizados, ele também pode ser usado para armazenar em cache os resultados das solicitações de pesquisa. Uma vez que a localização das métricas é muito menos propensas a mudar com freqüência, isso normalmente deve ser armazenado em cache por mais tempo. O trade-off da configuração do tempo limite do cache para encontrar resultados muito longos, no entanto, é que as novas métricas que foram adicionadas à hierarquia podem não aparecer tão rapidamente para o usuário. 7.9.2. Distinção de métricas em um cluster O webapp grafite é bastante homogêneo em todo um cluster, na medida em que executa exatamente o mesmo trabalho em cada servidor. O papel do carbono, no entanto, pode variar de servidor para servidor, dependendo dos dados que você escolhe enviar para cada instância. Muitas vezes, há muitos clientes diferentes enviando dados para o carbono. Então seria bastante irritante acoplar cada configuração de clientes com seu layout de clusters de grafite. As métricas do aplicativo podem ir para um servidor de carbono, enquanto as métricas de negócios podem ser enviadas para vários servidores de carbono para redundância. Para simplificar o gerenciamento de cenários como este, Graphite vem com uma ferramenta adicional chamada de retransmissão de carbono. Seu trabalho é bastante simples, ele recebe dados métricos de clientes exatamente como o daemon de carbono padrão (que é realmente chamado de carbono-cache), mas em vez de armazenar os dados, ele aplica um conjunto de regras aos nomes das métricas para determinar quais servidores de cache de carbono Para retransmitir os dados para. Cada regra consiste em uma expressão regular e uma lista de servidores de destino. Para cada ponto de dados recebido, as regras são avaliadas em ordem e a primeira regra cuja expressão regular corresponde ao nome da métrica é usada. Desta forma, todos os clientes precisam fazer é enviar seus dados para o retransmissão de carbono e acabará nos servidores certos. Em certo sentido, o retransmissão de carbono fornece funcionalidade de replicação, embora seja mais exatamente chamado de duplicação de entrada, uma vez que não trata de problemas de sincronização. Se um servidor for desativado temporariamente, faltará os pontos de dados para o período de tempo em que estava para baixo, mas, de outra forma, funcionou normalmente. Existem scripts administrativos que deixam o controle do processo de re-sincronização nas mãos do administrador do sistema. 7.10. Reflexões de design Minha experiência em trabalhar com grafite reafirmou a crença de que a escalabilidade tem muito pouco a ver com desempenho de baixo nível, mas sim é um produto do design geral. Eu já encontrei muitos estrangulamentos ao longo do caminho, mas cada vez que busco melhorias no design, em vez de acelerar o desempenho. Foi-me perguntado muitas vezes por que escrevi Grafite em Python em vez de Java ou C, e minha resposta é sempre que ainda não encontrei uma verdadeira necessidade do desempenho que outro idioma poderia oferecer. Em Knu74, Donald Knuth disse que a otimização prematura é a raiz de todo o mal. Enquanto assumirmos que nosso código continuará a evoluir de maneiras não triviais, então toda otimização 6 é, de certa forma, prematura. Um dos grafites maiores pontos fortes e maiores fraquezas é o fato de que muito pouco foi projetado no sentido tradicional. Em geral, a grafite evoluiu gradualmente, obstáculo ao obstáculo, à medida que surgem problemas. Muitas vezes, os obstáculos eram previsíveis e várias soluções preventivas pareciam naturais. No entanto, pode ser útil evitar resolver problemas que você ainda não possui, mesmo que pareça provável que você em breve. A razão é que você pode aprender muito mais de estudar de perto as falhas reais do que teorizar sobre estratégias superiores. A resolução de problemas é conduzida tanto pelos dados empíricos que temos em mãos quanto pelo nosso próprio conhecimento e intuição. Descobri que duvidar de sua própria sabedoria o suficiente pode forçá-lo a analisar seus dados empíricos mais detalhadamente. Por exemplo, quando eu escrevi pela primeira vez, eu estava convencido de que teria que ser reescrito em C para velocidade e que minha implementação do Python seria apenas um protótipo. Se eu estivesse de acordo com uma crise de tempo, eu poderia ter ignorado completamente a implementação do Python. Acontece, no entanto, que a IO é um gargalo muito anterior à CPU, que a menor eficiência de Python dificilmente importa na prática. Como eu disse, porém, a abordagem evolutiva também é uma grande fraqueza da grafite. Interfaces, afinal, não se prestam bem à evolução gradual. Uma boa interface é consistente e emprega convenções para maximizar a previsibilidade. Por esta medida, a API de URL de grafites é atualmente uma interface de sub-par na minha opinião. As opções e as funções foram adotadas ao longo do tempo, às vezes formando pequenas ilhas de consistência, mas, em geral, não possuem um senso global de consistência. A única maneira de resolver esse problema é através da versão de interfaces, mas isso também tem inconvenientes. Uma vez que uma nova interface é projetada, a antiga ainda é difícil de se livrar, permanecendo como bagagem evolutiva como o apêndice humano. Pode parecer inofensivo até um dia o seu código obter apendicite (ou seja, um erro ligado à interface antiga) e você é obrigado a operar. Se eu mudasse uma coisa sobre Graphite no início, teria sido ter muito mais cuidado ao projetar as APIs externas, pensando em vez de as evoluir um pouco a pouco. Outro aspecto da grafite que causa alguma frustração é a flexibilidade limitada do modelo hierárquico de nomenclatura métrica. Embora seja bastante simples e muito conveniente para a maioria dos casos de uso, faz algumas consultas sofisticadas muito difíceis, mesmo impossíveis, expressar. Quando pensei pela primeira vez em criar grafite, eu sabia desde o início que queria uma API de URL editável por humanos para criar gráficos 7. Embora eu ainda fique feliz por o Grafite fornecer isso hoje, receio que esse requisito tenha sobrecarregado a API com uma sintaxe excessivamente simples que Faz expressões complexas pesadas. Uma hierarquia torna o problema de determinar a chave primária para uma métrica bastante simples porque um caminho é essencialmente uma chave primária para um nó na árvore. A desvantagem é que todos os dados descritivos (ou seja, dados de coluna) devem ser incorporados diretamente no caminho. Uma solução potencial é manter o modelo hierárquico e adicionar um banco de dados de metadados separado para permitir uma seleção mais avançada de métricas com uma sintaxe especial. 7.11. Tornando-se de código aberto Olhando para a evolução da grafite, ainda estou surpreso por quão longe ele veio como um projeto e por quão longe ele me levou como programador. Começou como um projeto de estimação que era apenas algumas centenas de linhas de código. O mecanismo de renderização começou como uma experiência, simplesmente para ver se eu poderia escrever um. O sussurro foi escrito no decorrer de um fim de semana fora de desespero para resolver um problema de show-stopper antes de uma data de lançamento crítica. O carbono foi reescrito mais vezes do que eu me lembrava. Uma vez que eu tinha permissão para lançar Grafite sob uma licença de código aberto em 2008, nunca esperava muita resposta. Depois de alguns meses, foi mencionado em um artigo da CNET que foi retirado pela Slashdot e o projeto decolou de repente e tem estado ativo desde então. Hoje, existem dezenas de grandes e médias empresas que usam Graphite. A comunidade é bastante ativa e continua a crescer. Longe de ser um produto acabado, há muitos trabalhos experimentais que estão sendo feitos, o que mantém divertido trabalhar e cheio de potencial. Launchpad. netgraphite Existe outra porta sobre a qual os objetos serializados podem ser enviados, o que é mais eficiente do que o formato de texto simples. Isso só é necessário para níveis muito altos de tráfego. Memcached. org As unidades de estado sólido geralmente têm tempos de busca extremamente rápidos em comparação com os discos rígidos convencionais. Os arquivos RRD são, na verdade, nós de ramificação porque eles podem conter várias fontes de dados, uma fonte de dados RRD é um nó de folha. Knuth especificamente significou otimização de código de baixo nível, não otimização macroscópica, como melhorias de design. Isso força os próprios gráficos a serem de código aberto. Qualquer um pode simplesmente olhar para um URL de gráficos para compreendê-lo ou modificá-lo. R. R. Donnelley Sons Company Dados de Resumo de Cotação de Ações em Tempo Real Após Horas Notícias Pré-Mercado Citação de Resumo de Cálculo Sumário Gráficos Interativos Configuração Padrão Por favor, note que, uma vez que você fizer sua seleção, ela se aplicará a todas as futuras visitas ao NASDAQ. Se, a qualquer momento, você estiver interessado em reverter as nossas configurações padrão, selecione Configuração padrão acima. Se você tiver dúvidas ou encontrar quaisquer problemas na alteração das configurações padrão, envie um email para isfeedbacknasdaq. Confirme a sua seleção: Você selecionou para alterar sua configuração padrão para a Pesquisa de orçamento. Esta será a sua página de destino padrão, a menos que você altere sua configuração novamente ou exclua seus cookies. Tem certeza de que deseja alterar suas configurações. Temos um favor a pedir. Desative seu bloqueador de anúncios (ou atualize suas configurações para garantir que o javascript e os cookies estejam habilitados), para que possamos continuar fornecendo as notícias de mercado de primeira linha E os dados que você espera esperar de nós.

Comments