AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 187571
Accepted
Jonathan Fite
Jonathan Fite
Asked: 2017-10-04 13:28:38 +0800 CST2017-10-04 13:28:38 +0800 CST 2017-10-04 13:28:38 +0800 CST

Service Broker - Vida útil da conversa?

  • 772

Estamos tentando fazer com que o Service Broker trabalhe em nosso ambiente para resolver um caso de negócios. Não sei se o título da mensagem é bom, mas minha dúvida está abaixo. Mas pode não ser uma boa pergunta, então depois disso é o que estamos fazendo e porque eu acho que é a pergunta certa.

Quantas mensagens devem ser enviadas em uma conversa antes de encerrar a conversa?

Queremos usar o Service Broker para atualizar de forma assíncrona uma tabela de resultados. A tabela de resultados é achatada e rápida. Temos triggers nas tabelas base que enviam uma mensagem com sua tabela e chave primária. Temos três filas:

  • Baixa latência - o objetivo é de 15 segundos para processar. Ele lida com itens que mudam em relação a um item específico.
  • Fila em massa - o objetivo é de 5 minutos para processar. Ele lida quando algo muda que afeta muitas centenas (ou milhares) de itens. Ele divide a lista de itens que foram afetados e os alimenta na Fila de baixa latência adiada.
  • Baixa latência diferida - o objetivo é de 30 minutos para processar. Isso processa itens, mas apenas da fila em massa.

Basicamente, se as informações de um cliente forem atualizadas, isso afetará muitos produtos, então isso será enviado para a fila em massa para um processamento mais lento. No entanto, se um produto for atualizado, ele será enviado para a fila de baixa latência.

Reutilizamos conversas semelhantes ao blog de Remus Rusanu http://rusanu.com/2007/04/25/reusing-conversations/ , com a exceção de que fazemos isso com base no módulo da chave primária. Isso tem o benefício colateral de ajudar na desduplicação de chaves primárias.

Então, estamos reutilizando as conversas e estamos dentro das nossas diretrizes. Com dois threads, consegui gravar 125 mensagens/segundo (queda artificial de vários milhares de mensagens), o que é mais do que capaz de acompanhar a produção (est. 15 mensagens/s).

No entanto, o problema que estamos enfrentando é que, após um período de tempo, ~4 horas ou 120 mil mensagens, começamos a ver blocos e alta contenção no sysdesend e na tabela de filas. As fechaduras são LCK_M_U e são fechaduras KEY. Às vezes, o hobt resolve para sysdesend e outras vezes para a tabela de fila específica (queue_).

Temos um processo em vigor que encerrará as conversas após 24 horas ou 30 minutos de inatividade, podemos apenas aumentar o tempo antes de alternar entre as conversas.

Estamos usando o SQL 2016 Enterprise (13.0.4001.0)

  1. Disparar Incêndios (enviar para baixa latência ou em massa)
  2. Procure ou crie um identificador de conversa.
  3. Enviar mensagem
  4. Procedimento ativado em fila
  5. Atualizar tabela de resultados

O processo de limpeza é executado a cada 10 minutos para ver se há conversas ociosas. ltd os encontra mais de três vezes seguidas, marca-os como inativos e encerra as conversas.

Por favor, deixe-me saber se há quaisquer detalhes adicionais que possam ser benéficos. Não tenho muita experiência com Service Broker, então não sei se nossas mensagens/s são baixas, altas ou indiferentes.

ATUALIZAR

Então, tentamos novamente hoje e encontramos o mesmo problema. Alteramos a vida útil da conversa para 2 horas e isso não teve efeito. Então, implementamos o truque 150, que apresentava o mesmo problema.

Toneladas de espera em SEND CONVERSATION, aguardando sysdesend. Alguém tem mais alguma ideia?

ATUALIZAÇÃO 2

Executamos o teste por mais tempo hoje e, em um dos períodos de amostra de 17 minutos, processamos 41 mil mensagens em 4 identificadores de conversa. Conseguimos acompanhar, exceto no final, quando os bloqueios no sysdesend e na tabela de filas se tornaram demais, e começamos a ficar para trás antes de pará-lo. Parece que não temos problemas para processar mensagens, sem que as coisas entrem na fila: podemos retirá-las e processá-las pelo menos 5x essa velocidade. Nossa velocidade parece ser limitada com base na adição de mensagens.

Em um teste posterior, removemos um dos gatilhos que representavam 80% das mensagens. Mesmo com essa carga muito reduzida, começamos a ver as mesmas esperas.

ATUALIZAÇÃO 3

Obrigado, Remus, pelo seu conselho (e obrigado por postar artigos tão excelentes no blog sobre o assunto, eles foram fundamentais para chegar a este ponto).

Corremos de novo hoje e nos saímos melhor (já que passamos mais tempo antes de ver as esperas e ainda mais antes de nos aleijar). Então, os detalhes.

Nós mudamos:

  • Aumentou o número de conversas mantidas por thread de 1:1 para 2:1. Basicamente, tínhamos 8 identificadores de conversa para 4 threads.

  • consolidou a fila em massa (porque uma mensagem de entrada pode significar centenas de mensagens de saída) para consolidar em menos mensagens maiores.

