Todos los productos
Search
Centro de documentos

ApsaraDB for MongoDB:Mejores prácticas para índices TTL en ApsaraDB for MongoDB

Última actualización: Sep 19, 2026

Un índice TTL (Time-To-Live) es un índice especial de un solo campo que MongoDB utiliza para eliminar documentos automáticamente después de que caducan. Este tema describe cómo funcionan los índices TTL, cómo crearlos y gestionarlos, sus límites, los problemas comunes con sus soluciones y las mejores prácticas para usarlos en ApsaraDB for MongoDB.

Descripción general

Un índice TTL (Time-To-Live) es un índice especial de un solo campo que MongoDB utiliza para eliminar documentos automáticamente cuando alcanzan un tiempo de caducidad específico. Los índices TTL son adecuados para gestionar datos con un ciclo de vida bien definido, como registros de log, información de sesión, cachés temporales y códigos de verificación. Si los usa correctamente, controlará de manera eficaz el volumen de datos de una colección y evitará un crecimiento descontrolado del almacenamiento.

Sin embargo, un uso inadecuado de los índices TTL en entornos de producción provoca diversos problemas, como picos periódicos de CPU, retrasos en la eliminación de datos caducados y un aumento continuo del espacio en disco. Este tema explica cómo funcionan los índices TTL, cómo utilizarlos, los problemas más frecuentes y las mejores prácticas. Así podrá usarlos correctamente en ApsaraDB for MongoDB.

Cómo funcionan los índices TTL

Mecanismo básico

Cuando se inicia un proceso mongod, se crea un hilo en segundo plano llamado TTLMonitor. De forma predeterminada, este hilo inicia un ciclo de limpieza TTL cada 60 segundos. Cada ciclo ejecuta las siguientes operaciones:

  1. Recopila todos los índices TTL de la base de datos actual.

  2. Genera un plan de ejecución para cada índice TTL de forma secuencial y realiza la limpieza de datos.

  3. Elimina los documentos cuyo valor del campo indexado más expireAfterSeconds sea anterior a la hora actual.

El umbral de caducidad se calcula de la siguiente manera: el valor de fecha del campo indexado más la cantidad de segundos especificada por expireAfterSeconds. Si el resultado es anterior a la hora actual, el documento se considera caducado.

Comportamiento en conjuntos de réplicas

En un conjunto de réplicas, el hilo TTL en segundo plano ejecuta operaciones de eliminación únicamente en el nodo Primary. Los hilos TTL de los nodos Secondary permanecen inactivos y sincronizan las eliminaciones mediante la replicación del oplog desde el nodo Primary. Esto significa que las eliminaciones TTL generan entradas adicionales en el oplog y pueden afectar el retraso de replicación del conjunto de réplicas.

Diferencias entre versiones: optimización de eliminación por lotes (MongoDB 7.0+)

A partir de MongoDB 7.0 (una función introducida originalmente en la versión de desarrollo 6.1), la eliminación TTL utiliza un mecanismo de "eliminación justa" que asigna tiempo de eliminación a cada índice TTL mediante intervalos de tiempo. Esto evita que los datos caducados de ciertas colecciones queden sin procesar durante la limpieza. Las principales mejoras son a continuación:

  • ttlMonitorBatchDeletes: habilita el modo de eliminación por lotes. Está activado de forma predeterminada. Cuando se habilita, las eliminaciones TTL se distribuyen de manera más equitativa entre las colecciones.

  • ttlIndexDeleteTargetTimeMS: límite máximo de tiempo por ciclo de eliminación para cada índice TTL. Valor predeterminado: 1000 ms.

  • ttlIndexDeleteTargetDocs: límite máximo de documentos eliminados por ciclo para cada índice TTL. Valor predeterminado: 50000.

  • ttlMonitorSubPassTargetSecs: límite máximo de tiempo para un subciclo que recorre los índices TTL. Valor predeterminado: 60 segundos.

Estos parámetros aparecen como la etapa BATCHED_DELETE en el plan de ejecución. Para consultarlos, utilice el comando explain.

Crear y gestionar índices TTL

Crear un índice TTL

Utilice el método createIndex para crear un índice TTL en un campo de tipo Date.

Ejemplo 1: cree un índice TTL para que los documentos caduquen 3600 segundos después del valor del campo lastModifiedDate.

db.eventlog.createIndex(
  { "lastModifiedDate": 1 },
  { expireAfterSeconds: 3600 }
)

Ejemplo 2: caducidad en un momento específico. Establezca expireAfterSeconds en 0 para que el valor del campo determine por sí solo el tiempo de caducidad.

db.sessions.createIndex(
  { "expireAt": 1 },
  { expireAfterSeconds: 0 }
)

