This article discusses the memory allocation mechanism of memcached. Here are some opinions:
Memcached uses the Slab allocator mechanism to allocate and manage memory by default, which is a pre-allocation method. Let's take a look at the principle of Slab allocator.
Below are the objectives of Slab allocator in the memcached document:
"The primary goal of the slabs subsystem in memcached was to eliminate memory fragmentation issues totally by using fixed-size memory chunks coming from a few predetermined size classes ."
That is to say, the basic principle of Slab allocator is to divide the allocated memory into blocks of a specific length according to the predefined size to completely solve the memory fragmentation problem.
Because the pre-allocation method is used, memcached will not release the allocated memory, but will reuse the allocated memory, which causes the data loss and hit reduction mentioned below.
Memcached preferentially uses the time-out record space to reuse allocated memory, but even so, there will be insufficient space-time for appending new records,
In this case, the least recently used (LRU) mechanism is used to allocate space. As the name suggests, this is a mechanism to delete records that are "least recently used.
Therefore, when memcached has insufficient memory space (when the new space cannot be obtained from the slab class), it will be searched from the records that have not been used recently, and allocate the space to the new record.
From the perspective of caching, this model is ideal. However, the following application scenarios may cause problems.
When starting memcached, you can use the following method to increase the memory allocation or disable LRU to avoid this problem:
$ memcached -M -m 1024
The "-M" parameter indicates that LRU is disabled. The "-M" option is used to specify the maximum memory size. If no specific value is specified, the default value is 64 MB.
After all, memcached is mainly used as a cache, so we recommend that you enable LRU. If you need persistent storage, you can consider using redis.
The original reprinted text is as follows:
Memcached, a well-known remote distribute
Cache is also very simple to use. It is used on many websites, and almost few large websites do not use memcached.
I have read a lot of articles on analyzing the internal mechanism of memcached, But I have forgotten it and I have no profound concepts. However, I recently encountered a problem, this problem forces me to get to know memcache again. Next I will explain my problems.
Problem: I have tens of millions of data that will be frequently used. Currently, it must be stored in memcached to ensure access speed, but data in my memcached is often used
Some data is lost, but the data in memcached cannot be lost. When my data is lost, memcached
The server memory is only 60%, that is, 40% of the memory is seriously wasted. But not all applications are like this, and other applications have less memory waste. Why is the memory used?
When 60%, LRU was executed. (It was determined that LRU was executed because I found that my data was always put in front, and in this process, the data was not accessed, for example, the first time
Only million entries can be accessed, and million or earlier data is lost. From the log, million entries must be included ).
With these questions, I began to review the memcached product. First, we started from its memory model: we know that there are two ways to allocate memory in C ++: pre-allocation and dynamic allocation, apparently
Allocating memory first will make the program faster, but its disadvantage is that it cannot effectively use the memory, while dynamic allocation can effectively use the memory, but will reduce the program running efficiency. memcached memory allocation is
Based on the above principle, it is obvious that in order to get a faster speed, sometimes we have to change the time with space.
That is to say, memcached will allocate memory in advance. By the way, memcached allocates memory in Allocator mode. First, there are three concepts:
1 Slab
2 page
3 chunk
Generally, a memcahced process divides itself into several slabs in advance. Each slab has several pages, and each page has multiple
Chunk. If we think of the three Doon as the object, this is a one-to-many relationship. Generally speaking, the number of slab instances is limited to a few, dozens, or dozens.
It depends on the memory configured by the process. The default page size for each slab is 1 MB. That is to say, if an slab occupies MB of memory, the default slab has
The number of pages is 100, and the chunk is the final place where data is stored.
For example, if I start a memcached process that occupies 100 MB of memory, telnet and telnet localhost 11211. After connecting to memcache, enter stats slabs and press enter to display the following data:
- Stat 1: chunk_size 80
- Stat 1: chunks_per_page 13107
- Stat 1: total_pages 1
- Stat 1: total_chunks 13107
- Stat 1: used_chunks 13107
- Stat 1: free_chunks 0
- Stat 1: free_chunks_end 13107
- Stat2: chunk_size 100
- Stat 2: chunks_per_page 10485
- Stat 2: total_pages 1
- Stat 2: total_chunks 10485
- Stat 2: used_chunks 10485
- Stat 2: free_chunks 0
- Stat 2: free_chunks_end 10485
- Stat 3: chunk_size 128
- Stat 3: chunks_per_page 8192
- Stat 3: total_pages 1
- Stat 3: total_chunks 8192
- Stat 3: used_chunks 8192
- Stat 3: free_chunks 0
- Stat 3: free_chunks_end 8192
The above is the detailed information of the first three slabs.
Chunk_size indicates the size of data storage blocks, and chunks_per_page indicates the number of chunks in a memory page.
Total_pages indicates the number of pages under each slab. Total_chunks indicates the total number of chunks in this slab (= total_pages
*
Chunks_per_page), used_chunks indicates the number of chunks used in the slab, and free_chunks indicates that the slab can also
The number of chunks used.
From the above example, slab 1 has a total of 1 MB of memory space, and now it has been used up. slab2 also has 1 MB of memory space and is also used up. slab3 still has this situation.
The chunk size in the three slab shows that the first chunk is 80B, the second is 100b, and the third is 128b. Basically, the last one is the first one.
1.25 times, but we can control this growth. We can modify this value by getting the process parameter-f at startup, for example,-f.
1.1 indicates that the growth factor is 1.1. If the chunk in the first slab is 80 B, the chunk in the second slab should be about 80*1.1.
If I have explained so many problems, I can see the cause. If I still cannot see the cause, I would like to add the following key sentence: the address for storing the new value in memcached is
The size of the value is determined. The value is always stored in the slab closest to the chunk. For example, in the above example, if my value is 80B
All values are always stored in slab 1, and free_chunks in slab 1 are already 0. What should I do if you start memcached
No append-M (LRU is disabled. In this case, the out
Memcached clears the data in the chunk that is least recently used in this slab, and then puts the latest data. This explains why my memory still exists.
40%, LRU is executed, because chunk_size in my other slab is much larger than my value, so my value will not be placed in those slab,
Instead, it will only be placed in the slab where the chunk closest to my value is located (and these slab are already full and depressing ). As a result, my data is constantly overwritten, and the latter overwrites the former.
The problem is found, and the solution is still not found, because my data must require a hit rate of 100%. I can only adjust the slab Growth Factor and page size to maximize the hit rate.
The hit rate is close to 100%, but it cannot be 100%. (How can this problem be difficult to read? I will review my language skills, because of my
The memcached server cannot be stopped. It doesn't matter if there is another method: memcached-tool, execute the move command, for example, Move 3.
1 indicates moving a memory page in slab 3 to slab 1. Someone asked, What is the use of this page? For example, my slab 20 has a very low utilization rate, but there are many pages,
For example, 200 is 200 m, and 2 Slab often has LRU, obviously the page is not enough, so I can move 20
2. Move a memory page of slab No. 20 to slab No. 2 to make more effective use of the memory. (Some people have said that it is troublesome to move only one page at a time? Ahuaxuan
Let's just write a script and repeat it ).
Some people say no. Data in my memcache cannot be lost. OK. Try memcachedb of Sina. Although I have never used it, I suggest you try it.
Memcache protocol and berkeleydb (here, I have to admire danga. I think its biggest contribution is not memcache.
Server itself, but the memcache Protocol). It is said that it is used in many Sina applications, including Sina's blog.
In addition, the stats slab command can view the slab situation in memcached, while the stats command can view some of your memcached health conditions, such as the hit rate, for example:
- Stat PID 2232
- Statuptime 1348
- Stat time 1218120955
- Stat version 1.2.1
- Stat pointer_size 32
- Stat curr_items 0
- Stat total_items 0
- Stat bytes 0
- Stat curr_connections 1
- Stat total_connections 3
- Stat connection_structures 2
- Stat performance_get 0
- Stat performance_set 0
- Stat get_hits 0
- Stat get_misses 0
- Stat bytes_read 26
- Stat bytes_written 16655
- Stat limit_maxbytes 104857600
From the above data, we can see that the memcached process has a very good hit rate. The get_misses rate is as low as 0. What's the problem? I just used this process to start it.
When telnet is connected, the value of curr_connections is 1 and that of total_items is 0. Because I didn't put the data in, the value of get_hits is 0 because I
If the get method is not called, the final result is that misses is 0, of course. Wow, in other words, the hit rate is 100%, and then yy.
The conclusion is as follows:
Conclusion 1: The LRU obtained by memcached is not global, but for slab. It can be said that it is regional.
Conclusion 2: To increase the memcached hit rate, it is necessary to estimate the value size and adjust the memory page size and growth factor appropriately.
Conclusion 3: finding answers with questions is much better than simply looking at them.
OK. It's late. I'm asleep.
Address: http://www.iteye.com/topic/225692