Share via


Este artículo proviene de un motor de traducción automática.

Pronóstico: nublado

Windows Azure descomunal

Joseph Fultz

 

Joseph FultzPersonalmente, me encanta la manera que el ciclo de las cosas. Siempre me parece que cada evolución de un objeto o un mecanismo expresa una dualidad de propósito que avanza y reitera una posición del pasado. La tecnología es un gran lugar para ver esto, porque el ritmo en que cambios han tenido lugar hace que sea fácil de ver a un montón de evoluciones durante cortos períodos de tiempo.

Para mí, el movimiento NoSQL es una evolución de ese tipo. Al principio teníamos documentos y les guardamos en archivos y en el archivador y, eventualmente, en recursos compartidos de archivos. Era un estado natural de asuntos. El problema con la naturaleza es que a escala realmente no podemos envolver nuestros cerebros alrededor de ella. Para racionalizar el contenido y optaron por modelos de datos normalizados y racionalizado que previsiblemente nos ayudaría a consumir espacio, almacenar los datos, los datos de índice y poder encontrarlo. El problema con modelos racionales es que no son naturales.

Entrar en NoSQL, una aparente mezcla de los modelos relacionales y naturales. NoSQL es un sistema de gestión de base de datos optimizado para almacenar y recuperar grandes cantidades de datos. Es una manera para nosotros de mantener estilo documento datos y todavía aprovechar algunas características encontradas en los sistemas de la gestión cotidiana de base de datos relacional (RDBMSes).

Una de las principales herramientas de NoSQL es MongoDB de 10gen Inc., una fuente abierta, orientada en el documento sistema de base de datos NoSQL, y este mes voy a centrar en algunos de los aspectos de diseño e implementación del uso de MongoDB en un entorno de Windows Azure. Voy a asumir que sabes algo sobre NoSQL y MongoDB. Si no, puede que desee echar un vistazo a la columna de puntos de datos de noviembre de 2011 de Julie Lerman, "qué diablos son bases de datos de documento?" (MSDN.Microsoft.com/Magazine/hh547103), y Ted Neward mayo 2010 columna del programador trabajando, "Va NoSQL con MongoDB" (msdn.microsoft.com/magazine/ee310029).

Lo primero es lo primero

Si estás pensando en probar MongoDB o considerarlo como una alternativa a Windows Azure tablas o base de datos SQL de Windows Azure, necesita ser consciente de algunas cuestiones sobre el diseño y planificación de lado, algunos relacionados con la infraestructura y algunos en desarrollo.

Arquitectura de implementación

Generalmente, los datos de vuelta fin debe estar disponible y duradera. Para hacer esto con MongoDB, utiliza un conjunto de replicación. Conjuntos de replicación proporcionan failover y replicación, utilizando un poco de inteligencia artificial (IA) para resolver cualquier empate en la elección del nodo principal del conjunto. Para sus funciones de Windows Azure, esto significa que usted necesitará tres instancias para configurar un conjunto mínimo de replicación, además de una ubicación de almacenamiento que se puede asignar a una unidad para cada uno de esos roles. Tenga en cuenta que debido a las diferencias en máquinas virtuales (VMs), probablemente querrá tener al menos tamaño medianas VMs para cualquier implementación significativa. De lo contrario, la memoria o CPU podría convertirse rápidamente en un cuello de botella.

Figura 1 muestra una arquitectura típica para implementar una MongoDB ReplicaSet mínima que no esté expuesto al público. Podría convertirlo para exponer externamente el almacén de datos, pero es mejor hacerlo a través de una capa de servicio. Uno de los problemas que MongoDB puede ayudar a enfrentar a través de sus características integradas es diseñar e implementar una arquitectura de datos distribuidos. MongoDB tiene una función completa para apoyar sharding; combinar esa característica con ReplicaSets y Windows Azure Compute y tienes un almacén de datos que es altamente escalable, distribuidos y confiable. Para ayudarle a comenzar, 10gen ofrece una solución de muestra que establece un mínimo ReplicaSet. Encontrará la información en bit.ly/NZROWJ y usted puede agarrar los archivos desde GitHub en bit.ly/L6cqMF.

Windows Azure MongoDB Deployment
Figura 1 Windows Azure MongoDB implementación

