MongoDB and memory

Source: Internet
Author: User
Tags mongodb server

Anyone who first came into contact with MongoDB was surprised that it was greedy for memory. For the reason, let me first talk about how Linux manages memory and how MongoDB uses memory, the answer is clear.

It is said that learning with problems is more effective, first look at the top command result of a MongoDB Server:

shell> top -p $(pidof mongod)Mem:  32872124k total, 30065320k used,  2806804k free,   245020k buffersSwap:  2097144k total,      100k used,  2097044k free, 26482048k cached VIRT  RES  SHR %MEM1892g  21g  21g 69.6

Is there any performance problem with this MongoDB server? You can continue reading while thinking.

First, let's talk about how Linux manages memory.

In Linux (similar to other systems), the memory has physical memory and virtual memory. There is no need to explain what physical memory is, and the virtual memory is actually an abstraction of physical memory, in most cases, for convenience, the program accesses a virtual memory address, and the operating system translates it into a physical memory address through the page table mechanism, for more information, see understanding memory and understanding virtual memory. For how the program uses virtual memory, see playing with virtual memory.

Many people will confuse virtual memory with swap. In fact, swap is only a technology derived from virtual memory: Once the operating system has insufficient physical memory, in order to free up memory space for new storage capacity, the content in the current physical memory will be put in the SWAp partition, and will be retrieved later. It should be noted that the use of swap may cause performance problems, and occasionally there is no need to worry about it, the bad thing is that the physical memory and swap partitions frequently exchange data, which is called swap bumps. Once this happens, you must first identify the cause, if the memory is insufficient, you can solve the problem by adding the memory. However, sometimes this problem may occur even if the memory is sufficient, for example, MySQL may, an optional solution is to restrict the use of swap:

shell> sysctl -w vm.swappiness=0

The free command is most commonly used to view memory conditions:

shell> free -m             total       used       free     shared    buffers     cachedMem:         32101      29377       2723          0        239      25880-/+ buffers/cache:       3258      28842Swap:         2047          0       2047

When a newbie sees that the value of used is too large, and the value of free column is too small, it is often considered that the memory is used up. In fact, this is not the case because every time we operate on a file, Linux will cache the file to the memory as much as possible, so that the next access time, the results can be obtained directly from the memory, so the value in the cached column is very large, but don't worry, this part of memory is recoverable, the Virtual Memory Manager of the operating system removes cold data according to the LRU algorithm. There is also a buffers that can be recycled, but it is reserved for Block devices.

After understanding the principle, we can calculate that the available memory of the system is free + buffers + cached:

shell> echo $((2723 + 239 + 25880))28842

The actual memory used by the system is used-Buffers-cached:

shell> echo $((29377 - 239 - 25880))3258

In addition to the free command, you can also use the sar command:

shell> sar -rkbmemfree kbmemused  %memused kbbuffers  kbcached  3224392  29647732     90.19    246116  26070160shell> sar -Wpswpin/s pswpout/s    0.00      0.00

I hope you are not scared by % memused. If you are unfortunate enough, re-read this article.

Let's talk about how MongoDB uses memory.

Currently, MongoDB uses the memory ing storage engine, which maps data files to the memory. For read operations, the data in the memory is cached. For write operations, memory can also convert random write operations into sequential write operations, which can greatly improve performance. MongoDB does not interfere with memory management, but leaves the work to the Virtual Memory Manager of the operating system for processing. The advantage of doing so is that it simplifies the work of MongoDB, but the disadvantage is that you have no way to easily control the memory occupied by MongoDB. Fortunately, the existence of the virtual memory manager makes us not need to care about this issue most of the time.

MongoDB's memory usage mechanism makes it more advantageous in cache reconstruction. In short, if the process is restarted, the cache is still valid. if the system is restarted, you can copy the data file to/dev/null to recreate the cache. For more details, see cache reheating-not to be ignored.

Sometimes, even if MongoDB uses a 64-bit operating system, it may encounter an OOM problem. In this case, it is mostly because the memory size is limited. You can check the current value as follows:

shell> ulimit -a | grep memory

By default, most operating systems are set to unlimited. If your operating system is not, you can modify it as follows:

shell> ulimit -m unlimitedshell> ulimit -v unlimited

Note: The use of ulimit has a context, and it is best to put it in the MongoDB STARTUP script.

Sometimes, if the number of MongoDB connections is too large, performance will be slowed down. You can query the number of connections through serverstatus:

mongo> db.serverStatus().connections

Each connection is a thread and requires a stack. The default stack settings in Linux are generally large:

shell> ulimit -a | grep stackstack size              (kbytes, -s) 10240

The actual size of the stack used by MongoDB can be confirmed using the following command (unit: K ):

shell> cat /proc/$(pidof mongod)/limits | grep stack | awk -F 'size' '{print int($NF)/1024}'

If the stack size is too large (for example, 10240 K), it makes no sense to simply compare the size and RSS in the command results:

shell> cat /proc/$(pidof mongod)/smaps | grep 10240 -A 10

The memory consumed by all connections is astonishing. We recommend that you set the stack to a smaller value, for example, 1024:

shell> ulimit -s 1024

Note: From mongodb1.8.3, MongoDB automatically sets the stack at startup.

Sometimes, for some reason, you may want to release the memory occupied by MongoDB, but as mentioned above, the memory management work is controlled by the Virtual Memory Manager, fortunately, you can use the MongoDB built-in closealldatabases command to achieve the goal:

mongo> use adminmongo> db.runCommand({closeAllDatabases:1})

In addition, you can release the cache by adjusting the Kernel Parameter drop_caches:

shell> sysctl -w vm.drop_caches=1

You can use the Mongo command line to monitor the memory usage of MongoDB as follows:

mongo> db.serverStatus().mem:{    "resident" : 22346,    "virtual" : 1938524,    "mapped" : 962283}

You can also use the mongostat command to monitor MongoDB memory usage, as shown below:

shell> mongostatmapped  vsize    res faults  940g  1893g  21.9g      0

The memory-related fields have the following meanings:

  • Mapped: The data size mapped to the memory.
  • Visze: Virtual Memory Used
  • Res: physical memory used

Note: If the operation cannot be completed in the memory, the value of the result faults column will not be 0, and performance problems may occur depending on the size.

In the above results, vsize is twice the size of the mapped, and mapped is equal to the size of the data file. Therefore, vsize is twice the size of the data file, mongoDB has enabled journal and needs to map data files once more in the memory. If journal is disabled, the vsize and mapped are roughly the same.

To verify this, you can use the pmap command to observe the file ing after you enable or disable Journal:

shell> pmap $(pidof mongod)

What size of memory is suitable for MongoDB? Broadly speaking, it is more beneficial. To be specific, this depends on your data and index size. It is best to add indexes for all data in the memory. However, in many cases, the data is larger than the memory, for example, the MongoDB instance involved in this article:

mongo> db.stats(){    "dataSize" : 1004862191980,    "indexSize" : 1335929664}

In this example, the index is more than 1 GB, the memory can be fully loaded, and the data file reaches 1 Tb. It is estimated that it is difficult to find such a large memory. At this time, ensure that the memory can be loaded with hot data, the amount of hot data depends on the specific application. As a result, the memory size is clear: Memory> index + hot data, it is better to have a little surplus, after all, the operating system itself needs to consume a part of the memory for normal operation.

For more information about MongoDB and memory, see the official documentation.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.