Como optimizar procesos de inserción masiva en MongoDB

Mongo DB es un document storage NoSql que tiene una capacidad de escritura muy alta, y realmente la tiene, por mi experiencia mucho más que por ejemplo MySql. Pero cuando empiezas a cargarlo de verdad, con procesos de inserción masiva, del orden de millones de documentos, la cosa ya no va sola, y necesitas empezar a desarrollar de una forma determinada para conseguir que tus procesos sigan yendo a toda pastilla. Aquí te cuento algunos de los que he descubierto a base de leer en algunos casos, y de tortas en otros.

No gestionar las transacciones

Ni se te ocurra gestionar las transacciones en este tipo de procesos. Mongo tiene la virtud de poder “insertar y olvidar”, es decir, de enviar los datos a insertar al servidor, y no esperar ningún tipo de respuesta, ni de confirmación por su parte. Esto lo consigues especificando un WriteConcern.UNACKNOWLEDGED, que quiere decir eso, que no te interesa si la inserción ha ido bien o mal. Eso si, para utilizar esto, ya te tienes que haber preocupado previamente de asegurarte que tus inserciones no van a fallar, sino, mal lo tendrás para poder verificar lo que ha ido bien o mal.

Ejecuta un único save para cada documento, nunca update

El método save es mucho más rápido que el método update, ya que directamente escribe, sin verificar si previamente existe el registro o no. Nunca, repito, nunca desarrolles procesos de inserción masiva que quieras que vayan rápido y que no se degraden al crecer las colecciones en los que hagas uno o varios updates. Nuevamente, en este proceso, tendrás que preocuparte de tener a tu alcance toda la información que quieres guardar para cada documento, júntala durante N procesos e inserta una única vez.

Contra colecciones vacías

El tiempo de inserción en colecciones vacías en Mongo es mas bajo que cuando tiene datos. Plantéate en tu proceso si es posible al inicio del mismo borrar completamente la colección y volver a generarla de nuevo con los datos que vas a insertar. Aunque parezca mentira, en muchos casos puede ser más rápido hacer de nuevo una inserción completa que N parciales.

Contra colecciones sin índices

Si tus colecciones tienen índices, bórralos con dropIndex antes de empezar a insertar, ejecutas, y al finalizar vuelves a crear el indice con ensureIndex. El tiempo de creación del índice global es mucho menor que el tiempo que se tiene que invertir en actualizar el mismo índice ya creado en cada inserción de cada documento.

En colecciones más pequeñas

Trocea tus colecciones, tanto la inserción como la recuperación de datos van a ir más rápidas contra diez colecciones de 2 millones de documentos, que contra una única colección de 20 millones. Además, esto te permitirá paralelizar tus procesos y reducir la duración total.

Utiliza diferentes databases

Es incluso preferible utilizar diferentes databases para datos temporales o que vayas a regenerar por completo en ese ciclo, que diferentes colecciones en la misma base de datos. Esto te permitirá incluso hacer dropDatabase que liberará el espacio en disco que Mongo reserva para la db, cosa que no hace si eliminas la colección.

Y hasta aquí mis pequeños trucos para optimizar la inserción masiva en Mongo. Si tienes algún truco que no haya dicho, no dudes en comentármelo.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s