Esquema de datos

Siendo un wiz en diseño de esquema de DB puede realmente obstaculizar le al diseñar un enfoque NoSQL. Las habilidades requeridas son más como objeto diseño modelado e integración de las infraestructuras de mensajería. Hay dos razones para esto:

  1. Los datos se ve como un documento y contiene a veces objetos anidados o documentos.
  2. Hay apoyo mínimo para las uniones, por lo que tienes que equilibrar el formato de almacenamiento de los datos contra las consecuencias de anidamiento y el número de llamadas que el cliente tiene que hacer para obtener una vista única.

Una de las primeras actividades de pasar de una mentalidad relacional a la perspectiva del documento MongoDB es rediseñar el esquema de datos. Para algunos de los objetos que están separados en un modelo relacional, se mantiene la separación. Por ejemplo, productos y pedidos serán siendo esquema separado de MongoDB y todavía utilizará una clave externa para hacer búsquedas entre los dos. Simplificar un poco, el rediseño de estos dos objetos entre sí es principalmente directo, como se muestra en la figura 2.

Direct Schema Translation
Figura 2 traducción directa de esquema

Sin embargo, no puede ser tan fácil cuando trabajas con esquemas que no son tan limpiamente separadas conceptualmente, aunque pueden ser fácilmente y obviamente separadas en un modelo relacional. Por ejemplo, los clientes y CustomerAddresses son entidades que se pueden combinar tal que cliente contendrá una colección de direcciones asociadas (véase figura 3).

Converting Relational Schema to Nested Object Schema
Figura 3 convertir esquema relacional al esquema de objetos anidados

Deberás tomar una mirada cuidadosa a su modelo relacional y considerar cada relación de clave externa y forma que se obtenga representados en el gráfico de la entidad como se traduce al modelo NoSQL.

Interacción de datos

Tanto comportamiento de consulta y almacenamiento en caché de comportamiento son importantes en un sistema relacional, pero es caché de comportamiento que sigue siendo más importante aquí. Tanto como con Windows Azure tablas, es fácil dejar caer un objeto en MongoDB. Y a diferencia de Windows Azure tablas y más como bases de datos de SQL Windows Azure, cualquiera de los campos pueden ser indexado, lo que permite una mejor rendimiento de las consultas sobre objetos individuales. Sin embargo, la falta de uniones (y falta de expresividad de consulta general) vueltas una vez lo que podría ser una consulta con uno o más se une a un gruesos datos de retorno dentro de varias llamadas al almacén de datos de back-end para recuperar los datos de la mismos. Esto puede ser un poco desalentador si desea obtener una colección de objetos y luego buscar una colección relacionada para cada elemento de la primera colección. Así, con mi base de datos relacional de pubs, podría escribir una consulta SQL que se ve algo como lo siguiente para recuperar todos los apellidos de autor y todos los títulos de cada autor:

    Select authors.au_lname, authors.au_id,
      titles.title_id, titles.title
    From authors inner join titleauthor
      on authors.au_id = titleauthor.au_id
      inner join titles on
      titles.title_id = titleauthor.title_id
    Order By authors.au_lname

En contraste, para obtener los mismos datos utilizando el controlador de C# y MongoDB, el código parece que se muestra en figura 4.

Figura 4 unirse a las colecciones de MongoDB

MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
MongoCollection<BsonDocument> authorsCollection =
  mongoPubs.GetCollection("Authors");
MongoCursor<BsonDocument> authors = authorsCollection.FindAll();
string auIdQueryString = default(string);           
Dictionary<string,BsonDocument> authorTitles =
  new Dictionary<string,BsonDocument>();
// Build string for "In" comparison
// Build list of author documents, add titles next
foreach (BsonDocument bsonAuthor in authors)
{
  auIdQueryString = bsonAuthor["au_id"].ToString() + ",";
  authorTitles.Add(bsonAuthor["au_id"].ToString(), 
    new BsonDocument{{"au_id",
    bsonAuthor["au_id"].ToString()},
   {"au_lname", bsonAuthor["au_lname"]}});
   authorTitles.Add("titles",
   new BsonDocument(new Dictionary<string,object>()));
}
// Adjust last character
auIdQueryString = auIdQueryString.Remove(auIdQueryString.Length-1,1);
// Create query
QueryComplete titleByAu_idQuery = Query.In("au_id", auIdQueryString);
Dictionary<string, BsonDocument> bsonTitlesToAdd =
  new Dictionary<string,BsonDocument>();