Modificar el tiempo de caducidad de un índice TTL

Utilice el comando collMod para cambiar el valor de expireAfterSeconds de un índice TTL existente sin necesidad de reconstruirlo.

db.runCommand({
  "collMod": "log_events",
  "index": {
    "keyPattern": { "createdAt": 1 },
    "expireAfterSeconds": 600
  }
})

Convertir un índice normal en un índice TTL (MongoDB 6.0+)

A partir de MongoDB 6.0, puede usar el comando collMod para convertir un índice normal de un solo campo en un índice TTL, sin tener que eliminarlo y reconstruirlo previamente.

db.runCommand({
  "collMod": "tickets",
  "index": {
    "keyPattern": { "lastModifiedDate": 1 },
    "expireAfterSeconds": 100
  }
})

Supervisar el estado de TTL

Para supervisar las operaciones TTL, utilice los siguientes comandos.

// View the total number of documents deleted by TTL
db.serverStatus().metrics.ttl.deletedDocuments

// View the number of TTL thread passes
db.serverStatus().metrics.ttl.passes

// View the TTL scan interval (default: 60 seconds)
db.runCommand({ getParameter: 1, ttlMonitorSleepSecs: 1 })

// View the TTL delete operations that are currently running
db.currentOp()

Límites de los índices TTL

Antes de usar un índice TTL, tenga en cuenta los siguientes límites importantes:

  • Los índices TTL solo admiten índices de un solo campo. Los índices compuestos no pueden usar esta función. Incluso si establece expireAfterSeconds, el sistema lo ignorará.

  • El campo _id no admite índices TTL.

  • El campo indexado debe ser de tipo BSON Date. Si el valor del campo no es de tipo Date (por ejemplo, un entero de marca de tiempo UNIX o una cadena), los documentos no se eliminarán automáticamente.

  • Los documentos que no contienen el campo indexado no caducan.

  • Si el campo es una matriz, se utiliza el valor de fecha más antiguo de la matriz para calcular el tiempo de caducidad.

  • **No puede modificar un índice TTL existente mediante createIndex**; debe usar el comando collMod.

  • **expireAfterSeconds debe estar en el rango de 0 a 2,147,483,647**, y no debe configurarse como NaN. De lo contrario, podrían producirse comportamientos inesperados y pérdida de datos.

Problemas comunes y soluciones

Problema 1: picos periódicos de CPU causados por eliminaciones TTL

Síntoma

El uso de CPU de la instancia muestra picos periódicos evidentes a intervalos fijos. Al ejecutar db.currentOp(), se observa que el hilo TTL está realizando una gran cantidad de operaciones de eliminación.

Causa

Cuando la aplicación inserta una gran cantidad de datos al mismo tiempo y los valores del campo TTL son iguales o muy cercanos, estos documentos caducan en la misma ventana de tiempo. El hilo TTL necesita eliminar muchos documentos en un solo escaneo, lo que genera una presión significativa sobre la CPU y las operaciones de E/S.

Solución

  • Distribuya los tiempos de caducidad: al insertar datos, agregue un desplazamiento aleatorio al campo TTL para distribuir las caducidades en una ventana de tiempo y evitar eliminaciones masivas. Por ejemplo, para datos que caducan en 24 horas, sume o reste un desplazamiento aleatorio de varios minutos al tiempo de caducidad.

  • Actualice a MongoDB 7.0 o posterior: utilice los mecanismos de eliminación por lotes y eliminación justa para suavizar la presión de las eliminaciones.

  • Elija una especificación de instancia adecuada: asegúrese de que la instancia tenga suficiente CPU y memoria para manejar la carga adicional de las eliminaciones TTL.

Ejemplo: agregue un desplazamiento de caducidad aleatorio a los datos insertados.

// Add a random offset of 0 to 600 seconds on top of 24 hours
var randomOffset = Math.floor(Math.random() * 600);
var expireTime = new Date(Date.now() + (86400 + randomOffset) * 1000);
db.logs.insertOne({
  data: "log content",
  createdAt: expireTime
})

Problema 2: los datos no se eliminan después de caducar

Síntoma

Los documentos superaron su tiempo de caducidad esperado, pero siguen existiendo en la colección.

