阿里云主机折上折
  • 微信号
Current Site:Index > Memory management and cache optimization

Memory management and cache optimization

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

Fundamentals of Memory Management

MongoDB's memory management directly impacts query performance and system stability. The WiredTiger storage engine defaults to using a memory-mapped file mechanism, mapping data files to memory address spaces. The storage.wiredTiger.engineConfig.cacheSizeGB parameter can be configured to set the cache size, recommended at 50%-70% of physical memory. When the working set exceeds cache capacity, page swapping occurs. Cache hit rates can be monitored via db.serverStatus().wiredTiger.cache:

// View cache usage
const cacheStats = db.serverStatus().wiredTiger.cache;
print(`Bytes read into cache: ${cacheStats['bytes read into cache']}`);
print(`Bytes written from cache: ${cacheStats['bytes written from cache']}`);
print(`Pages evicted: ${cacheStats['pages evicted']}`);

Working Set Optimization

The working set refers to the residency of active data in memory. Collection working set characteristics can be analyzed using db.collection.stats():

const stats = db.orders.stats();
print(`Working set size: ${stats.size} bytes`);
print(`Index size: ${stats.totalIndexSize} bytes`);

Optimization strategies include:

  1. Vertical sharding: Separate large fields into independent collections
  2. Hot data isolation: Store frequently accessed data in centralized locations
  3. Preloading: Use the touch command to load indexes at startup

Index Memory Optimization

Indexes are major memory consumers. Compound index design should follow the ESR principle:

  • Equality (fields for equality queries come first)
  • Sort (sort fields in the middle)
  • Range (fields for range queries come last)

Example before optimization:

db.products.createIndex({ category: 1, price: 1, rating: -1 })

After optimization:

db.products.createIndex({ category: 1, rating: -1, price: 1 })

Be mindful of memory overhead when using hint() to enforce indexes:

db.orders.find({ status: "shipped" })
  .sort({ created_at: -1 })
  .hint({ status: 1, created_at: -1 })

Query Memory Control

Use cursor.maxTimeMS() and allowDiskUse to control memory usage:

// Limit query memory usage
db.reports.aggregate([
  { $match: { year: 2023 } },
  { $group: { _id: "$department", total: { $sum: "$sales" } } }
], {
  maxTimeMS: 30000,
  allowDiskUse: true
})

For large result sets, use batch fetching:

const batchSize = 1000;
let cursor = db.logs.find().batchSize(batchSize);
while (cursor.hasNext()) {
  const docs = cursor.next();
  // Process documents
}

Write Memory Optimization

Batch inserts are 3-5 times more memory-efficient than single inserts:

// Inefficient approach
for (let i = 0; i < 1000; i++) {
  db.measurements.insert({ value: Math.random() });
}

// Efficient approach
const bulk = db.measurements.initializeUnorderedBulkOp();
for (let i = 0; i < 1000; i++) {
  bulk.insert({ value: Math.random() });
}
bulk.execute();

For updates, use $set instead of full document replacement:

// Not recommended
db.users.update({ _id: 1 }, { name: "New", email: "new@example.com" });

// Recommended
db.users.update({ _id: 1 }, { $set: { name: "New", email: "new@example.com" } });

Connection Pool Tuning

Connection pool size affects memory usage and concurrent performance. Calculation formula:

Maximum connections = (Core count * 2) + Effective disk count

Configuration example:

# mongod.conf
net:
  maxIncomingConnections: 500
  serviceExecutor: "adaptive"

Monitor connection usage:

const connStats = db.serverStatus().connections;
print(`Available connections: ${connStats.available}`);
print(`Current in use: ${connStats.current}`);

Operating System-Level Optimization

Linux systems require kernel parameter adjustments:

# Increase memory page size
sysctl -w vm.nr_hugepages=1024

# Adjust dirty page ratios
sysctl -w vm.dirty_ratio=20
sysctl -w vm.dirty_background_ratio=5

Use cgroups to limit MongoDB memory:

cgcreate -g memory:mongodb
cgset -r memory.limit_in_bytes=16G mongodb

Monitoring and Diagnostic Tools

Real-time monitoring tools:

// Current memory status
db.currentOp(true).inprog.forEach(op => {
  if(op.memUsage) print(`Op ${op.opid} using ${op.memUsage}MB`);
});

// Periodic sampling
setInterval(() => {
  const mem = db.serverStatus().mem;
  print(`Resident: ${mem.resident}MB Virtual: ${mem.virtual}MB`);
}, 5000);

Use mongotop and mongostat to analyze hotspots:

mongotop --host localhost --rows 5 --seconds 3
mongostat --host localhost --discover --all

Sharded Cluster Memory Management

Special considerations for sharded clusters:

  1. Config servers: Maintain small working sets
  2. Query routers: Increase mongos memory
  3. Data shards: Balance shard distribution

Check shard balance status:

db.adminCommand({ balancerStatus: 1 });
db.adminCommand({ getShardDistribution: "db.collection" });

Adjust chunk size to impact memory usage:

db.settings.update(
  { _id: "chunksize" },
  { $set: { value: 64 } },
  { upsert: true }
);

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

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

上一篇:慢查询分析与优化

下一篇:磁盘IO优化

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 ☕.