// Execute query, coalesce authors and titles
foreach (BsonDocument bsonTitle in 
  authorsCollection.Find(titleByAu_idQuery))
{
  Debug.WriteLine(bsonTitle.ToJson());
  // Add to author BsonDocument
  BsonDocument authorTitlesDoc = 
    authorTitles[bsonTitle["au_id"].ToString()];
  ((IDictionary<string, object>) authorTitlesDoc["titles"]).Add(bsonTitle["title_id"].ToString(), 
      bsonTitle);
}

Hay maneras esto puede optimizar a través de código y estructura, pero no se pierda el punto que mientras MongoDB es adecuado para consultas directas incluso en objetos anidados, consultas más complejas que requieren conjuntos de entidades de la Cruz son un buen bit más... bueno, digamos más manual. La mayoría de nosotros utiliza LINQ para Mundial de puente el objeto a relacional. Lo interesante con MongoDB es que querrá ese puente, pero por la razón opuesta — se perderá la funcionalidad relacional.

También podría perderse restricciones referenciales, especialmente las restricciones foreign key. Porque literalmente nada puede agregar a la colección de MongoDB, un elemento puede o no tener los datos adecuados para relacionarlo con otras entidades. Mientras esto puede parecer un defecto de la plataforma si eres un fan empedernido de RDBMS, no lo es. De hecho, es un punto de partida en la filosofía. Para bases de datos NoSQL en general, la idea es mover la inteligencia en el sistema de almacén de datos y dejar que los datos a almacenar el enfoque en la lectura y escritura de datos. Por lo tanto, si usted siente la necesidad de aplicar explícitamente las cosas como las restricciones foreign key en la implementación de MongoDB, todo lo que tienda a través del negocio o la capa de servicio que se encuentra en la parte delantera de los datos.

La migración

Una vez que ha rediseñado los esquemas de datos y considera el comportamiento de la consulta y los requisitos es el momento de obtener algunos datos que hay en la nube para trabajar con él.

La mala noticia es que no hay ningún asistente que le permite apuntar a su instancia de base de datos SQL de Windows Azure y su instancia de MongoDB y haga clic en migrar. Deberás escribir algunas secuencias de comandos en la shell o en código. Afortunadamente, si el código para el lado de MongoDB de la ecuación se construye bien, serás capaz de reutilizar una buena parte de ella para la operación normal de tiempo de ejecución de la solución.

El primer paso es hacer referencia a la MongoDB.Bson y Mongo­DB.Bibliotecas de controlador y agregando el uso de declaraciones:

using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using MongoDB.Driver.Wrappers;

Objetos mostrará algunos nuevos métodos que son muy útiles cuando se intenta pasar de regulares objetos .net a los objetos de Bson utilizados con MongoDB. Como figura 5 muestra, esto se hace evidente en una función para convertir las filas de la salida de un fetch de base de datos en un BsonDocument para guardar en MongoDB.

Figura 5 migración de datos con LINQ y MongoDB

pubsEntities myPubsEntities = new pubsEntities();
var pubsAuthors = from row in myPubsEntities.authors
  select row;
MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
mongoPubs.CreateCollection("Authors");
MongoCollection<BsonDocument> authorsCollection =
  mongoPubs.GetCollection("Authors");
BsonDocument bsonAuthor;
foreach (author pubAuthor in pubsAuthors)
{
  bsonAuthor = pubAuthor.ToBsonDocument();
    authorsCollection.Insert(bsonAuthor);
}

En el ejemplo simple de figura 5 convierte los datos directamente mediante los métodos de extensión MongoDB. Sin embargo, tienes que tener cuidado, especialmente con LINQ, al realizar este tipo de operación. Por ejemplo, si intento la misma operación para los títulos, la profundidad del gráfico de objetos de la tabla de títulos en el modelo de entidad hará que el controlador de MongoDB producir un error de desbordamiento de pila. En tal caso, la conversión será un poco más detallada en el código, como se muestra en la figura 6.

Figura 6 convertir valores individualmente