Observações sobre esta tentativa:

  • desabilitando o procedimento de ativação da fila de destino. nenhuma alteração no bloqueio (esperamos 5 minutos) e as mensagens foram enviadas para sys.transmission_queues.

  • monitorando sys.conversation_endpoints. Esse número passou de 0 a 13K muito rapidamente e depois aumentou mais lentamente ao longo do dia, terminando em cerca de 25K após ~ 5 horas. O bloqueio não começou a ocorrer até atingir 16K+/-

  • Entrei no DAC e executei os comandos DBREINDEX para as filas, embora a partir de uma consulta, os registros fantasmas nunca tenham ficado acima de 200 ou mais antes da limpeza chegar e reduzir a contagem para 0.

  • sysdesend e sysdercv tinham contagens idênticas de 24.932 quando terminei o teste.

  • processamos ~310 mil mensagens em 5 horas.

Fomos tão longe antes que as coisas desmoronassem que eu realmente pensei que conseguiríamos desta vez. Amanhã tentaremos forçar as mensagens a passarem pelo fio.

sql-server sql-server-2016
  • 1 1 respostas
  • 2123 Views

1 respostas

  • Voted
  1. Best Answer
    Jonathan Fite
    2017-10-11T04:36:28+08:002017-10-11T04:36:28+08:00

    Eu sei que é indelicado responder sua própria pergunta, mas eu queria encerrar isso para quem estiver interessado. Finalmente conseguimos resolver o problema, ou pelo menos resolvê-lo o suficiente para atender aos nossos requisitos. Quero agradecer a todos que contribuíram com comentários; Remus Rusanu e Kin, pois foram muito úteis.

    Nosso banco de dados está bastante ocupado e está no modo RCSI. Temos vários (milhares) de dispositivos móveis que atualizam suas informações de localização a cada 45 segundos. Por meio dessas atualizações, várias tabelas obtêm suas informações atualizadas (design ruim, pois eu teria limitado as informações voláteis a uma única tabela e depois as juntaria para obter os resultados). Essas tabelas são as mesmas para as quais estávamos tentando gerar informações de relatório de forma assíncrona, em vez de fazer com que os usuários finais fossem diretamente nas tabelas base.

    Inicialmente, tínhamos os gatilhos fazendo um cursor sobre os registros modificados em cada instrução de atualização/inserção (deveria ter uma linha na maioria dos casos) e enviando cada chave primária em uma mensagem para o agente de serviço. Dentro do service broker, especialmente a fila em massa, havia outros cursores que executavam o procedimento upsert para o relatório (uma execução por chave primária).

    O que finalmente nos fez trabalhar:

    • Removemos os cursores e decidimos enviar mensagens maiores. Ainda uma mensagem por transação de usuário por tabela, mas agora enviamos mensagens com mais de uma chave primária.

    • O processador em massa também envia várias chaves por mensagem, o que reduziu o número de CONVERSAÇÕES DE ENVIO que estavam acontecendo enquanto ele embaralhava as mensagens para a outra fila conforme apropriado.

    • A tabela mais volátil (nossa tabela de dados do dispositivo móvel) teve seus gatilhos removidos. Atualizamos o procedimento upsert para incluir as chaves estrangeiras apropriadas e agora apenas nos juntamos novamente a essa tabela ao buscar resultados para os usuários. Essa tabela contribuiu facilmente com 80% das mensagens que tivemos que processar em um dia.

    Processamos cerca de 1 milhão de mensagens por dia (sem a tabela Mobile) e a grande maioria (99%+) de nossas mensagens são processadas dentro do nosso objetivo. Ainda temos o outlier ocasional, mas dada a natureza rara do que é considerado aceitável.

    Fatores contribuintes:

    • Encontrei um bug no procedimento de limpeza de conversa mencionado anteriormente que não estava realmente limpando as conversas adequadamente e encerrando-as prematuramente. Isso agora resultou em nossa contagem de sysdesends para nunca ser mais do que alguns milhares (a maior parte vem do uso do truque de 150).

    • Os cursores nos gatilhos pareciam ter mais travamento do que o previsto (mesmo com estático, somente para frente). removê-los parece ter tornado os bloqueios que vemos em SEND CONVERSATION mais transitórios por natureza (ou pelo menos as vezes que vemos são muito menores).

    • Estávamos essencialmente executando duas soluções lado a lado (o back-end da solução Service Broker (para testar sob carga de produção)) e a solução atual (consulta terrível que abrange muitas tabelas).

    Como um benefício colateral, isso descobriu um problema de limpeza de registro fantasma e, embora não estivesse nas tabelas do Service Broker (sistema ou fila), é bastante desenfreado em nosso sistema e os sintomas se alinham muito bem com nossa "sem causa clara" problemas que experimentamos às vezes. A investigação está em andamento sobre isso, estamos tentando encontrar as tabelas que estão contribuindo para isso e provavelmente reconstruiremos seus índices rotineiramente.

    Agradeço novamente.

    *** ATUALIZAÇÃO 2021 ***

    Eu tenho outro upvote sobre isso, então eu queria voltar e revisitar. Acabamos abandonando o Service Broker logo depois que fiz essa pergunta, pois nossa carga de trabalho de transações ainda era muito alta/rápida para funcionar com eficiência. Eventualmente, mudamos para esse estilo de fila para nosso sistema de mensagens de alto rendimento e funciona muito bem.

    http://kejser.org/implementing-message-queues-in-relational-databases/

    • 4

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve