Ao otimizar as publicações de meteoros · @radekmie a opinião e outras coisas

Ao otimizar as publicações de meteoros · @radekmie a opinião e outras coisas


Ao otimizar as publicações de meteoros · @radekmie a opinião e outras coisas

@radekmie

Por Radosław Miernik · Publicar em · Comente no fórum de meteoros, reddit

Índice

Introdução

Fazer um servidor fazer menos trabalho geralmente é uma coisa boa. É por isso que a maioria, se não todas, as implantações de meteoros em larga escala cultofcoders:redis-oplog. Hoje, nos concentraremos no ajuste fino deste pacote. Se você quiser saber o porquê, vá em frente e leia Na substituição do Oplog em Meteor primeiro.

Nosso objetivo é reduzir o número de eventos que uma instância de meteoro deve processar. Isso pode ser feito com canais e namespaces personalizados (que são baseados em canais personalizados de qualquer maneira). A ideia é simples: em vez de ser notificado em todo Mudança na coleção, gostaríamos de reduzi -la ao publicado Somente documentos.

É perfeitamente factível apenas com mudanças no aplicativo, embora você precise configurar ambos em todas as publicações, que é factível… Mas você precisaria configurá -lo em cada insert/remove/updatetambém.

E como eu sou bastante preguiçoso um fã de soluções automatizadas, agora é implementado em changestream-to-redis através do NAMESPACES opção.

Como usá -lo

Como esta solução é aplicável a praticamente todas as suas publicações, vamos começar com as mudanças no aplicativo primeiro. Vamos configurar um único namespace Com base no campo, estamos consultando os documentos. Aqui está um exemplo:

 Meteor.publish('myTasks', function () {
   // Some authorization logic here...
-  return Tasks.find({ userId: this.userId });
+  return Tasks.find({ userId: this.userId }, {
+    namespace: `userId::${this.userId}`,
+  });
 });

Sem mais alterações, esta publicação enviará apenas o estado inicial e nada mais. Agora, nós poderia Altere todas as operações de mutação da seguinte forma:

-Tasks.insert(task);
+Tasks.insert(task, { namespace: `userId::${task.userId}` });

Em vez disso, poderíamos configurar changestream-to-redis Para gerar todas essas mensagens de nome do nome automaticamente; É tão fácil quanto adicionar uma variável ambiental NAMESPACES=tasks.userId (onde tasks é o nome da coleção e userId é o nome do campo).

Ele também funciona se o campo que você está consultando for uma matriz ou objeto! As matrizes publicam uma mensagem de namespaced para cada elemento e os objetos publicam um para cada chave. Isso significa que as consultas a seguir também funcionam:

 Meteor.publish('projectsByScope', function (scope) {
   // Some authorization logic here...
-  return Projects.find({ scopes: scope });
+  return Projects.find({ scopes: scope }, {
+    namespace: `scopes::${scope}`
+  });
 });

 Meteor.publish('groupsByRole', function (role) {
   // Some authorization logic here...
-  return Groups.find({ (`roles.${role}`): { $exists: true } });
+  return Groups.find({ (`roles.${role}`): { $exists: true } }, {
+    namespace: `roles::${role}`
+  });
 });

A configuração permanece simples: NAMESPACES=groups.roles,projects.scopes.

E, finalmente, se você está consultando por vários campos, cabe a você decidir qual deles usar. Como regra geral, é melhor usar o mais seletivo, ou seja, aquele que resulta em menos documentos quando consultado sozinho.

Implementação

Sob o capô, changestream-to-redis solicitará os documentos completos das coleções selecionadas para gerar as mensagens com base nos valores (origem) de seus campos. No entanto, como o delete Os eventos de mudança não incluem documentos completos, também solicita as pré-imagens.

Agora, como pode significativamente aumentar o número de mensagens levadas para Redis, considere aumentar REDIS_BATCH_SIZE. Estamos aos 100 agora, e a latência média permanece em 10 milissegundos estáveis. (Você pode rastrear a latência usando as métricas de Prometheus expostas com METRICS_ADDRESS.) Pelo mesmo motivo, monitore a RAM da sua instância Redis. No nosso caso, aumentou cerca de 20 megabytes (definitivamente não muito, mas não insignificante).

Resultados

Lançamos todas as mudanças de publicação em uma semana, liberando um pequeno lote todos os dias. No total, mudamos cerca de 40 publicações e 200 linhas, incluindo a configuração de infraestrutura necessária.

E os resultados? Eu acho que eles são loucamente bom! Em três dias, o número de documentos buscados caiu de mais de 453 para cerca de 35 milhões – quase 93% menos. Mais importante, porém, o número de notificações do Oplog caiu de mais de 306 para menos de 1,5 milhão – mais de 99,5% menos!

Métricas de publicação antes

Ao otimizar as publicações de meteoros · @radekmie a opinião e outras coisas

Métricas de publicação depois

Métricas de publicação depois

Você deve ter notado que o número de alterações do observador (ou seja, alterações empurradas para o cliente) também aumentou ligeiramente (aproximadamente 28%). Desde que mudamos apenas o número de servidor notificações e o tráfego permaneceu estável, o número de mudanças deve permanecer o mesmo também.

Essa mudança é realmente desejável! Devido a um número muito alto de gravações em algumas coleções, tivemos que mudar para a pesquisa (disableOplog). Com publicações para o nome, fomos capazes de tornar essas publicações em tempo real novamente.

Pensamentos finais

Embora essas otimizações sejam raras, elas são uma bênção. Realmente, com que frequência você pode gastar menos de um dia para cortar qualquer métrica relacionada ao banco de dados em 200x? Claro, revisar índices e ajustar a configuração é uma coisa, mas é isso.

Deixe -me saber o quanto isso ajudou seu aplicativo de meteoros!

Sobre a reificação de fechamentos aninhados no perfeccionismo de Ruston em dados



Source link

Postagens Similares

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *