Tengo un MongoDB que almacenan datos de producto para 204.639.403 elementos, los datos ya ha escupido hacia arriba, por el elemento del país, en cuatro lógico bases de datos que se ejecutan en la misma máquina física en el mismo proceso de MongoDB.

Aquí está una lista con el número de documentos por lógico de base de datos:

  • CoUk: 56.719.977
  • De: 61.216.165
  • Fr: 52.280.460
  • Es: 34.422.801

Mi problema es que la base de datos de rendimiento de escritura es llegar worser, especialmente escribe a la mayor de las cuatro bases de datos (De) se ha convertido en muy mal, según iotop el proceso mongod utiliza 99% de la IO tiempo con menos de 3MB escribe y 1.5 MB lecturas por segundo. Esto conduce a un bloqueo largo de bases de datos, 100%+ de bloqueo convertido normalmente de acuerdo a mongostat – incluso si todos los procesos de escritura y lectura para el país de las bases de datos se ha detenido. El esclavo actual alcanza una CARGA de hasta 6, el conjunto de réplicas máster tiene una carga de 2 a 3 al mismo tiempo, por lo que conduce a un retraso de la replicación, demasiado.

Cada una de las bases de datos tiene los mismos datos y la estructura del índice, estoy usando la base de datos más grande (De) para más ejemplos.

Este es un elemento aleatorio tomado de la base de datos, sólo como ejemplo, la estructura está optimizado para reunir todos los datos importantes con una sola lectura:

{
    "_id" : ObjectId("533b675dba0e381ecf4daa86"),
    "ProductId" : "XGW1-E002F-DW",
    "Title" : "Sample item",
    "OfferNew" : {
        "Count" : 7,
        "LowestPrice" : 2631,
        "OfferCondition" : "NEW"
    },
    "Country" : "de",
    "ImageUrl" : "http://….jpg",
    "OfferHistoryNew" : [ 
         
        {
            "Date" : ISODate("2014-06-01T23:22:10.940+02:00"),
            "Value" : {
                "Count" : 10,
                "LowestPrice" : 2171,
                "OfferCondition" : "NEW"
            }
        }
    ],
    "Processed" : ISODate("2014-06-09T23:22:10.940+02:00"),
    "Eans" : [ 
        "9781241461959"
    ],
    "OfferUsed" : {
        "Count" : 1,
        "LowestPrice" : 5660,
        "OfferCondition" : "USED"
    },
    "Categories" : [ 
        NumberLong(186606), 
        NumberLong(541686), 
        NumberLong(288100), 
        NumberLong(143), 
        NumberLong(15777241)
    ]
}

Típica pregunta se forma simple como por el ProductId o una EAN sólo a mejoras por la categoría y ordenados por su rango o refinamientos de la categoría y Un rango rango (1 a 10.000 por ejemplo), y ordenadas por el B rango… .

Esto son las estadísticas de la más grande db:

{
    "ns" : "De.Item",
    "count" : 61216165,
    "size" : 43915150656,
    "avgObjSize" : 717,
    "storageSize" : 45795192544,
    "numExtents" : 42,
    "nindexes" : 6,
    "lastExtentSize" : 2146426864,
    "paddingFactor" : 1,
    "systemFlags" : 0,
    "userFlags" : 1,
    "totalIndexSize" : 41356824320,
    "indexSizes" : {
        "_id_" : 2544027808,
        "RankA_1" : 1718096464,
        "Categories_1_RankA_1_RankB_-1" : 16383534832,
        "Eans_1" : 2846073776,
        "Categories_1_RankA_-1" : 15115290064,
        "ProductId_1" : 2749801376
    },
    "ok" : 1
}

Es mencionable que el tamaño del índice es casi la mitad del tamaño de almacenamiento.

Cada país DB tiene que manejar 3 y 5 millones de actualizaciones/inserta por día, mi objetivo es llevar a cabo las operaciones de escritura en menos de cinco horas durante la noche.

Actualmente es un conjunto de réplicas con dos servidores, cada uno tiene 32 gb de memoria RAM y un RAID 1 con 2 TB de discos Duros. Simple optimizaciones como el interbloqueo programador y noatime ya ha sido hecho.