Pasos para solucionar el problema

  1. Compruebe el tipo de campo: verifique si el valor del campo con índice TTL es de tipo BSON Date. Un error común consiste en usar un entero de marca de tiempo UNIX en lugar de un objeto Date.

    // Check the field type
    db.collection.findOne({}, { createdAt: 1 })
    // Correct: ISODate("2024-01-01T00:00:00Z")
    // Wrong: 1704067200 (integer timestamp)
  2. Compruebe que el campo exista: verifique si los documentos realmente contienen el campo con índice TTL. Los documentos que no lo incluyen no se eliminan automáticamente.

  3. Revise la definición del índice: compruebe que el índice incluya la propiedad expireAfterSeconds.

    db.collection.getIndexes()
  4. Revise la dirección del índice: asegúrese de que el índice TTL esté en orden ascendente (el valor es 1). Un índice descendente puede provocar que TTL funcione mal. Si la dirección del índice es incorrecta, elimínelo y vuelva a crearlo.

  5. Compruebe si TTL Monitor está habilitado: verifique que el parámetro ttlMonitorEnabled esté establecido en true.

    db.adminCommand({ getParameter: 1, ttlMonitorEnabled: 1 })

Problema 3: la eliminación TTL no alcanza la velocidad de inserción de datos

Síntoma

La cantidad de datos en la colección sigue creciendo y el uso del disco aumenta continuamente, a pesar de haber configurado un índice TTL.

Causa

El hilo TTL es de un solo hilo y se ejecuta cada 60 segundos. Cuando la velocidad de inserción de datos supera por mucho la velocidad de limpieza TTL, los datos caducados se acumulan. Además, si existen varios índices TTL en una instancia, se procesan de forma secuencial, lo que reduce aún más la eficiencia de la limpieza.

Solución

  • Ajuste la frecuencia de escaneo: puede acortar el intervalo de escaneo mediante el parámetro ttlMonitorSleepSecs. Tenga en cuenta que una mayor frecuencia incrementa la carga del sistema.

    // Set the scan interval to 10 seconds
    db.adminCommand({ setParameter: 1, ttlMonitorSleepSecs: 10 })
  • Realice la limpieza desde la aplicación: en escenarios con volúmenes de escritura especialmente altos, implemente una eliminación por lotes programada en su aplicación en lugar de depender exclusivamente de los índices TTL.

  • Considere usar colecciones particionadas por tiempo: en escenarios con escrituras extremadamente altas, divida los datos en colecciones por tiempo y elimine las colecciones caducadas completas. Este método es mucho más eficiente que eliminar documentos uno por uno con un índice TTL.

Problema 4: el espacio en disco no se libera después de la eliminación

Síntoma

TTL eliminó una gran cantidad de documentos, pero el uso del disco no disminuyó de forma significativa.

Solución

MongoDB utiliza el motor de almacenamiento WiredTiger. Cuando se eliminan documentos, el espacio se marca como reutilizable, pero no se devuelve inmediatamente al sistema operativo. Para recuperar el espacio en disco de inmediato, ejecute el comando compact o reconstruya los archivos de datos mediante una sincronización inicial. Se recomienda ejecutar compact fuera del horario de mayor actividad.

Mejores prácticas

1. Asegúrese de usar los tipos de datos correctos

Los índices TTL solo funcionan en campos de tipo BSON Date. Se recomienda aplicar el tipo de fecha correcto para los campos TTL desde la aplicación o mediante la función Schema Validation de MongoDB.

db.createCollection("sessions", {
  validator: {
    $jsonSchema: {
      properties: {
        expireAt: { bsonType: "date", description: "The TTL field must be of the Date type" }
      },
      required: ["expireAt"]
    }
  }
})

2. Distribuya los tiempos de caducidad para evitar eliminaciones masivas

Esta es la forma más eficaz de prevenir los picos de CPU causados por las eliminaciones TTL. Al insertar datos, agregue un desplazamiento aleatorio al tiempo de caducidad para que un lote de datos caduque a lo largo de un rango de tiempo. De este modo, el hilo TTL elimina solo una pequeña cantidad de documentos por escaneo, lo que reduce significativamente el impacto en el rendimiento del sistema.

Nota

Para datos con un periodo de retención prolongado (como 24 horas o más), se recomienda agregar un desplazamiento aleatorio de 0 a 10 minutos al tiempo de caducidad.

3. Modifique expireAfterSeconds con precaución

Reducir el valor de expireAfterSeconds de un índice TTL existente provoca que muchos documentos caduquen de inmediato. Esto puede desencadenar operaciones de eliminación a gran escala y afectar gravemente el rendimiento de la instancia. Se recomienda lo siguiente:

  1. Calcule cuántos documentos caducarán inmediatamente después del ajuste.

  2. Aplique el cambio fuera del horario de mayor actividad.

  3. Si la cantidad de documentos caducados es grande, elimine primero una parte de los datos por lotes mediante un script y luego modifique expireAfterSeconds.

4. Consideraciones al crear un nuevo índice TTL

