Sunday, 1 April 2018

Sistemas de negociação de baixa latência de alto débito


A página não pode ser encontrada.
Por favor, tente o seguinte:
Verifique se o endereço do site exibido na barra de endereços do seu navegador está escrito e formatado corretamente. Se você chegou a esta página clicando em um link, entre em contato com o administrador do site para alertá-los de que o link está formatado incorretamente. Clique no botão Voltar para tentar outro link.
HTTP Error 404 - Arquivo ou diretório não encontrado.
Serviços de Informações da Internet (IIS)
Informações técnicas (para pessoal de suporte)
Acesse os Serviços de suporte técnico da Microsoft e execute uma pesquisa de título para as palavras HTTP e 404. Abra a Ajuda do IIS, acessível no Gerenciador do IIS (inetmgr) e procure tópicos intitulados Configuração do site, tarefas administrativas comuns e Sobre mensagens de erro personalizadas.

11 Práticas recomendadas para sistemas de baixa latência.
Foram 8 anos desde que o Google notou que um extra de 500ms de latência caiu o tráfego em 20% e a Amazon percebeu que 100ms de latência extra caíram as vendas em 1%. Desde então, os desenvolvedores estiveram correndo para o fundo da curva de latência, culminando em desenvolvedores de front-end espremendo todos os últimos milésimos de segundo de seu JavaScript, CSS e HTML. O que se segue é uma caminhada aleatória através de uma variedade de práticas recomendadas para ter em mente ao projetar sistemas de baixa latência. A maioria dessas sugestões são levadas ao extremo lógico, mas é claro que podem ser feitas compensações. (Obrigado a um usuário anônimo por fazer esta pergunta no Quora e me fazer colocar meus pensamentos por escrito).
Escolha o idioma certo.
As linguagens de script não precisam se aplicar. Embora eles continuem ficando cada vez mais rápidos, quando você está olhando para raspar os últimos milissegundos do seu tempo de processamento, você não pode ter a sobrecarga de um idioma interpretado. Além disso, você vai querer um modelo de memória forte para habilitar a programação sem bloqueio para que você esteja olhando Java, Scala, C ++ 11 ou Go.
Mantenha tudo na memória.
I / O irá matar sua latência, portanto, certifique-se de que todos os seus dados estão na memória. Isso geralmente significa gerenciar suas próprias estruturas de dados em memória e manter um registro persistente, para que você possa reconstruir o estado após uma reinicialização de máquina ou processo. Algumas opções para um registro persistente incluem Bitcask, Krati, LevelDB e BDB-JE. Alternativamente, você pode fugir com a execução de um banco de dados local, persistente na memória, como redis ou MongoDB (com dados da memória & gt; & gt;). Observe que você pode perder alguns dados sobre falhas devido à sua sincronização de fundo no disco.
Mantenha dados e processamento colocados.
O lúpulo de rede é mais rápido do que o disco, mas mesmo assim eles vão adicionar muitas despesas gerais. Idealmente, seus dados devem caber inteiramente na memória em um host. Com a AWS fornecendo quase 1/4 TB de RAM na nuvem e servidores físicos que oferecem múltiplas TBs, isso geralmente é possível. Se você precisa executar em mais de um host, você deve garantir que seus dados e solicitações sejam adequadamente particionados para que todos os dados necessários para atender uma determinada solicitação estejam disponíveis localmente.
Mantenha o sistema subutilizado.
A baixa latência requer sempre recursos para processar a solicitação. Não tente executar no limite do que seu hardware / software pode fornecer. Sempre tem muita sala de cabeça para rajadas e depois algumas.
Mantenha os parâmetros de contexto ao mínimo.
Os switches de contexto são um sinal de que você está fazendo mais trabalho de computação do que você tem recursos. Você quer limitar seu número de segmentos ao número de núcleos em seu sistema e colocar cada segmento no seu núcleo.
Mantenha suas leituras seqüenciais.
Todas as formas de armazenamento, murchar é rotacional, com base em flash ou memória, melhoram significativamente quando usado sequencialmente. Ao emitir leituras seqüenciais para a memória, você desencadeia o uso da pré-busca no nível de RAM, bem como no nível de cache da CPU. Se for feito corretamente, a próxima peça de dados que você precisa estará sempre em cache L1 antes de precisar. A maneira mais fácil de ajudar esse processo é fazer uso intenso de matrizes de tipos ou tipos de dados primitivos. Os ponteiros a seguir, seja através do uso de listas vinculadas ou através de matrizes de objetos, devem ser evitados a todo custo.
Lote suas escritas.
Isso parece contraintuitivo, mas você pode obter melhorias significativas no desempenho através de gravações por lotes. No entanto, existe um equívoco de que isso significa que o sistema deve aguardar uma quantidade arbitrária de tempo antes de escrever. Em vez disso, um segmento deve girar em um loop apertado fazendo I / O. Cada escrita irá lote todos os dados que chegaram desde a última gravação emitida. Isso faz com que um sistema muito rápido e adaptável.
Respeite seu cache.
Com todas essas otimizações no local, o acesso à memória rapidamente se torna um gargalo. Fixar threads para seus próprios núcleos ajuda a reduzir a poluição do cache da CPU e as E / S seqüenciais também ajudam a pré-carregar o cache. Além disso, você deve manter os tamanhos de memória para baixo usando tipos de dados primitivos para que mais dados se encaixem no cache. Além disso, você pode procurar algoritmos cache-inconscientes que funcionam recursivamente, quebrando os dados até que ele se encaixe no cache e depois faça qualquer processamento necessário.
Não bloqueando o máximo possível.
Faça com que os amigos não bloqueiem e aguardem estruturas e algoritmos de dados gratuitos. Toda vez que você usa um bloqueio, você precisa baixar a pilha para o sistema operacional para mediar o bloqueio, que é uma enorme sobrecarga. Muitas vezes, se você sabe o que está fazendo, você pode contornar os bloqueios através da compreensão do modelo de memória da JVM, C ++ 11 ou Go.
Async, tanto quanto possível.
Qualquer processamento e particularmente qualquer E / S que não seja absolutamente necessário para a construção da resposta deve ser feito fora do caminho crítico.
Paralelize o máximo possível.
Qualquer processamento e particularmente qualquer E / S que possa acontecer em paralelo deve ser feito em paralelo. Por exemplo, se sua estratégia de alta disponibilidade inclui o log de transações para o disco e o envio de transações para um servidor secundário, essas ações podem acontecer em paralelo.
Quase tudo isso vem de seguir o que o LMAX está fazendo com seu projeto Disruptor. Leia sobre isso e siga tudo o que Martin Thompson faz.
Compartilhar isso:
Relacionados.
Publicado por.
Benjamin Darfler.
29 pensamentos sobre & ldquo; 11 melhores práticas para sistemas de baixa latência & rdquo;
E feliz em estar na sua lista 🙂
Bom artigo. One beef: Go doesn & # 8217; t tem um modelo de memória sofisticado como Java ou C ++ 11. Se o seu sistema se encaixa com a rotina da rotina e a arquitetura dos canais, é bom demais, sem sorte. O AFAIK não é possível excluir o agendador de tempo de execução, portanto, não há falhas de sistema operacional nativas e a capacidade de criar suas próprias estruturas de dados livres de bloqueio como (colunas SPSC / anejadores) também faltam severamente.
Obrigado pela resposta. Embora o modelo de memória Go (golang. org/ref/mem) possa não ser tão robusto quanto o Java ou o C ++ 11, tive a impressão de que você ainda poderia criar estruturas de dados sem bloqueio usando isso. Por exemplo, github / textnode / gringo, github / scryner / lfreequeue e github / mocchira / golfhash. Talvez eu estivesse faltando alguma coisa? É certo que eu sei muito menos sobre o Go do que a JVM.
Benjamin, o modelo de memória Go detalhado aqui: golang. org/ref/mem é principalmente em termos de canais e mutexes. Eu olhei através dos pacotes que você listou e enquanto as estruturas de dados existem & # 8220; lock free & # 8221; eles não são equivalentes ao que um pode construir em Java / C ++ 11. O pacote de sincronização a partir de agora, não tem suporte para átomos relaxados ou a semântica de aquisição / lançamento do C ++ 11. Sem esse suporte, é difícil construir estruturas de dados SPSC tão eficientes quanto as possíveis em C ++ / Java. Os projetos que você liga usam atomic. Add & # 8230; que é um átomo consistente consecutivamente. Ele é construído com XADD como deveria ser # 8211; github / tonnerre / golang / blob / master / src / pkg / sync / atomic / asm_amd64.s.
Eu não estou tentando derrubar Ir para baixo. É preciso um esforço mínimo para escrever IO assíncrono e concorrente.
código suficientemente rápido para a maioria das pessoas. A biblioteca std também está altamente ajustada para o desempenho. A Golang também tem suporte para estruturas que estão faltando em Java. Mas, como está, penso que o modelo de memória simplista e o tempo de execução da rotina estão no caminho da construção do tipo de sistemas de que você está falando.
Obrigado pela resposta em profundidade. Espero que as pessoas achem isso útil.
Enquanto um & # 8216; native & # 8217; O idioma provavelmente é melhor, não é estritamente necessário. O Facebook nos mostrou que pode ser feito em PHP. Concedido eles usam o PHP pré-compilado com sua máquina HHVM. Mas é possível!
Infelizmente, o PHP ainda não possui um modelo de memória aceitável, mesmo que o HHVM melhore significativamente a velocidade de execução.
Enquanto eu lutarei para usar linguagens de nível superior, tanto quanto o próximo cara, acho que a única maneira de alcançar os aplicativos de baixa latência que as pessoas estão procurando é deslizar para um idioma como C. Parece que a mais difícil é escrever em um idioma, mais rápido ele executa.
Eu recomendo que você olhe para o trabalho que está sendo feito nos projetos e blogs aos quais eu liguei. A JVM está rapidamente se tornando o ponto quente para esses tipos de sistemas porque fornece um modelo de memória forte e uma coleta de lixo que permitem a programação sem bloqueio quase impossivel com um modelo de memória fraco ou indefinido e contadores de referência para gerenciamento de memória.
Olharei, Benjamin. Obrigado por apontá-los.
A coleta de lixo para programação sem bloqueio é um pouco de um deus ex machina. As filas MPMC e SPSC podem ser criadas sem necessidade de GC. Há também muitas maneiras de fazer programação sem bloqueio sem coleta de lixo e a contagem de referências não é a única maneira. Os ponteiros de perigo, RCU, Proxy-Collectors, etc, fornecem suporte para recuperação diferida e geralmente são codificados em suporte de um algoritmo (não genérico), portanto, eles geralmente são muito mais fáceis de construir. É claro que o trade-off reside no fato de que os GCs de qualidade de produção têm muito trabalho colocado neles e ajudarão o programador menos experiente a escrever algoritmos sem bloqueio (eles deveriam estar fazendo isso?) Sem codificação de esquemas de recuperação diferida . Alguns links sobre o trabalho realizado neste campo: cs. toronto. edu/
Sim C / C ++ recentemente ganhou um modelo de memória, mas isso não significa que eles eram completamente inadequados para o código sem bloqueio anteriormente. O GCC e outros compiladores de alta qualidade tinham diretrizes específicas do compilador para fazer programação gratuita de bloqueio em plataformas suportadas por um tempo realmente grande # 8211; não era padronizado na língua. Linux e outras plataformas forneceram essas primitivas por algum tempo também. A posição única de Java foi que forneceu um modelo de memória formalizado que garantiu trabalhar em todas as plataformas suportadas. Embora, em princípio, isso seja incrível, a maioria dos desenvolvedores do lado do servidor trabalham em uma plataforma (Linux / Windows). Eles já tinham as ferramentas para criar código sem bloqueio para sua plataforma.
GC é uma ótima ferramenta, mas não é necessária. Tem um custo tanto em termos de desempenho como em complexidade (todos os truques necessários para evitar STW GC). C ++ 11 / C11 já possui suporte para modelos de memória adequados. Não vamos esquecer que as JVMs não têm responsabilidade em suportar a API insegura no futuro. O código inseguro é & # 8220; unsafe & # 8221; então você perde os benefícios das características de segurança da Java. Finalmente, o código inseguro usado para criar memória e simular estruturas em Java parece muito mais feio do que as estruturas C / C ++ onde o compilador está fazendo isso funciona de maneira confiável. C e C ++ também fornecem acesso a todas as ferramentas elétricas específicas de plataforma de baixo nível, como PAUSE ins, SSE / AVX / NEON etc. Você pode até ajustar seu layout de código através de scripts de linker! O poder fornecido pela cadeia de ferramentas C / C ++ é realmente incomparável pela JVM. O Java é uma ótima plataforma, no entanto, acho que a maior vantagem é que a lógica comercial comum (90% do seu código?) Ainda pode depender do GC e dos recursos de segurança e fazer uso de bibliotecas altamente sintonizadas e testadas escritas com inseguro. Este é um grande trade-off entre obter os últimos 5% de perf e ser produtivo. Um trade-off que faz sentido para muitas pessoas, mas um trade-off, no entanto. Escrever um código de aplicação complicado em C / C ++ é um pesadelo depois de tudo.
No dia 10 de março de 2014 às 12:52, CodeDependents escreveu:
& gt; Graham Swan comentou: "Tenho uma olhada, Benjamin. Obrigado por & gt; apontando para fora. & # 8221;
Falta o 12: Não use linguagens coletadas Garbadge. GC é um gargalo na piora. Provavelmente, interrompe todos os tópicos. É um global. Isso distrai o arquiteto para gerenciar um dos recursos mais craterais (CPU-near memory).
Na verdade, muito deste trabalho vem diretamente de Java. Para fazer uma programação livre de bloqueio, você precisa de um modelo de memória claro, que c ++ recentemente ganhou recentemente. Se você sabe trabalhar com GC e não contra isso, você pode criar sistemas de baixa latência com muita facilidade.
Eu tenho que concordar com Ben aqui. Houve muitos progressos no paralelismo do GC na última década, ou seja, com o coletor G1 sendo o incantation mais recente. Pode levar um pouco de tempo para sintonizar o heap e vários botões para obter o GC para coletar com quase nenhuma pausa, mas isso contrasta em comparação com o tempo de desenvolvimento necessário para não ter GC.
Você pode até dar um passo adiante e criar sistemas que produzem tão pouco lixo que você pode facilmente empurrar o seu GC fora da sua janela de operação. É assim que todas as lojas comerciais de alta freqüência o fazem quando são executados na JVM.
A coleta de lixo para programação sem bloqueio é um pouco de um deus ex machina. As filas MPMC e SPSC podem ser criadas sem necessidade de GC. Há também muitas maneiras de fazer programação sem bloqueio sem coleta de lixo e a contagem de referências não é a única maneira. Os ponteiros de perigo, RCU, Proxy-Collectors, etc, fornecem suporte para recuperação diferida e são codificados em suporte de um algoritmo (não genérico), portanto, eles são muito mais fáceis de construir. É claro que o trade-off reside no fato de que os GCs de qualidade de produção têm muito trabalho colocado neles e ajudarão o programador menos experiente a escrever algoritmos sem bloqueio (eles deveriam estar fazendo isso?) Sem codificação de esquemas de recuperação diferida . Alguns links sobre o trabalho realizado neste campo: cs. toronto. edu/
Sim C / C ++ recentemente ganhou um modelo de memória, mas isso não significa que eles eram completamente inadequados para o código sem bloqueio anteriormente. O GCC e outros compiladores de alta qualidade tinham diretrizes específicas do compilador para fazer programação gratuita de bloqueio em plataformas suportadas por um tempo realmente grande # 8211; não era padronizado na língua. Linux e outras plataformas forneceram essas primitivas por algum tempo também. A posição única de Java foi que forneceu um modelo de memória formalizado que garantiu trabalhar em todas as plataformas suportadas. Embora, em princípio, isso seja incrível, a maioria dos desenvolvedores do lado do servidor trabalham em uma plataforma (Linux / Windows). Eles já tinham as ferramentas para criar código sem bloqueio para sua plataforma.
GC é uma ótima ferramenta, mas não é necessária. Tem um custo tanto em termos de desempenho quanto em complexidade (todos os truques necessários para atrasar e evitar STW GC). C ++ 11 / C11 já possui suporte para modelos de memória adequados. Não vamos esquecer que as JVMs não têm responsabilidade em suportar a API insegura no futuro. O código inseguro é & # 8220; unsafe & # 8221; então você perde os benefícios das características de segurança da Java. Finalmente, o código inseguro usado para criar memória e simular estruturas em Java parece muito mais feio do que as estruturas C / C ++ onde o compilador está fazendo isso funciona de maneira confiável. C e C ++ também fornecem acesso a todas as ferramentas elétricas específicas de plataforma de baixo nível, como PAUSE ins, SSE / AVX / NEON etc. Você pode até ajustar seu layout de código através de scripts de linker! O poder fornecido pela cadeia de ferramentas C / C ++ é realmente incomparável pela JVM. O Java é uma ótima plataforma, no entanto, acho que a maior vantagem é que a lógica comercial comum (90% do seu código?) Ainda pode depender do GC e dos recursos de segurança e fazer uso de bibliotecas altamente sintonizadas e testadas escritas com inseguro. Este é um grande trade-off entre obter os últimos 5% de perf e ser produtivo. Um trade-off que faz sentido para muitas pessoas, mas um trade-off, no entanto. Escrever um código de aplicação complicado em C / C ++ é um pesadelo depois de tudo.
& gt; Não use linguagens coletadas garbadge.
Ou, pelo menos, & # 8220; tradicional & # 8221; Lixo coletado línguas. Porque eles são diferentes & # 8211; enquanto Erlang também tem um colecionador, não criou gargalos porque não pára o mundo & # 8217; t & # 8220; pára o mundo & # 8221; como Java, enquanto colecionava lixo e # 8211; em vez disso, interrompe os microcréditos pequenos individuais & # 8220; & # 8221; em uma escala de microssegunda, portanto, não é visível no grande.
Reescreva isso para & # 8220; tradicional & # 8221; algoritmos [i] de coleta de lixo [/ i]. Na LMAX usamos o Azul Zing, e apenas usando uma JVM diferente com uma abordagem diferente para a coleta de lixo, vimos grandes melhorias no desempenho, porque os GCs maiores e menores são ordens de magnitude mais baratas.
Existem outros custos que compensam isso, é claro: você usa um monte muito mais, e o Zing não é barato.
Reblogged this em Java Prorgram Exemplos e comentou:
Um dos artigos de leitura obrigatória para programadores Java, é a lição que você aprenderá depois de passar um tempo considerável de afinação e desenvolver sistemas de baixa latência em Java em 10 minutos.
Revivendo um tópico antigo, mas (incrivelmente) isso deve ser apontado:
1) Linguagens de nível superior (por exemplo, Java) não desejam a funcionalidade do hardware que não está disponível para idiomas de nível inferior (por exemplo, C); declarar que assim e assim é completamente impossível & # 8221; em C, facilmente acessível em Java, é um lixo completo sem reconhecer que o Java é executado em hardware virtual onde a JVM deve sintetizar a funcionalidade exigida pelo Java, mas não fornecida pelo hardware físico. Se uma JVM (por exemplo, escrita em C) pode sintetizar a funcionalidade X, então também pode um programador C.
2) & # 8220; Lock free & # 8221; não é o que as pessoas pensam, exceto quase por coincidência em certas circunstâncias, como o único núcleo x86; multicore x86 não pode ser executado sem bloqueio sem barreiras de memória, que tem complexidades e custos semelhantes ao bloqueio regular. De acordo com 1 acima, se o Lock Free funcionar em um determinado ambiente, é porque ele é suportado pelo hardware, ou emulado / sintetizado por software em um ambiente virtual.
Great Points Julius. O ponto que eu estava tentando (talvez sem sucesso) é que é proibitivamente difícil aplicar muitos desses padrões em C, pois eles dependem do GC. Isso vai além do simples uso de barreiras de memória. Você também deve considerar a liberação de memória, o que fica particularmente difícil quando você está lidando com algoritmos livres de segurança e sem espera. É aqui que o GC adiciona uma grande vitória. Dito isto, eu ouço que Rust tenha algumas idéias muito interessantes sobre a propriedade da memória que possam começar a abordar algumas dessas questões.

