MongoDB - Buenas prácticas

MongoDB


Esté artículo en Inglés.

MongoDB es una una base de datos ágil que, gracias a su flexibilidad de cambiar los esquemas de los documentos, nos brinda productividad, así como también escalabilidad, rendimiento y disponibilidad por su arquitectura y opciones que brinda a la hora de configurar un clúster.

Modelado de datos

La decisión entre qué datos debe estar normalizado y desnormalizado es importante, por eso se debe tomar un tiempo en pensar la forma que más se adecue a nuestras necesidades. Hay variedad de estrategias de modelado que se pueden usar para leer y escribir nuestros datos, tanto normalizados como desnormalizados, como: uno a pocos o uno a muchos.

Un ejemplo de uno a pocos, pueden ser los números de teléfono de un contacto, donde es posible embeberlo directamente en el documento al que pertenece permitiendo editarlo y acceder a él en una sola llamada:

{
  name: 'Peter Pan',
  ssn: '456-123-0987',
  numbers: [
    {name: 'Personal', number: '918-876-5199'},
    {name: 'Home', number: '417-789-9995'}
  ]
}

Por otro lado, en el caso de uno a muchos, se pueden tener unos cientos o máximo miles de un objeto relacionado a un solo objeto. Podemos ver como ejemplo la factura de compra de un mini-market, donde se tiene una colección de productos con un identificador único y otra colección con las facturas de compra, donde tenemos:

Cada producto compuesto de la siguiente manera:

{
  _id: ObjectId('AAAA'),
  number: 123,
  name: 'Milk 1 lt',
  price: 0.97
  qty: 2
}

Y cada factura de compra como sigue:

{
  date: '2016-11-24T22:43:03.288Z',
  total: 39.64,
  tax: 9.70,
  products: [
    ObjectId('AAAA'),
    ObjectId('AABB'),
    // etc
  ]
}

Podríamos obtener toda la información en dos consultas, realizando un "join" a nivel de aplicación:

invoice = db.invoices.findOne({number: 123});
invoice_products = db.products.find({_id: {$in: invoice.products}}).toArray()    

Agregar indices

Agregar índices permite que las operaciones de búsqueda se realicen mucho más rápido. Se debe tener en cuenta que solo se usa un índice por consulta, así como que el hecho de tener muchos índices tampoco beneficia, por lo que siempre es bueno analizar el comportamiento de los datos.

Por defecto Mongo crea un índice único para el campo ‘_id’ durante la creación de la colección, esto previene la inserción de dos documentos con el mismo valor en el campo ‘_id’.

Para crear un índice se ejecuta la siguiente sentencia:

db.collection_name.createindex({fieldName: 1})

Donde collection_name es el nombre de la colección y esto nos permite realizar consultas mas eficientes usando el campo fieldName.

Usar conjuntos de réplicas

Los conjuntos de réplicas permiten una alta disponibilidad mediante la conmutación por error, esto quiere decir que si el nodo primario fallase, se elegirá otro nodo como primario y así todo seguirá funcionando sin interrupciones. Hay que tener en cuenta que los conjuntos de réplicas no son copias de respaldo. La razón es que una réplica no se puede proteger del error humano, por ejemplo, el borrar una colección de datos accidentalmente o desplegar una versión errónea de una aplicación.

Siempre respaldar tus datos

Todos conocemos la importancia de respaldar los datos, cuando se despliega a producción se debe tener una estrategia para respaldar y restaurar las copias de seguridad para cualquier tipo de eventualidad, como pérdida de datos. Con una cantidad de datos pequeña y una instancia de Mongo se pueden usar un par de utilidades que brinda Mongo, mongodump y mongorestore.

La primera permite "exportar" una base de datos, una colección o una consulta:

$ mongodump --host localhost:27017 --db database_name --out /home/user/database_name

El ejemplo anterior realizaría un respaldo de la base de datos database_name en la ruta /home/user/database_name que sería una carpeta con archivos BSON para el respaldo realizado.

Para restaurar una respaldo se debe usar mongorestore:

$ mongorestore --host localhost:27017 --drop --db database_name /home/user/database_name

El comando anterior restaurará el respaldo ubicado en /home/user/database_name en la base de datos database_name y la opcion ‘--drop’ le indica que debe eliminar la base de datos antes de resturarla.

Usar la versión estable más reciente

La tecnología avanza a pasos agigantados, estar al tanto de las nuevas versiones nos permite aprovechar de nuevas funcionalidades, mejoras en el rendimiento y facilidad de uso. Al momento de escribir esta entrada, la versión estable más reciente es 3.2.11. Es recomendable ir al centro de descargas oficial [https://www.mongodb.com/download-center] o usar el gestor de paquetes de el sistema operativo.

Evitar usar MongoDB en sistemas de 32 bits

MongoDB limita sus procesos a unos 2 GB de datos, aunque esto no supone mayor problema hoy en día ya que es bastante común disponer de sistemas de 64 bits.

Seguridad

Restringir quién o qué puede acceder a la información almacenada es vital. Por defecto MongoDB no incluye seguridad pero sí brinda la forma de asegurar el acceso a la información dentro de las cuales incluye Autenticación, Autorización, Encriptación del transporte. Es bueno tener una lista de chequeo de seguridad antes de desplegar a producción. A continuación se listan y describen algunos puntos importantes:

  • Habilitar el acceso de control y forzar la autenticación. Por ejemplo, se puede usar el mecanismo que incluye Mongo para forzar a que se provean credenciales válidas si se desea acceder o modificar a la información en la base de datos.

  • Configurar control de acceso basado en roles, basado en las necesidades de la aplicación o sistema. Se pueden definir roles que puedan realizar ciertas operaciones, como por ejemplo, un usuario de solo consulta.

  • Encriptar la comunicación: si MongoDB debe expuesto de manera que haya comunicación entre aplicaciones que se encuentran en diferentes hosts al que se encuentra alojado MongoDB, encriptar todo el tráfico saliente y entrante usando TLS/SSL asegura que ningún tercero pueda acceder a la información sin su consentimiento.

  • Limitar la exposición a la red: permitir funcionar Mongo únicamente en redes de confianza como redes privadas o, mejor aún, si su aplicación se encuentra en el mismo host que MongoDB, puede ser limitado a solo acceso local.

  • Ejecutar MongoDB con un usuario dedicado: permitir a los procesos de MongoDB ejecutarse con un usuario dedicado que no tenga permisos innecesarios.

Existen otras muchas buenas prácticas a seguir que las mencionadas, siempre es bueno tenerlas presentes cuando planeamos realizar un despliegue a producción, manteniendo listas de chequeo para la buena salud de nuestras aplicaciones durante su ciclo de vida.