Crear un índice TTL en una colección que ya contiene muchos documentos que cumplen la condición de caducidad puede desencadenar eliminaciones a gran escala justo después de compilar el índice. Se recomienda lo siguiente:

  • Cree el índice TTL fuera del horario de mayor actividad.

  • Limpie primero los datos históricos caducados y luego cree el índice TTL.

  • Compile el índice en segundo plano para no afectar las operaciones habituales.

5. No deshabilite TTL Monitor durante periodos prolongados

Aunque puede deshabilitar temporalmente la función TTL mediante el parámetro ttlMonitorEnabled, no se recomienda mantenerla deshabilitada por mucho tiempo en un entorno de producción. La gran cantidad de documentos caducados acumulados durante ese periodo se eliminará de golpe cuando vuelva a habilitar la función, lo que podría causar problemas graves de rendimiento.

Aviso

Después de deshabilitar temporalmente TTL Monitor, vuelva a habilitarlo cuanto antes para evitar que se acumulen datos caducados.

6. Evalúe el impacto de TTL en el oplog

Cada documento eliminado por TTL genera una entrada en el oplog. Cuando el volumen de eliminaciones es alto, la cantidad de escrituras en el oplog aumenta significativamente, lo que puede afectar el retraso de replicación del conjunto de réplicas. Se recomienda evaluar el impacto de las siguientes maneras:

  • Supervise metrics.ttl.deletedDocuments para dar seguimiento al volumen de eliminaciones TTL.

  • Supervise el retraso de replicación del conjunto de réplicas para asegurarse de que los nodos Secondary puedan manejar el oplog adicional generado por TTL.

  • Aumente el tamaño del oplog si es necesario para evitar desbordamientos causados por las eliminaciones TTL.

7. Alternativas para escenarios con muchas escrituras

Los índices TTL son adecuados para escenarios con volúmenes de escritura moderados. En escenarios con volúmenes de escritura extremadamente altos, considere las siguientes alternativas:

  1. Colecciones particionadas por tiempo: divida la colección según una dimensión temporal (como por día o por semana) y elimine la colección caduca completa. Esta es la forma más eficiente de hacer caducar datos.

  2. Colecciones de series de tiempo: MongoDB 5.0+ admite colecciones de series de tiempo, que incluyen caducidad de datos integrada y eliminan datos por lotes según el bucket. Este enfoque es mucho más eficiente que eliminar documentos uno por uno en una colección normal.

  3. Limpieza programada desde la aplicación: utilice tareas programadas para realizar eliminaciones por lotes fuera del horario de mayor actividad. Esto le otorga un control más preciso sobre la velocidad y el momento de la eliminación.

Funciones TTL por versión

Versión

Funciones

6.0+

Admite la conversión de un índice normal de un solo campo a un índice TTL mediante collMod, sin necesidad de eliminarlo y reconstruirlo previamente.

7.0+

Introduce el mecanismo de eliminación por lotes (BATCHED_DELETE), que mejora la eficiencia de eliminación; implementa la eliminación justa para evitar que ciertas colecciones queden sin procesar; admite índices TTL parciales para colecciones de series de tiempo y una expresión partialFilterExpression más flexible.

Referencia de parámetros TTL

Parámetro

Descripción

Valor predeterminado

ttlMonitorSleepSecs

Intervalo de escaneo del hilo TTL.

60 segundos

ttlMonitorEnabled

Interruptor de la función TTL.

true

ttlMonitorBatchDeletes

Modo de eliminación por lotes (7.0+).

true

ttlIndexDeleteTargetTimeMS

Límite máximo de tiempo por ciclo de eliminación (7.0+).

1000 ms

ttlIndexDeleteTargetDocs

Límite máximo de documentos eliminados por ciclo (7.0+).

50000

ttlMonitorSubPassTargetSecs

Límite máximo de tiempo para un subciclo (7.0+).

60 segundos

Resumen

Los índices TTL son un mecanismo potente y práctico de caducidad automática de datos en MongoDB que gestiona de manera eficaz los datos con un ciclo de vida definido. En entornos de producción, configúrelos según su escenario de negocio para evitar problemas de rendimiento. Los puntos clave son a continuación:

  1. Asegúrese de que el campo TTL sea de tipo BSON Date. Este es el requisito previo para que los índices TTL funcionen correctamente.

  2. Distribuir los tiempos de caducidad es la forma más eficaz de evitar picos de CPU.

  3. Supervise continuamente el estado de TTL (volumen de eliminaciones, ciclos de escaneo, retraso del conjunto de réplicas).

  4. En escenarios con muchas escrituras, considere alternativas como colecciones particionadas por tiempo o colecciones de series de tiempo.

  5. Actualizar a una versión más reciente (como 7.0+) ofrece un mejor rendimiento y mayor equidad en las eliminaciones TTL.