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