Arquiteturas eficientes para sistemas de baixa latência e alta taxa de transferência na JVM.
Interesses relacionados.
Classificação e Estatísticas.
Opções de compartilhamento.
Ações de documentos.
As páginas 2 a 15 não são mostradas nesta pré-visualização.
Documentos recomendados.
Documentos semelhantes às arquiteturas eficientes para sistemas de baixa latência e alta taxa de transferência na JVM.
Documentos Sobre Fio (Informática)
Documentos sobre computação paralela.
Menu de Rodapé.
Legal.
Mídia social.
Direitos autorais e cópia; 2017 Scribd Inc.. Procure livros. Site móvel. Diretório do site. Idioma do site:
Você tem certeza?
Esta ação pode não ser possível desfazer. Você tem certeza que quer continuar?
Tem certeza de que deseja excluir esta lista?
Tudo o que você selecionou também será removido de suas listas.
Este livro também será removido de todas as suas listas.
Nós temos títulos com curadoria que achamos que você adorará.
O resto deste título estará disponível em breve.
Arquiteturas eficientes para sistemas de baixa latência e alta taxa de transferência na JVM estarão disponíveis.

Sistemas de negociação de baixa latência de alta conversão
Obter através da App Store Leia esta publicação em nosso aplicativo!
Alto rendimento versus baixa latência em HDFS.
Eu tentei definir o que o alto débito versus a baixa latência significa em HDFS em minhas próprias palavras e surgiu a seguinte definição:
O HDFS está otimizado para acessar lotes de dados mais rápidos (alto débito), em vez de registros particulares nesse conjunto de dados (baixa latência)
Isso faz sentido? :)
Eu acho que o que você descreveu é mais como a diferença entre a otimização de diferentes padrões de acesso (acesso seqüencial, em lotes versus acesso aleatório) do que a diferença entre throughput e latência no sentido mais puro.
Quando penso em um sistema de alta latência, não estou pensando em qual registro estou acessando, mas sim que acessar qualquer registro tem um alto custo indireto. Acessar mesmo o primeiro byte de um arquivo do HDFS pode demorar cerca de um segundo ou mais.
Se você estiver mais inclinado quantitativamente, você pode pensar sobre o tempo total necessário para acessar uma série de registros N como T (N) = aN + b. Aqui, representa o rendimento, e b representa a latência. Com um sistema como HDFS, N é muitas vezes tão grande que b torna-se irrelevante e as compensações favorecendo um baixo são benéficas. Contraste isso a um armazenamento de dados de baixa latência, onde muitas vezes cada leitura está apenas acessando um único registro e, em seguida, otimizar o baixo b é melhor.
Com isso dito, sua afirmação não está incorreta; é definitivamente verdade, e muitas vezes o caso das lojas de acesso em lote tem alta latência e alto rendimento, enquanto as lojas de acesso aleatório têm baixa latência e baixo débito, mas isso não é estritamente sempre o caso.
Eu vou dar uma volta a este.
Acesso de dados de baixa latência: toque a tecla enter (ou botão de envio) e espero resultados em segundos no máximo. O tempo de consulta do meu banco de dados deve ser sub-segundo. Alto rendimento de dados: eu quero examinar milhões de linhas de dados e contar ou somar algum subconjunto. Espero que isso demore alguns minutos (ou muito mais dependendo da complexidade) para completar. Pense em mais trabalhos em estilo de lote.
Advertências: este é realmente um problema de mapa / redução também. A configuração e processamento de trabalhos M / R leva um pouco de sobrecarga. Há alguns projetos que trabalham agora para se mover para o menor acesso a dados de latência.
Além disso, o HDFS armazena dados em blocos e distribui-los em vários nós. Isso significa que haverá (quase) sempre uma transferência de dados de rede necessária para obter a resposta final e que "diminui" as coisas um pouco, dependendo da taxa de transferência e de vários outros fatores.

No comments:

Post a Comment