Mejores prácticas de rendimiento
Utilice esta información para aplicar las mejores prácticas a su implantación de Databases for MongoDB en IBM Cloud.
Diagrama de flujo de resolución de problemas de rendimiento
Utilice el diagrama de flujo para determinar cómo solucionar los problemas de rendimiento y los pasos a seguir.
┌─────────────────────────────────┐
│ Performance issue detected │
└────────────┬────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Check IBM Cloud Monitoring │
│ - CPU > 80%? │
│ - Memory > 80%? │
│ - Disk latency high? │
└────────────┬────────────────────┘
│
┌────┴────┐
│ YES │
▼ │
┌──────────────┐ │
│ Scale │ │
│ resources │ │
└──────────────┘ │
│ NO
▼
┌─────────────────────┐
│ Check slow queries │
│ db.system.profile │
└─────────┬───────────┘
│
┌────┴────┐
│ Found? │
▼ │
┌─────────┐ │
│ Optimize│ │
│ queries │ │
│ & indexes│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check Locks │
│ currentOp() │
└────────┬───────┘
│
┌────┴────┐
│ Locked? │
▼ │
┌─────────┐ │
│ Kill or │ │
│ optimize│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check cache │
│ hit ratio │
└────────┬───────┘
│
┌────┴────┐
│ < 95%? │
▼ │
┌─────────┐ │
│ Scale │ │
│ memory │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check │
│ replication │
└────────┬───────┘
│
┌────┴────┐
│ Lagging?│
▼ │
┌─────────┐ │
│ Scale │ │
│ or fix │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Contact IBM │
│ Support │
└────────────────┘
Antimodelos habituales
Evite estos errores comunes que provocan problemas de rendimiento.
Antipatrones de consulta
1. Índices que faltan
Problema:
// No index on 'email' field
db.users.find({ email: "user@example.com" })
Solución:
// Create index
db.users.createIndex({ email: 1 })
2. Consultas regex ineficaces
Problema:
// Case-insensitive regex without index
db.users.find({ name: /john/i })
Solución:
// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })
3. Grandes operaciones de skip()
Problema:
// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)
Solución:
// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)
4. Selección de campos innecesarios
Problema:
// Fetching entire documents
db.users.find({ status: "active" })
Solución:
// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })
5. Tuberías de agregación ineficaces
Problema:
// $match after $lookup
db.orders.aggregate([
{ $lookup: { ... } },
{ $match: { status: "completed" } }
])
Solución:
// $match first to reduce documents
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $lookup: { ... } }
])
Cuestiones de diseño de esquemas
1. Matrices no limitadas
Problema:
// Array grows indefinitely
{
userId: 123,
activities: [/* thousands of items */]
}
Solución:
// Use separate collection or bucketing
{
userId: 123,
month: "2024-01",
activities: [/* limited items */]
}
2. Incrustación excesiva
Problema:
// Deeply nested documents
{
user: {
profile: {
settings: {
preferences: {
// many levels deep
}
}
}
}
}
Solución:
// Flatten or use references
{
userId: 123,
profileId: 456
}
3. Documentos de gran tamaño
Problema:
// Documents approaching 16MB limit
{
data: "very large string...",
attachments: [/* large binary data */]
}
Solución:
// Store large data separately (GridFS or object storage)
{
dataRef: "s3://bucket/key",
attachments: [{ ref: "gridfs://id" }]
}
Errores en la gestión de las conexiones
1. No utilizar la agrupación de conexiones
Problema:
// Creating new connection per request
app.get('/api/users', async (req, res) => {
const client = await MongoClient.connect(uri);
// ...
await client.close();
});
Solución:
// Reuse connection pool
const client = new MongoClient(uri, { maxPoolSize: 50 });
await client.connect();
app.get('/api/users', async (req, res) => {
const db = client.db();
// ...
});
2. No cerrar cursores
Problema:
// Cursor left open
const cursor = db.collection.find();
// Never closed
Solución:
// Always close cursors
const cursor = db.collection.find();
try {
await cursor.forEach(doc => { /* process */ });
} finally {
await cursor.close();
}
3. Demasiadas conexiones
Problema:
// One connection per user session
const connections = new Map();
users.forEach(user => {
connections.set(user.id, new MongoClient(uri));
});
Solución:
// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool
Errores de indexación
1. Demasiados índices
Problema:
// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes
Impacto: Ralentiza las escrituras y aumenta el almacenamiento.
Solución: Mantener sólo los índices necesarios y utilizar índices compuestos.
2. Orden incorrecto de los índices compuestos
Problema:
// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 } // Wrong order
Solución:
// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })
3. No utilizar consultas cubiertas
Problema:
// Index exists but query not covered
db.users.createIndex({ email: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1 })
// Still fetches documents
Solución:
// Include all projected fields in index
db.users.createIndex({ email: 1, name: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1, _id: 0 })
Apéndice: umbrales de las métricas
Umbrales recomendados para las principales métricas de rendimiento.
| Métrica | Umbral de aviso | Umbral crítico | Acción recomendada |
|---|---|---|---|
| Uso de CPU | 75% | 90% | Escala de núcleos de CPU |
| Utilización de memoria | 80% | 95% | Asignación de memoria a escala |
| Utilización de disco | 80% | 90% | Escalar el espacio en disco |
| IOPS de disco | 80% del límite | 95% del límite | Aumentar el tamaño del disco para obtener más IOPS |
| Conexiones activas | 80% del límite | 95% del límite | Plan de escalado u optimización de la agrupación de conexiones |
| Retardo de réplica | 5 segundos | 30 segundos | Investigar y ampliar si es necesario |
| Proporción de accesos a la memoria caché | < 95% | < 90% | Escalar la memoria u optimizar las consultas |
| Tiempo de ejecución de la consulta |
|
|
Optimización de consultas e índices |
| Tiempo de espera de bloqueo |
|
|
Optimice las operaciones y elimine las consultas de larga duración |
| Errores de página |
|
|
Memoria de escala |
| Latencia de red |
|
|
Comprobar la configuración de la red |
| Duración de copia de seguridad | 1 hora | 4 horas | Considerar la ampliación u optimización |
Recomendaciones sobre la frecuencia de los controles
| Categoría de medida | Frecuencia de comprobación | Periodo de retención |
|---|---|---|
| Utilización de recursos | Cada 1 minuto | 30 días |
| Rendimiento de consultas | Cada 5 minutos | 14 días |
| Estado de réplica | Cada 1 minuto | 30 días |
| Estadísticas de conexión | Cada 5 minutos | 14 días |
| Estado de copia de seguridad | Cada hora | 90 días |
| Crecimiento del disco | Cada hora | 90 días |
Ejemplos de configuración de alertas
Alerta CPU
Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes
Alerta de memoria
Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes
Alerta de retraso en la replicación
Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds
Alerta de espacio en disco
Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%
Resumen de buenas prácticas
| Área | Recomendación |
|---|---|
| Indexación | Revisar y eliminar periódicamente los índices no utilizados |
| Monitoring | Configuración de alertas de retardo de CPU, memoria, disco y replicación |
| Planificación de la capacidad | Mantenga el uso del disco por debajo del 80% y escale de forma proactiva |
| Diseño de consultas | Utilizar planes explicativos durante el desarrollo |
| Escalado | Escala proactiva antes de la saturación |
| técnica de agrupación de conexiones | Utilizar agrupaciones de conexiones y evitar las conexiones por solicitud |
| Leer preferencias | Utilizar secundarios para cargas de trabajo de lectura intensiva |
| Escribir preocupación | Equilibrio entre durabilidad y rendimiento |
| Diseño de esquemas | Evitar las matrices no delimitadas y la incrustación excesiva |
| Planificación de copias de seguridad | Horario en periodos de poco tráfico |
| Red | Utilice puntos finales privados para las cargas de trabajo de IBM Cloud |
| Seguridad | Rote las credenciales con regularidad y utilice listas de IP permitidas |
| Documentación | Documentar las métricas de referencia y los patrones normales |
| Pruebas | Pruebe primero los cambios de rendimiento en la fase de no producción |
| Soporte | Recopilar diagnósticos antes de ponerse en contacto con el servicio de asistencia |