2011-04-18 49 views
6

Estaba tratando de cargar un poco mi Redis con fines de prueba y averiguar los límites superiores. Primero lo cargué con 50,000 y 100,000 claves de tamaño 32caracteres con valores de alrededor de 32 caracteres. No tomó más de 8-15 segundos en ambos tamaños de llave. Ahora intento poner 4kb de datos como valor para cada clave. Las primeras 10000 claves tardan 800 milisegundos en establecerse. Pero a partir de ese punto, se ralentiza gradualmente y para establecer 50,000 teclas completas, tarda de 40 minutos. Estoy cargando la base de datos usando NodeJs con node_redis (Mranney). ¿Hay algún error que esté cometiendo o Redis es tan lento con grandes valores de tamaño 4 KB?¿Problemas de rendimiento de Redis?

Una cosa más que encontré ahora es cuando ejecuto otro cliente paralelo al actual y actualizo las claves. Este segundo cliente termina cargando las 50000 claves con valores de 4kb en 8 segundos mientras el primer cliente todavía hace lo suyo para siempre. ¿Es un error en el nodo o en la biblioteca redis? Esto es alarmante y no es aceptable para la producción.

+0

¿Estás usando hiredis? – generalhenry

+0

Hmm ... instalé hiredis pero no sé si se carga automáticamente en el programa cuando lo necesito ('redis'). ¿Ese es el problema? – Lalith

+0

Para verificar si tiene el módulo hiredis instalado, puede ejecutar el nodo, y luego 'exigir (" hiredis ")'. –

Respuesta

5

Deberá obtener algún tipo de contrapresión para realizar grabaciones masivas desde el nodo hacia Redis. De forma predeterminada, el nodo pondrá en cola todas las escrituras y no impone un límite superior en el tamaño de la cola de salida.

node_redis tiene un evento "drain" que puede escuchar para implementar una contrapresión rudimentaria.

+0

Hola Matt, traté de mirar client.command_queue.length y parar hasta que aparezca un evento de "drenaje". client.command_queue.length siempre es 0. Así que estaba revisando client.offline_queue.length, que me da el número correcto, pero el evento drain se activa solo una vez. Lo intentaré de nuevo y volveré con el código. Gracias. – Lalith

+0

He adjuntado el código aquí https://gist.github.com/945441. ¿Esta no parece ser la forma correcta de contrapresión? – Lalith

+2

Aquí hay un par de problemas diferentes.El primero es que los comandos de preconexión están en cola. El segundo es que una vez que tienes una conexión, se mantiene otra cola para los comandos enviados pero para los que aún no se ha recibido una respuesta. He agregado un ejemplo de una forma general de tratar ambos casos aquí: https://github.com/mranney/node_redis/blob/master/examples/backpressure_drain.js –

3

La configuración predeterminada de redis no está optimizada para ese tipo de uso. Sospecho que lo tiene intercambiando en el disco con un tamaño de página de 32 bytes, lo que significa que cada clave añadida tiene que encontrar 128 páginas libres contiguas y puede terminar usando la VM del sistema o necesitando expandir mucho el archivo de intercambio.

Cuando actualiza una clave, el espacio ya está asignado, por lo que no ve ningún problema de rendimiento.

+0

Esto es solo para fines de prueba, así que no me importa mucho. ¿Pero qué pasa si tal demanda ocurre en tiempo real y mi aplicación necesita almacenar tanta información? ¿Hay alguna configuración que pueda cambiar para que coincida con mi requisito? – Lalith

+0

También antes de que el primer cliente haya creado todas las 50000 claves. Si ejecuto el segundo cliente, continúa y finaliza antes de la primera. Entonces, lo que dijiste puede no ser el problema que estoy enfrentando. – Lalith

+3

El tamaño de la página y el uso de la memoria son configurables; verifique los comentarios en redis.conf. El segundo cliente finalizado no necesariamente descarta ese escenario: la combinación de condiciones de memoria baja y concurrencia puede volverse bastante compleja, especialmente si se trata de tiempos de espera y reintentos automáticos. Por ejemplo, ¿podría reiniciar todas las teclas anteriores cada vez que se ejecuta un error? –

0

Como estaba haciendo mucho conjunto (valor clave) en NodeJs que se realiza de forma asíncrona, muchas conexiones de socket se abren al mismo tiempo. El búfer de escritura del zócalo NodeJs podría estar sobrecargado y GC podría venir y jugar con el proceso del nodo.

PD: Cambié las configuraciones de memoria de redis como sugirió Tom, pero todavía estaba haciendo lo mismo.

Cuestiones relacionadas