阿里云主机折上折
  • 微信号
Current Site:Index > Best practices and common issue troubleshooting

Best practices and common issue troubleshooting

Author:Chuan Chen 阅读数:3113人阅读 分类: MongoDB

Best Practices

Index Optimization

In MongoDB, proper index design can significantly improve query performance. The order of compound indexes follows the ESR principle (Equality, Sort, Range):

  • Fields for equality queries come first
  • Sort fields are placed in the middle
  • Range query fields are placed last
// Good index example
db.orders.createIndex({ 
  userId: 1,       // Equality
  createDate: -1,  // Sort
  amount: 1        // Range
})

Avoid over-indexing, as each additional index increases write overhead. Use explain() to analyze query execution plans:

db.orders.find({
  userId: "user123",
  createDate: { $gt: ISODate("2023-01-01") }
}).sort({ amount: 1 }).explain("executionStats")

Document Design

Choose between embedding or referencing based on query patterns:

  • One-to-few relationships with frequent joint queries are suitable for embedding
  • One-to-many relationships or independently accessed data are suitable for referencing
// Embedded document example (suitable for blog posts and comments)
{
  _id: "post1",
  title: "MongoDB Guide",
  comments: [
    { user: "Alice", text: "Great article", date: ISODate(...) },
    { user: "Bob", text: "Very helpful", date: ISODate(...) }
  ]
}

// Reference example (suitable for users and orders)
// users collection
{ _id: "user1", name: "John" }

// orders collection
{ _id: "order1", userId: "user1", items: [...] }

Write Optimization

Use bulkWrite() for batch operations instead of single writes:

const bulkOps = [
  { insertOne: { document: { name: "Product A", price: 100 } } },
  { updateOne: { 
    filter: { name: "Product B" },
    update: { $set: { price: 200 } }
  }},
  { deleteOne: { filter: { name: "Product C" } }}
];

db.products.bulkWrite(bulkOps);

Set appropriate write concern levels to balance data safety and performance:

// Majority node confirmation for writes
db.products.insertOne(
  { name: "New Product", stock: 50 },
  { writeConcern: { w: "majority", j: true } }
)

Common Issue Troubleshooting

Performance Issues

Slow queries are typically caused by:

  1. Missing or improper indexes
  2. Full collection scans
  3. In-memory sorts (sorts that cannot use indexes)

Use db.currentOp() to view ongoing operations:

// View operations running longer than 3 seconds
db.currentOp({
  "active": true,
  "secs_running": { "$gt": 3 }
})

Monitor database activity with mongotop and mongostat:

mongotop --host localhost:27017
mongostat --host localhost:27017 --rowcount 5

Connection Issues

Connection pool exhaustion manifests as applications being unable to acquire new connections. Adjust connection pool size:

// Node.js driver example
const client = new MongoClient(uri, {
  poolSize: 50,            // Connection pool size
  connectTimeoutMS: 30000, // Connection timeout
  socketTimeoutMS: 60000   // Socket timeout
});

Check connection status:

db.serverStatus().connections
// Example output
{
  "current" : 25,
  "available" : 475,
  "totalCreated" : 42
}

Memory Usage

MongoDB tends to use all available memory as cache. Monitor memory usage:

db.serverStatus().mem
// Typical output
{
  "bits" : 64,
  "resident" : 1024,  // Resident memory (MB)
  "virtual" : 2048,   // Virtual memory (MB)
  "supported" : true
}

When memory pressure occurs:

  1. Check if the working set exceeds physical memory
  2. Add more RAM
  3. Optimize queries to reduce memory usage

Replica Set Issues

Common replication delay causes:

  • Insufficient network bandwidth
  • Underpowered secondary nodes
  • High write load on primary node

Check replication status:

rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()

// Detailed status
rs.status()

Handling replication delays:

  1. Increase oplog size
  2. Upgrade secondary node configurations
  3. Limit primary node write rate

Sharded Cluster Issues

Common sharded cluster issues include:

  • Uneven data distribution
  • Queries not including shard keys
  • High configuration server load

Check data distribution:

db.collection.getShardDistribution()

Balancer status check:

sh.isBalancerRunning()
sh.getBalancerState()

Shard key selection principles:

  1. High cardinality (many distinct values)
  2. Even write distribution
  3. Matches query patterns

Lock Contention

MongoDB uses multi-granularity locking. View lock status:

db.currentOp({ "waitingForLock": true })
db.serverStatus().locks

Methods to reduce lock contention:

  1. Shorten transaction duration
  2. Avoid full collection scans
  3. Use appropriate write concern levels

Transaction Handling

Multi-document transaction considerations:

  • Maximum transaction runtime of 60 seconds
  • Limit on total operations in a transaction
  • Avoid creating collections within transactions

Transaction example:

const session = client.startSession();
try {
  session.startTransaction({
    readConcern: { level: "snapshot" },
    writeConcern: { w: "majority" }
  });

  await accounts.updateOne(
    { _id: "A" }, { $inc: { balance: -100 } },
    { session }
  );
  
  await accounts.updateOne(
    { _id: "B" }, { $inc: { balance: 100 } },
    { session }
  );

  await session.commitTransaction();
} catch (error) {
  await session.abortTransaction();
  throw error;
} finally {
  session.endSession();
}

Storage Engine Issues

WiredTiger engine tuning:

// View storage engine status
db.serverStatus().wiredTiger

// Adjust cache size (in configuration file)
storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2

Compression configuration:

storage:
  wiredTiger:
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true

Query Optimizer

The MongoDB query optimizer may choose non-optimal execution plans. Force using specific indexes:

db.orders.find({ userId: "123", status: "A" })
  .hint({ userId: 1, status: 1 })

Rebuild indexes:

db.orders.reIndex()

Date Handling

Common date query issues include timezone handling and format conversion:

// Query documents for a specific date (UTC time)
db.events.find({
  date: {
    $gte: ISODate("2023-01-01T00:00:00Z"),
    $lt: ISODate("2023-01-02T00:00:00Z")
  }
})

// Use aggregation to convert timezones
db.events.aggregate([
  {
    $project: {
      localDate: {
        $dateToString: {
          format: "%Y-%m-%d %H:%M",
          date: "$date",
          timezone: "+08:00"
        }
      }
    }
  }
])

Array Operations

Common array query and update issues:

// Query arrays containing specific elements
db.products.find({ tags: "electronics" })

// Update specific elements in arrays
db.products.updateOne(
  { _id: 1, "variants.id": "v1" },
  { $set: { "variants.$.price": 19.99 } }
)

// Use $elemMatch for multiple condition queries
db.survey.find({
  results: {
    $elemMatch: { 
      product: "xyz", 
      score: { $gte: 8 } 
    }
  }
})

Security Configuration

Common security configuration issues:

  1. Authentication not enabled
  2. Weak passwords
  3. Network exposure

Basic security configuration:

security:
  authorization: enabled
  keyFile: /path/to/keyfile

net:
  bindIp: 127.0.0.1,192.168.1.100
  port: 27017

Create users:

db.createUser({
  user: "admin",
  pwd: passwordPrompt(), // or plaintext password
  roles: [ 
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" }
  ]
})

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:事务在应用中的使用

下一篇:引用规范

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.