bytes > limit_maxbytes and no evictions?

Steve Grimm sgrimm at facebook.com
Sun Jun 24 21:30:55 UTC 2007


On 6/24/07 2:15 PM, "Steve Webb" <swebb at pronto.com> wrote:
> /usr/local/bin/memcached -d -p 11111 -u nobody -c 1024 -m 1024 -P
> /tmp/memcached1.pid

Your original message shows

> STAT limit_maxbytes 5242880

which seems inconsistent with that command line. That would be more like "-m
5" instead. It is no surprise memcached's memory usage is exceeding such a
tiny limit.

memcached uses a slab allocator that divides objects into ranges of sizes
("slab classes"). It allocates a 1MB slab to hold a set of objects of a
given slab class. To prevent bogus "out of memory" errors when a "set"
request comes in with an object in a previously unused slab class, it has a
policy of always allowing a single slab to be allocated in each slab class,
regardless of whether the configured maximum has already been reached.

There are 41 slab classes by default, so the worst-case behavior is that you
could exceed the configured maximum by 40MB. To get that worst-case
behavior, you'd have to initially fill the cache with objects of uniform
size, then afterwards store at least one object whose size falls in each of
the slab classes. (Run memcached with "-vv" to see a list of slab classes
with the maximum object size for each.)

This is not actually an issue in real-world deployments for two reasons.
First, on a cache of reasonable size, all you see in the worst case is an
extra 40MB on top of, say, a 1GB cache, probably barely even noticeable in
monitoring tools. Second, though, the worst case behavior will only happen
if, while the cache is initially getting populated, it is not getting a
range of object sizes. If your cache is of reasonable sizes, you will
probably have already allocated at least one slab in each class by the time
you hit the configured maximum, in which case memcached won't grow the cache
beyond that maximum at all.

If you are truly interested in running memcached with a miniscule cache like
5MB, then you should probably recompile it with the "-DUSE_SYSTEM_MALLOC"
option, which will bypass the slab allocator and use malloc() for the
individual objects. It is likely to be slower and you will get memory
fragmentation if your objects vary in size a lot.

-Steve



More information about the memcached mailing list