2012-09-06 10 views
14

Tengo una colección con documentos de 10M de 6000 acciones, el nombre de stock está indexado. Cuando me suscribo a una acción nueva, el meteoro se cuelga más de 10 segundos para obtener aproximadamente 3000 documentos de esta acción. También después de que se suscriben varias acciones, el meteoro se cuelga con el uso de 100% de la CPU. Meteor se ve muy lento con la sincronización de la "gran" colección. En realidad, mi aplicación solo es de lectura. Me pregunto si hay forma de acelerar meteoro para cliente de solo lectura. También me pregunto si la creación de una colección separada para cada acción ayuda?La suscripción y la sincronización de Meteor son lentas

Respuesta

7

Si bien este es un problema de escala y, probablemente, se puede mejorar; se debe tener en cuenta que está utilizando la tecnología incorrecta para su tarea, porque Meteor está diseñado para la interacción entre clientes y no para recuperar toneladas de datos confidenciales de solo lectura. Si bien una pantalla de seguimiento del estado aún puede tener algún sentido, los datos críticos en tiempo real en cantidades enormes ciertamente no ...

Toda la pila Meteor introduce una sobrecarga extrema sobre una implementación simple en cualquier pila nativa; Honestamente, incluso tomaría en cuenta los gastos generales que Java o C# introducirían y pensarían dos veces al elegir entre eso y los lenguajes de bajo nivel como PHP y C++. Los lenguajes como Ruby, Python, Node.js y más son realmente una historia diferente; están hechos para la creación rápida de prototipos, pero en términos de latencia/rendimiento están retrasados ​​debido a la sobrecarga que les toma JIT, y no olviden que en el nivel superior se agregan algunos enfoques no nativos para hacer cosas.

TL; DR: Usar las herramientas adecuadas para el trabajo, o tendrá que cortar sus dedos ...

+0

Personalmente me gustaría que esto funcione con ese tipo de carga. La edición de un conjunto de datos de + - 10Mb en el momento no debería ser un problema. el problema actual parece ser que la sincronización de los primeros 4-5Mb es realmente rápida y luego desacelera mucho. – Thierry

+1

Hola Tom, ¡aprecio el trabajo que estás haciendo con win.meteor.com! Con respecto al problema anterior, ¿no se puede gestionar esto en Meteor como se sugiere a continuación? –

+0

@MaxHodges: No dije que "no podía", dije que simplemente estaba "mal"; puede obtener bastante rendimiento si utiliza la tecnología de la manera correcta, pero no puede alcanzar el rendimiento que los idiomas de bajo nivel pueden ofrecerle. Si puede permitirse el ligero retraso en los datos, ¿por qué no? pero una vez que llegas a tiempo, vida y dinero, cosas críticas que realmente necesitas reconsiderar ... –

1

Me encanta la sencillez de meteoritos. Simplemente dejo de usar la colección local de mongodb para evitar la sobrecarga de la sincronización, el rendimiento se ve realmente bien.

Meteor.default_connection.registerStore "prices", 
    beginUpdate: -> 
    update: (msg) -> 
    updateChart(msg.set) 
    endUpdate: -> 
    reset: -> 

para meteorito nuevo, debajo funciona.

Meteor.default_connection.registerStore collection, 
    constructor: (@update) -> 
    # Called at the beginning of a batch of updates. 
    beginUpdate: -> 
    update: (msg) -> 
     update(msg.fields, msg.id) if msg.fields 
    endUpdate: -> 
    reset: -> 
13

Meteor empuja todo el conjunto de datos a su cliente.

Puede desactivar PUBLIAUTO eliminando el paquete PUBLIAUTO:

meteor remove autopublish

A continuación, cree una suscripción específica específica para su cliente.

Cuando se suscribe puede pasar una variable de sesión como un argumento, por lo que en el cliente haces algo como:

sub = new Meteor.autosubscribe(function(){ Meteor.subscribe('channelname', getSession('filterval')); }

En el servidor utiliza el argumento para filtrar el conjunto de resultados enviado a la cliente, para que no esté canalizando todo a la vez. Segmentas los datos de alguna manera usando un filtro.

Meteor.publish('channelname', function(filter){ return Collection.find({field: filter}); }

Ahora, cada vez que cambie el filterval en el cliente utilizando setSession('filterval', 'newvalue'); la suscripción se cambiará automáticamente y el nuevo conjunto de datos se envía al cliente.

Puede utilizar esto como un medio para controlar la cantidad y la información que se envía al cliente.

Como dijo otro afiche, realmente tiene que preguntar si esta es la mejor herramienta para este trabajo.Meteor está diseñado para conjuntos de datos relativamente pequeños que se actualizan en tiempo real en (potencialmente) dos direcciones. Está muy optimizado y tiene una tonelada de andamios para ese caso de uso.

Para otro caso de uso (como el gran conjunto de datos de solo lectura) puede no tener sentido. Tiene una gran cantidad de gastos generales que proporciona funciones que no utilizará, y estará codificando para obtener la funcionalidad que necesita.

1

Con autopublish habilitado, es posible que vea un golpe de rendimiento con grandes colecciones de documentos en Mongodb. Puede solucionar esto eliminando autopublish y escribiendo código para publicar solo los datos relevantes en lugar de toda la base de datos.

Los documentos también entran en la gestión de la memoria caché de forma manual:

clientes sofisticados pueden activar las suscripciones de encendido y apagado para controlar la forma en datos mucho se guarda en la memoria caché y gestionar el tráfico de red. Cuando se desactiva una suscripción , todos sus documentos se eliminan de la memoria caché , a menos que el mismo documento también sea provisto por otra suscripción activa .

Se están trabajando en mejoras de rendimiento adicionales para Meteor, incluyendo un proxy de nivel DDP para admitir "un gran número de clientes". Puede ver más detalles sobre esto en Meteor roadmap.

12

Estaba luchando con el mismo problema. En mi caso, solo tuve que sincronizar ~ 3000 registros, alrededor de 30 KB en total. Después de semanas de intentarlo, finalmente me di cuenta de que la sincronización no era el problema, sino las actualizaciones de LiveHTML que ocurrieron durante la sincronización.

Pude reducir la carga de mi página de 10 segundos para 300 registros (filtrados) a menos de 2 segundos para los 3000 registros al deshabilitar las actualizaciones de la plantilla durante la carga de la página inicial. He logrado que mediante la adición de una condición a la función que define el contenido de la plantilla:

Antes de (10s carga de la página para 300 registros que se publicó por el servidor):

Template.itemlist.items = function() { 
    return Item.find({type: 'car'}, 
        {sort: {start: -1}, 
         limit: 30}); 
}; 

Para (carga de la página 2s para 3000 registros publicadas por el servidor):

Template.itemlist.items = function() { 
    if (Session.get("active")) {  
     return Item.find({type: 'car'}, 
         {sort: {start: -1}, 
          limit: 30}); 
    } else { 
     return []; 
    } 
}; 

para "activar" la sesión sólo una vez los datos se cargó, añadí:

Deps.autorun(function() { 
    Meteor.subscribe("Item", 
        { 
         onReady: function() { 
          Session.set("active", true); 
         } 
        }); 
}); 
+0

Gracias! Yo estaba teniendo el mismo problema. – pcorey

+0

¡Buen consejo! Gracias. –

+0

gracias, funciona. 44 000 registros en + -20s y sin ningún bloqueo contrario a antes. Es mejor que nada, pero aún es largo ... –

Cuestiones relacionadas