pubsEntities myPubsEntities = new pubsEntities();
var pubsTitles = from row in myPubsEntities.titles
  select row;
MongoDatabase mongoPubs = _mongoServer.GetDatabase("Pubs");
MongoCollection<BsonDocument> titlesCollection =
  mongoPubs.GetCollection("Titles");
BsonDocument bsonTitle;
foreach (title pubTitle in pubsTitles)
{
  bsonTitle = new BsonDocument{ {"titleId", pubTitle.title_id},
     {"pub_id", pubTitle.pub_id},
     {"publisher", pubTitle.publisher.pub_name},
     {"price", pubTitle.price.ToString()},
     {"title1", pubTitle.title1}};
  titlesCollection.Insert(bsonTitle);
}

Para mantener la conversión más simple posible, el mejor enfoque es escribir las consultas SQL para devolver a entidades individuales que se pueden agregar más fácilmente a la colección de MongoDB correspondiente. Para BsonDocuments que tienen colecciones de documentos de niño, se adoptan un enfoque multietapa para crear al padre BsonDocument, agregar el niño BsonDocuments al padre BsonDocument y luego agregar al padre a la colección.

Los bits obvios deberás convertir si pasar de una base de datos de Windows Azure SQL a una implementación de MongoDB es todo el código que vive en procedimientos almacenados, vistas y disparadores. En muchos casos, el código será algo más sencillo, dado que voy tratando con una BsonDocument con los niños que ustedes persisten en su totalidad en lugar de tener que trabajar a través de las restricciones relacionales de tablas múltiples. Además, en lugar de escribir TSQL, puedes usar tu idioma preferido de .net, con todo el apoyo de Visual Studio como el IDE. El código que no puede ser inicialmente cuenta es lo que tendrás que crear para poder hacer transacciones a través de documentos. En cierto sentido, es una pena tener que mover toda la funcionalidad de la plataforma de base de datos SQL de Windows Azure en código de aplicación. Por otro lado, una vez que termines tendrás un extremadamente rápido y escalable de datos back-end, porque se centra únicamente en datos realizar trayectos. También puede obtener un nivel medio altamente escalable moviendo toda esa lógica previamente atrapada en el RDMBS en una capa de nivel medio adecuada.

Una última nota de cierta relevancia es que, debido a la naturaleza del almacenamiento de datos, es probable que aumente el tamaño de los datos. Esto es porque cada documento tiene que sostener el esquema y los datos. Mientras que esto no puede ser terriblemente importante para más, debido al bajo costo del espacio en Windows Azure tablas, todavía es algo que debe tener en cuenta en el diseño.

Reflexiones finales

Una vez que los datos están disponibles en MongoDB, trabajar con ella, en muchos sentidos, sentirá familiarizado.

A partir de C# en el controlador 1.4 (actualmente en 1.5.0.4566) se mejora el soporte LINQ, para escribir el código no se sienta completamente desconocido. Así, si su proyecto o solución podría beneficiarse de un almacén de datos NoSQL como MongoDB, no deje que la sintaxis asustar, porque el ajuste será mínima. Tenga en cuenta, sin embargo, que existen algunas diferencias importantes entre una madura y sólida plataforma RDBMS — como la base de datos SQL de Windows Azure — y MongoDB. Por ejemplo, salud y seguimiento requerirá más trabajo manual. En lugar de vigilancia sólo cierto número de instancias de base de datos SQL de Windows Azure, tendrás que controlar las funciones del trabajador de host, el host de almacenamiento de Windows Azure Blob de los archivos de base de datos y los archivos de registro de MongoDB sí.

NoSQL soluciones ofrecen un gran rendimiento para algunas operaciones de base de datos y algunas características útiles e interesantes que realmente pueden ser una bendición para un equipo de desarrollo de la solución. Si usted tiene una gran cantidad de datos y estás con un presupuesto limitado, el MongoDB en la opción de Windows Azure podría ser una gran adición a su arquitectura de la solución.

Joseph Fultz es un arquitecto de software en Hewlett-Packard Co., trabajando como parte del grupo HP.com Global IT. Anteriormente fue un arquitecto de software de Microsoft, trabaja con su empresa de primer nivel y clientes de ISV para definir soluciones de arquitectura y diseño.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Wen ming Ye