• ¡Obtenga la seguridad de la aplicación de la manera correcta! Detectar, proteger, monitorear, acelerar y más ...
  • La fragmentación es un proceso de dividir la gran escala de conjuntos de datos en un fragmento de conjuntos de datos más pequeños en varias instancias de MongoDB en un entorno distribuido.

    ¿Qué es Sharding?

    Fragmentación de MongoDB nos proporciona una solución escalable para almacenar una gran cantidad de datos entre la cantidad de servidores en lugar de almacenarlos en un solo servidor.

    En términos prácticos, no es factible almacenar datos que crecen exponencialmente en una sola máquina. La consulta de una gran cantidad de datos almacenados en un solo servidor podría conducir a una alta utilización de recursos y puede no proporcionar un rendimiento de lectura y escritura satisfactorio.

    Básicamente, existen dos tipos de métodos de escalado para realizar el crecimiento de datos con el sistema:

    • Vertical
    • Horizontal

    Escalado vertical trabaja para mejorar el rendimiento de un solo servidor agregando procesadores más potentes, actualizando la RAM o agregando más espacio en disco al sistema. Pero existen las posibles implicaciones de aplicar el escalado vertical en casos de uso prácticos con configuraciones de hardware y tecnología existentes.

    Escala horizontal trabaja agregando más servidores y distribuyendo la carga en múltiples servidores. Dado que cada máquina manejará el subconjunto del conjunto de datos completo, proporciona una solución más eficiente y rentable en lugar de implementar el hardware de alta gama. Pero requiere un mantenimiento adicional de una infraestructura compleja con una gran cantidad de servidores.

    La fragmentación de Mongo DB funciona con la técnica de escalado horizontal.

    Componentes de fragmentación

    Para lograr la fragmentación en MongoDB, se requieren los siguientes componentes:

    Casco es una instancia de Mongo para manejar un subconjunto de datos originales. Los fragmentos deben implementarse en el conjunto de réplicas.

    Mongos es una instancia de Mongo y actúa como una interfaz entre una aplicación cliente y un clúster fragmentado. Funciona como un enrutador de consultas para fragmentos.

    Servidor de configuración es una instancia de Mongo que almacena información de metadatos y detalles de configuración del clúster. MongoDB requiere que el servidor de configuración se implemente como un conjunto de réplicas.

    Arquitectura de fragmentación

    El clúster de MongoDB consta de varios conjuntos de réplicas.

    Cada conjunto de réplicas consta de un mínimo de 3 o más instancias de mongo. Un clúster fragmentado puede constar de varias instancias de fragmentos de mongo, y cada instancia de fragmento funciona dentro de un conjunto de réplicas de fragmentos. La aplicación interactúa con Mongos, que a su vez se comunica con fragmentos. Por lo tanto, en Sharding, las aplicaciones nunca interactúan directamente con los nodos de fragmentos. El enrutador de consultas distribuye los subconjuntos de datos entre los nodos de los fragmentos según la clave del fragmento.

    Implementación de fragmentación

    Siga los pasos a continuación para fragmentar

    Paso 1:

    • EMPEZAR servidor de configuración en el conjunto de réplicas y habilite la réplica entre ellos.

    mongod --configsvr --port 27019 --replSet rs0 --dbpath C:\data\data1 --bind_ip localhost

    mongod --configsvr --port 27018 --replSet rs0 --dbpath C:\data\data2 --bind_ip localhost

    mongod --configsvr --port 27017 --replSet rs0 --dbpath C:\data\data3 --bind_ip localhost

    Paso 2:

    • Inicialice el conjunto de réplicas en uno de los servidores de configuración.

    rs.initiate( { _id : "rs0",  configsvr: true,  members: [   { _id: 0, host: "IP:27017" },   { _id: 1, host: "IP:27018" },   { _id: 2, host: "IP:27019" }    ] })

    rs.initiate( { _id : "rs0",  configsvr: true,  members: [   { _id: 0, host: "IP:27017" },   { _id: 1, host: "IP:27018" },   { _id: 2, host: "IP:27019" }    ] })
    {
            "ok" : 1,
            "$gleStats" : {
                    "lastOpTime" : Timestamp(1593569257, 1),
                    "electionId" : ObjectId("000000000000000000000000")
            },
            "lastCommittedOpTime" : Timestamp(0, 0),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593569257, 1),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            },
            "operationTime" : Timestamp(1593569257, 1)
    }

    Paso 3:

    • EMPEZAR servidores de fragmentación en el conjunto de réplicas y habilite la réplica entre ellos.

    mongod --shardsvr --port 27020 --replSet rs1 --dbpath C:\data\data4 --bind_ip localhost

    mongod --shardsvr --port 27021 --replSet rs1 --dbpath C:\data\data5 --bind_ip localhost

    mongod --shardsvr --port 27022 --replSet rs1 --dbpath C:\data\data6 --bind_ip localhost

    MongoDB inicializa el primer servidor de fragmentación como principal, para mover el uso del servidor de fragmentación principal movePrimary método.

    Paso 4:

    • Inicialice el conjunto de réplicas en uno de los servidores fragmentados.

    rs.initiate( { _id : "rs0",  members: [   { _id: 0, host: "IP:27020" },   { _id: 1, host: "IP:27021" },   { _id: 2, host: "IP:27022" }    ] })

    rs.initiate( { _id : "rs0",  members: [   { _id: 0, host: "IP:27020" },   { _id: 1, host: "IP:27021" },   { _id: 2, host: "IP:27022" }    ] })
    {
            "ok" : 1,
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593569748, 1),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            },
            "operationTime" : Timestamp(1593569748, 1)
    }

    Paso 5:

    • Comience los mangos para el racimo fragmentado

    mongos --port 40000 --configdb rs0/localhost:27019,localhost:27018, localhost:27017

    Paso 6:

    • Conecta el servidor de ruta mongo

    mongo --port 40000

    • Ahora, agregue servidores de fragmentación.

    sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")

    sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")
    {
            "shardAdded" : "rs1",
            "ok" : 1,
            "operationTime" : Timestamp(1593570212, 2),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593570212, 2),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Paso 7:

    • En mongo shell, habilite la fragmentación en bases de datos y colecciones.
    • Habilitar la fragmentación en la base de datos

    sh.enableSharding("geekFlareDB")

    sh.enableSharding("geekFlareDB")
    {
            "ok" : 1,
            "operationTime" : Timestamp(1591630612, 1),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1591630612, 1),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Paso 8:

    • Para fragmentar la colección, se requiere la clave de fragmentación (descrita más adelante en este artículo).

    Sintaxis: sh.shardCollection("dbName.collectionName", { "key" : 1 } )

    sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } )
    {
            "collectionsharded" : "geekFlareDB.geekFlareCollection",
            "collectionUUID" : UUID("0d024925-e46c-472a-bf1a-13a8967e97c1"),
            "ok" : 1,
            "operationTime" : Timestamp(1593570389, 3),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593570389, 3),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Nota: si la colección no existe, cree lo siguiente.

    db.createCollection("geekFlareCollection")
    {
            "ok" : 1,
            "operationTime" : Timestamp(1593570344, 4),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593570344, 5),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Paso 9:

    Inserta datos en la colección. Los registros de Mongo comenzarán a crecer e indicarán que un equilibrador está en acción e intentará equilibrar los datos entre fragmentos.

    Paso 10:

    El último paso es verificar el estado de la fragmentación. El estado se puede verificar ejecutando el siguiente comando en el nodo de ruta de Mongos.

    Estado de fragmentación

    Verifique el estado de fragmentación ejecutando el siguiente comando en el nodo de ruta mongo.

    sh.status()

    mongos> sh.status()
    --- Sharding Status ---
      sharding version: {
            "_id" : 1,
            "minCompatibleVersion" : 5,
            "currentVersion" : 6,
            "clusterId" : ObjectId("5ede66c22c3262378c706d21")
      }
      shards:
            {  "_id" : "rs1",  "host" : "rs1/localhost:27020,localhost:27021,localhost:27022",  "state" : 1 }
      active mongoses:
            "4.2.7" : 1
      autosplit:
            Currently enabled: yes
      balancer:
            Currently enabled:  yes
            Currently running:  no
            Failed balancer rounds in last 5 attempts:  5
            Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs1
            Time of Reported error:  Tue Jun 09 2020 15:25:03 GMT+0530 (India Standard Time)
            Migration Results for the last 24 hours:
                    No recent migrations
      databases:
            {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                    config.system.sessions
                            shard key: { "_id" : 1 }
                            unique: false
                            balancing: true
                            chunks:
                                    rs1     1024
                            too many chunks to print, use verbose if you want to force print
            {  "_id" : "geekFlareDB",  "primary" : "rs1",  "partitioned" : true,  "version" : {  "uuid" : UUID("a770da01-1900-401e-9f34-35ce595a5d54"),  "lastMod" : 1 } }
                    geekFlareDB.geekFlareCol
                            shard key: { "key" : 1 }
                            unique: false
                            balancing: true
                            chunks:
                                    rs1     1
                            { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
                    geekFlareDB.geekFlareCollection
                            shard key: { "product" : 1 }
                            unique: false
                            balancing: true
                            chunks:
                                    rs1     1
                            { "product" : { "$minKey" : 1 } } -->> { "product" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
            {  "_id" : "test",  "primary" : "rs1",  "partitioned" : false,  "version" : {  "uuid" : UUID("fbc00f03-b5b5-4d13-9d09-259d7fdb7289"),  "lastMod" : 1 } }
    
    mongos>

    Distribución de datos

    El enrutador Mongos distribuye la carga entre los fragmentos según la clave del fragmento y distribuye los datos de manera uniforme; equilibrador entra en acción.

    El componente clave para distribuir datos entre fragmentos son

    • Un equilibrador juega un papel en el equilibrio del subconjunto de datos entre los nodos fragmentados. Balancer se ejecuta cuando el servidor de Mongos comienza a distribuir cargas entre fragmentos. Una vez iniciado, Balancer distribuyó los datos de manera más uniforme. Para comprobar el estado de la ejecución del equilibrador <strong>sh.status()</strong> or sh.getBalancerState() or<code class="language-markup">sh.isBalancerRunning().
    mongos> sh.isBalancerRunning()
    true
    mongos>

    O

    mongos> sh.getBalancerState()
    true
    mongos>

    Después de insertar los datos, pudimos notar alguna actividad en el demonio de Mongos que indica que está moviendo algunos fragmentos para los fragmentos específicos y así sucesivamente, es decir, el equilibrador estará en acción tratando de equilibrar los datos entre los fragmentos. La ejecución del equilibrador podría provocar problemas de rendimiento; por lo tanto, se sugiere ejecutar el balanceador dentro de un cierto ventana equilibradora.

    mongos> sh.status()
    --- Sharding Status ---
      sharding version: {
            "_id" : 1,
            "minCompatibleVersion" : 5,
            "currentVersion" : 6,
            "clusterId" : ObjectId("5efbeff98a8bbb2d27231674")
      }
      shards:
            {  "_id" : "rs1",  "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",  "state" : 1 }
            {  "_id" : "rs2",  "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",  "state" : 1 }
      active mongoses:
            "4.2.7" : 1
      autosplit:
            Currently enabled: yes
      balancer:
            Currently enabled:  yes
            Currently running:  yes
            Failed balancer rounds in last 5 attempts:  5
            Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs2
            Time of Reported error:  Wed Jul 01 2020 14:39:59 GMT+0530 (India Standard Time)
            Migration Results for the last 24 hours:
                    1024 : Success
      databases:
            {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                    config.system.sessions
                            shard key: { "_id" : 1 }
                            unique: false
                            balancing: true
                            chunks:
                                    rs2     1024
                            too many chunks to print, use verbose if you want to force print
            {  "_id" : "geekFlareDB",  "primary" : "rs2",  "partitioned" : true,  "version" : {  "uuid" : UUID("a8b8dc5c-85b0-4481-bda1-00e53f6f35cd"),  "lastMod" : 1 } }
                    geekFlareDB.geekFlareCollection
                            shard key: { "key" : 1 }
                            unique: false
                            balancing: true
                            chunks:
                                    rs2     1
                            { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs2 Timestamp(1, 0)
            {  "_id" : "test",  "primary" : "rs2",  "partitioned" : false,  "version" : {  "uuid" : UUID("a28d7504-1596-460e-9e09-0bdc6450028f"),  "lastMod" : 1 } }
    
    mongos>
    • Clave de fragmento determina la lógica para distribuir documentos de colección fragmentada entre los fragmentos. La clave de fragmento puede ser un campo indexado o un campo compuesto indexado que debe estar presente en todos los documentos de la colección que se insertará. Los datos se dividirán en fragmentos y cada fragmento se asociará con la clave de fragmento basada en rango. Sobre la base del rango de consultas, el enrutador decidirá qué fragmento almacenará el fragmento.

    Clave de fragmento se puede seleccionar considerando cinco propiedades:

    • Cardinalidad
    • Distribución de escritura
    • Leer distribución
    • Leer segmentación
    • Leer localidad

    Una clave de fragmento ideal hace que MongoDB distribuya uniformemente la carga entre todos los fragmentos. Elegir una buena clave de fragmento es extremadamente importante.

    Imagen: MongoDB

    Eliminando el nodo del fragmento

    Antes de eliminar fragmentos del clúster, el usuario debe garantizar la migración segura de los datos a los fragmentos restantes. MongoDB se encarga de drenar de forma segura los datos a otros nodos de fragmentos antes de eliminar el nodo de fragmentos necesario.

    Ejecute el siguiente comando para eliminar el fragmento requerido.

    Paso 1:

    Primero, necesitamos determinar el nombre de host del fragmento que se eliminará. El siguiente comando enumerará todos los fragmentos presentes en el clúster junto con el estado del fragmento.

    db.adminCommand( { listShards: 1 } )

    mongos> db.adminCommand( { listShards: 1 } )
    {
            "shards" : [
                    {
                            "_id" : "rs1",
                            "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",
                            "state" : 1
                    },
                    {
                            "_id" : "rs2",
                            "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                            "state" : 1
                    }
            ],
            "ok" : 1,
            "operationTime" : Timestamp(1593572866, 15),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593572866, 15),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Paso 2:

    Ejecute el siguiente comando para eliminar el fragmento requerido del clúster. Una vez emitido, el equilibrador se encarga de eliminar los fragmentos del nodo de fragmentos de drenaje y luego equilibra la distribución de los fragmentos restantes entre los nodos de fragmentos restantes.

    db.adminCommand( { removeShard: "shardedReplicaNodes" } )

    mongos> db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )
    {
            "msg" : "draining started successfully",
            "state" : "started",
            "shard" : "rs1",
            "note" : "you need to drop or movePrimary these databases",
            "dbsToMove" : [ ],
            "ok" : 1,
            "operationTime" : Timestamp(1593572385, 2),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593572385, 2),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Paso 3:

    Para comprobar el estado del fragmento de drenaje, vuelva a ejecutar el mismo comando.

    db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )

    Necesitamos esperar hasta que se complete el drenaje de los datos. MSG y estado Los campos mostrarán si el drenaje de datos se ha completado o no, de la siguiente manera

    "msg" : "draining ongoing",
    "state" : "ongoing",

    También podemos comprobar el estado con el comando sh.status(). Una vez eliminado, el nodo fragmentado no se reflejará en la salida. Pero si el drenaje continuará, el nodo fragmentado vendrá con el estado de drenaje como verdadero.

    Paso 4:

    Continúe verificando el estado del drenaje con el mismo comando anterior, hasta que el fragmento requerido se elimine por completo.
    Una vez completado, la salida del comando reflejará el mensaje y el estado como completado.

    "msg" : "removeshard completed successfully",
    "state" : "completed",
    "shard" : "rs1",
    "ok" : 1,

    Paso 5:

    Finalmente, debemos verificar los fragmentos restantes en el clúster. Para verificar el estado ingrese <strong>sh.status()</strong> or <strong>db.adminCommand( { listShards: 1 } )</strong>

    mongos> db.adminCommand( { listShards: 1 } )
    {
            "shards" : [
                    {
                            "_id" : "rs2",
                            "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                            "state" : 1
                    }
            ],
            "ok" : 1,
            "operationTime" : Timestamp(1593575215, 3),
            "$clusterTime" : {
                    "clusterTime" : Timestamp(1593575215, 3),
                    "signature" : {
                            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                            "keyId" : NumberLong(0)
                    }
            }
    }

    Aquí, podemos ver que el fragmento eliminado ya no está presente en la lista de fragmentos.

    Beneficios de la fragmentación sobre la replicación

    • En la replicación, el nodo primario maneja todas las operaciones de escritura, mientras que los servidores secundarios son necesarios para mantener copias de respaldo o realizar operaciones de solo lectura. Pero en la fragmentación junto con los conjuntos de réplicas, la carga se distribuye entre varios servidores.
    • Un único conjunto de réplicas está limitado a 12 nodos, pero no hay restricción en la cantidad de fragmentos.
    • La replicación requiere hardware de alta gama o escalado vertical para manejar grandes conjuntos de datos, lo cual es demasiado costoso en comparación con agregar servidores adicionales en fragmentación.
    • En la replicación, el rendimiento de lectura se puede mejorar agregando más servidores esclavos / secundarios, mientras que, en la fragmentación, el rendimiento de lectura y escritura se mejorará al agregar más nodos de fragmentos.

    Limitación de fragmentación

    • El clúster fragmentado no admite la indexación única en los fragmentos hasta que el índice único tenga como prefijo la clave de fragmento completo.
    • Todas las operaciones de actualización de la colección fragmentada en uno o varios documentos deben contener la clave fragmentada o _id campo en la consulta.
    • Las colecciones se pueden fragmentar si su tamaño no supera el umbral especificado. Este umbral se puede estimar sobre la base del tamaño promedio de todas las claves de fragmentos y el tamaño configurado de los fragmentos.
    • La fragmentación comprende límites operativos sobre el tamaño máximo de colección o el número de divisiones.
    • Elegir las claves de fragmento incorrectas para generar implicaciones en el rendimiento.

    Conclusión

    MongoDB ofrece fragmentación incorporada para implementar una gran base de datos sin comprometer el rendimiento. Espero que lo anterior te ayude a configurar la fragmentación de MongoDB. A continuación, es posible que desee familiarizarse con algunos de los Comandos de MongoDB.