lericson / pylibmc

A Python wrapper around the libmemcached interface from TangentOrg.
http://sendapatch.se/projects/pylibmc/
BSD 3-Clause "New" or "Revised" License
481 stars 137 forks source link

Support "by masterkey" #53

Open holm opened 13 years ago

holm commented 13 years ago

It would be great if pylibmc could support the libmemcached functionality of hashing by master key instead of the actual key value. This allows to group related keys on the same memcached server, and avoid hitting many servers when getting or setting multiple values (get_multi, set_multi).

lericson commented 13 years ago

This is a very interesting feature! Perhaps we could make a more intuitive API than to extend get/set and friends, as this breaks new ground.

with mc.master_key("somekey"):
  mc.set_multi(dict.fromkeys("abcdef", "hi"))
  mc.get_multi("cbd")

Is what I come up with spontaneously, but I don't think it'll be very nice - imagine what happens if the with block code calls into eventlet.switch, making other Python code call master_key while one is already set? Should that give an error or what?

Much rather then that the master_key function return some kind of a proxy object, but then that proxy object will inevitably behave a lot like mc and people will probably confuse the two, it's simple to forget as submc and just assume it mutates mc.

holm commented 13 years ago

I think the proxy object would work well for our use-case. We are big user of multi-gets, and estimate we could save a lot of network traffic (and gain considerable performance), by hashing on a higher level.

Something like the following could be an option:

with mc.master_key("somekey") as mastered_mc:
  mastered_mc.get_multi(....)
holm commented 13 years ago

... and thanks for a great library, we use it with big satisfaction.

lericson commented 13 years ago

Hm, definitely needs a better name. There needs to be a logical name for the identifier, also what happens in this scenario:

with mc.master_key("a") as mmc:
  with mmc.master_key("b") as mmmc:
    # use mmmc

Edit: the logical thing would be for it to be equivalent to...

with mc.master_key("ab") as mmc:
  # use mmc