Mercurial > hg > memcached
comparison doc/memory_management.txt @ 0:30782bb1fc04 MEMCACHED_1_2_3
memcached-1.2.3
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 23 Sep 2007 03:58:34 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:30782bb1fc04 |
---|---|
1 Date: Fri, 5 Sep 2003 20:31:03 +0300 | |
2 From: Anatoly Vorobey <mellon@pobox.com> | |
3 To: memcached@lists.danga.com | |
4 Subject: Re: Memory Management... | |
5 | |
6 On Fri, Sep 05, 2003 at 12:07:48PM -0400, Kyle R. Burton wrote: | |
7 > prefixing keys with a container identifier). We have just begun to | |
8 > look at the implementation of the memory management sub-system with | |
9 > regards to it's allocation, de-allocation and compaction approaches. | |
10 > Is there any documentation or discussion of how this subsystem | |
11 > operates? (slabs.c?) | |
12 | |
13 There's no documentation yet, and it's worth mentioning that this | |
14 subsystem is the most active area of memcached under development at the | |
15 moment (however, all the changes to it won't modify the way memcached | |
16 presents itself towards clients, they're primarily directed at making | |
17 memcached use memory more efficiently). | |
18 | |
19 Here's a quick recap of what it does now and what is being worked | |
20 on. | |
21 | |
22 The primary goal of the slabs subsystem in memcached was to eliminate | |
23 memory fragmentation issues totally by using fixed-size memory chunks | |
24 coming from a few predetermined size classes (early versions of | |
25 memcached relied on malloc()'s handling of fragmentation which proved | |
26 woefully inadequate for our purposes). For instance, suppose | |
27 we decide at the outset that the list of possible sizes is: 64 bytes, | |
28 128 bytes, 256 bytes, etc. - doubling all the way up to 1Mb. For each | |
29 size class in this list (each possible size) we maintain a list of free | |
30 chunks of this size. Whenever a request comes for a particular size, | |
31 it is rounded up to the closest size class and a free chunk is taken | |
32 from that size class. In the above example, if you request from the | |
33 slabs subsystem 100 bytes of memory, you'll actually get a chunk 128 | |
34 bytes worth, from the 128-bytes size class. If there are no free chunks | |
35 of the needed size at the moment, there are two ways to get one: 1) free | |
36 an existing chunk in the same size class, using LRU queues to free the | |
37 least needed objects; 2) get more memory from the system, which we | |
38 currently always do in _slabs_ of 1Mb each; we malloc() a slab, divide | |
39 it to chunks of the needed size, and use them. | |
40 | |
41 The tradeoff is between memory fragmentation and memory utilisation. In | |
42 the scheme we're now using, we have zero fragmentation, but a relatively | |
43 high percentage of memory is wasted. The most efficient way to reduce | |
44 the waste is to use a list of size classes that closely matches (if | |
45 that's at all possible) common sizes of objects that the clients | |
46 of this particular installation of memcached are likely to store. | |
47 For example, if your installation is going to store hundreds of thousands of objects of the size exactly 120 bytes, you'd be much better | |
48 off changing, in the "naive" list of sizes outlined above, the class | |
49 of 128 bytes to something a bit higher (because the overhead of | |
50 storing an item, while not large, will push those 120-bytes objects over | |
51 128 bytes of storage internally, and will require using 256 bytes for | |
52 each of them in the naive scheme, forcing you to waste almost 50% of | |
53 memory). Such tinkering with the list of size classes is not currently | |
54 possible with memcached, but enabling it is one of the immediate goals. | |
55 | |
56 Ideally, the slabs subsystem would analyze at runtime the common sizes | |
57 of objects that are being requested, and would be able to modify the | |
58 list of sizes dynamically to improve memory utilisation. This is not | |
59 planned for the immediate future, however. What is planned is the | |
60 ability to reassign slabs to different classes. Here's what this means. | |
61 Currently, the total amount of memory allocated for each size class is | |
62 determined by how clients interact with memcached during the initial | |
63 phase of its execution, when it keeps malloc()'ing more slabs and | |
64 dividing them into chunks, until it hits the specified memory limit | |
65 (say, 2Gb, or whatever else was specified). Once it hits the limit, to | |
66 allocate a new chunk it'll always delete an existing chunk of the same | |
67 size (using LRU queues), and will never malloc() or free() any memory | |
68 from/to the system. So if, for example, during those initial few hours | |
69 of memcached's execution your clients mainly wanted to store very small | |
70 items, the bulk of memory allocated will be divided to small-sized | |
71 chunks, and the large size classes will get fewer memory, therefore the | |
72 life-cycle of large objects you'll store in memcached will henceforth | |
73 always be much shorter, with this instance of memcached (their LRU | |
74 queues will be shorter and they'll be pushed out much more often). In | |
75 general, if your system starts producing a different pattern of common | |
76 object sizes, the memcached servers will become less efficient, unless | |
77 you restart them. Slabs reassignment, which is the next feature being | |
78 worked on, will ensure the server's ability to reclaim a slab (1Mb of | |
79 memory) from one size class and put it into another class size, where | |
80 it's needed more. | |
81 | |
82 -- | |
83 avva |