> Thanks for the response, i believe it won't work. First i have many
> items of different sizes, so i can't get them to one slab, having 2
> clients would be a performance hit because i'd need to make
> connections twice every request (unfortunately the part that handles
> SQL write stagging is reading/writing some cache data too)

You don't/can't use persistent connections?

> >But pulling the full list of keys back so you can find and fast reclaim some 
> >is definitely the wrong way to do that
> Why it's wrong? Maybe we can pull the items inside memcached and then
> call item_lock=>do_item_unlink=>do_item_remove=>item_unlock
>
> If we managed to fork the client every minute we won't have to use
> locking and it probably won't use too much memory too. If it won't be
> possible maybe we could lock one slab (not whole slab class) and just
> process a copy so we can have some inexpensive garbage collection. LRU
> is very lightweight (yes i get the point of not having long lasting
> LOCKs) but not suitable for all use patterns, because it can miss keys
> then you have uncontrolled slab growth and then you need to restart
> (well from my experience it does most of the time when you start to
> have different expiration times). Eg. last time (before using this
> PULL_LIST->CALL_GET method i had 20 million keys in cache, and all
> slabs in 3 classes now i have about 20-30k).
.
> Maybe we could even get rid of all the code that does garbage
> collection and LRU if we just make LRU to be on-slab-cleanup instead
> of on-item-access? (eg. every 10 seconds we'd process all items from
> LRU slab from top to bottom, then move the slab to bottom of LRU
> list). This maybe would allow to have just one-way list instead of 2
> way list and play better with CPU cache, so be more memory efficient.
> I have read the code for about 1 hour or two so probably most of my
> assumptions are wrong. Can anyone suggest most efficient way of making
> fast reclaim?

No, we're not doing that.

> For now im thinking about forking to be honest... i know 2GB lost is
> not much memory but with current LRU approach i can't see any metrics
> on how much memory i need to keep the thing using memcached running
> and even if i use only about 30-40MB of those 2GB for not-expired
> items i still get evictions.
>
> If we have this kind of garbage collection would you include this into
> the client? Don't know if I'll be able to do this or if there's anyone
> willing to help with this?
>
> Easiest thing would be probably just increase the LRU keys scanned to
> eg. 10k but it'll probably just kill the server :)

We will never do anything like that. ever. I don't understand why people
constantly "suggest" that we add feature that will screw up latency as a
workaround for the fact that they can't use persistent connections or come
up with some sort of minor workaround.

Everything is O(1) always, locking for a long scan is forbidden. The worst
we do is in slab rebalance, which holds a slab logically and glances at it
with tiny locks.

The idea I was playing with (which needs time for me to get to and a lot
of testing) is an option to split the LRU per-slab. With the option
enabled each slab class ends up with 3 LRU's, one for short expiration,
one for long, and one for infinite (maybe four LRU's, this is in process
of being thought about! I don't know yet!). Memcached then would use some
algorithm to determine what expiration time classifies as "short" or
"long" for the traffic it's seeing, and would sort them.

Then, on allocation it would check the bottom of each for an expired item.

I was also playing with the idea of LRU "lurkers" which walk up through
the list with tiny locks, but that's tricky to do well and is constantly
interrupting with mostly pointless small locks which can impact latency.

If you're going to insist that you need to do it your own bizarre way, I'd
suggest you check out the 1.6 beta (or engine-pu tree on github) and
write your own storage engine. That should be the easiest method for you.

Reply via email to