He trabajado algunas optimizaciones de estrategias:

  • La reducción de los índices de número:
    • el valor predeterminado _id podría utilizar el ProductId en lugar de la predeterminada MongoId que habría de salvar a un 6-7% por DB por el total de los nixes tamaño.
    • Tratando de quitar la Categories_1_RankA_-1 índice tal vez el BrowseNodes_1_RankA_1_RankB_-1 índice podría manejar la consulta, también. ¿La clasificación todavía funciona bien cuando no en el índice completo se utiliza? Otra manera sería almacenar el índice de coincidencia de Categories_1_RankA_1_RankB_-1 en otra colección que se refiere a la colección principal.
  • La reducción de la cantidad de datos en bruto por el tamaño de las teclas, en lugar de ‘Categorías’, ‘Medio’, ‘OfferHistoryNew’… yo podría usar ‘a’, ‘b’, ‘c’… esto debería ser fácil, ya que he utilizado http://mongojack.org/ pero yo no ahora, ¿vale la pena será.
  • Sustitución de la RAID1 con un RAID0, podría ser fácilmente probado por tomarse el esclavo hacia abajo, la reinstalación y la lectura en el conjunto de réplicas… .
  • La prueba más fuerte de Hardware de las unidades Ssd y más memoria de la que debe ocuparse de la lee y escribe más rápido.
  • Usar MongoDB del sombreado de capacidades:
    • He leído que cada fragmento tiene que llevar a cabo toda la base de datos de índice?
    • Tengo la preocupación de que la estructura de consulta podrían no caber en un ambiente compartido bien. Utilizando el id de producto como fragmento de la clave parece encajar no todos los tipos de consulta y la fragmentación por la categoría es complicado, demasiado. Un solo elemento puede aparecer de múltiples principal y sub-categorías … . Mis preocupaciones de que podría estar equivocado, yo nunca he usado en un entorno de producción.

Pero debe haber otras estrategias de optimización, no viene a mi mente, me gustaría conocer!

Que la estrategia de optimización de sonido más prometedores o es una mezcla de varias optimizaciones que se necesita aquí?

  • Por razones históricas, vale la pena señalar que este hilo de Reddit contiene la discusión en relación con esta cuestión.

2 Comentarios

  1. 12

    Más probable es que usted está ejecutando en problemas debido a un crecimiento récord, ver http://docs.mongodb.org/manual/core/write-performance/#document-growth.

    Mongo prefiere registros de fijo (o al menos limitado) de tamaño. El aumento del tamaño de registro más allá de la pre-almacenamiento asignado hará que el documento para ser movido a otra ubicación en el disco, multiplicando su I/O con cada escritura. Considere la posibilidad de pre-asignación de «suficiente» espacio para el promedio de documento en insertar, si el documento tamaños son relativamente homogéneos. De lo contrario, considere la posibilidad de dividir rápido crecimiento de las matrices anidadas en un sistema de recogida selectiva, con lo que la sustitución de las actualizaciones con insertos. Consulte también a su fragmentación y a considerar la posibilidad de compactar las bases de datos de tiempo en tiempo, por lo que tiene una mayor densidad de documentos por cada bloque que se va a reducir duro de fallos de página.

    • El factor de relleno fue de 1 (sin relleno), estoy tratando ahora el usePowerOf2Sizes bandera: « db.runCommand( {collMod: «Elemento», usePowerOf2Sizes : true }) «
    • El relleno tiene un gran efecto para el que escribe, pero además el relleno de los índices se han optimizado. Ambas optimizaciones tenido un gran impacto en el rendimiento de escritura! – Con la optimización de índices: 4:47 2.5 Millones de actualizaciones – Con la optimización de indexado y relleno: 1:15 de 1,5 Millones de actualizaciones Sin ningún tipo de optimizaciones: 9:17 1.2 Millones de actualizaciones de Los próximos pasos que va a optimizar son los IOPS, actualmente estoy probando un RAID0 el siguiente paso será mover el diario a otro disco duro.
    • Cómo fue exactamente lo que usted optimice sus índices?
  2. 1

    Podría considerar el uso de una base de datos con mejor rendimiento que admite documentos? He escuchado historias de éxito con TokuMX. Y FoundationDB (de donde soy ingeniero) tiene un muy buen rendimiento con alta concurrente escribir carga y documentos de gran tamaño. Encantados de responder a más preguntas sobre FoundationDB.

    • Gracias, nunca había oído acerca de TokuMX pero le doy una oportunidad. Acerca de FoundationDB seeems a ser clave/valor de la tienda, pero necesito un dbms con anidada documentos y múltiples indexación… esto parece que no se adapta a mis necesidades.
    • FDB es la clave/valor en su base, pero admite más características (como anidada documentos y múltiples indexación) a través de las capas. Obviamente, yo soy parcial a pensar que es la mejor opción así que no voy a insistir en que es más aquí 🙂

Dejar respuesta

Please enter your comment!
Please enter your name here