Foundations of Python Network Programming

(WallPaper) #1

Chapter 8 ■ CaChes and Message Queues


138


The actual procedure for using Memcached is designed to be simple.

•    You run a Memcached daemon on every server with some spare memory.

•    You make a list of the IP address and port numbers of your new Memcached daemons and
distribute this list to all of the clients that will be using the cache.

•    Your client programs now have access to an organization-wide, blazingly fast key-value cache
that acts something like a big Python dictionary that all of your servers can share. The cache
operates on an LRU basis, dropping old items that have not been accessed for a while so that it
has room to both accept new entries and keep records that are being frequently accessed.

Enough Python clients are currently listed for Memcached that I had better just send you to the page that lists
them, rather than try to review them here: http://code.google.com/p/memcached/wiki/Clients.
The client listed first is written in pure Python, and thus it will not need to compile against any libraries. It should
install quite cleanly into a virtual environment (see Chapter 1), thanks to being available on the Python Package
Index. The version for Python 3 can be installed with a single command.


$ pip install python3-memcached


The API for this package is straightforward. Though you might have expected an interface that more strongly
resembles a Python dictionary with native methods like getitem(), the author of this API chose instead to use
the same method names as are used in other languages supported by Memcached. This was a good decision since it
makes it easier to translate Memcached examples into Python. A simple interaction at the Python prompt, if you have
Memcached installed and running on your machine at its default port of 11211, might run as follows:





import memcache
mc = memcache.Client(['127.0.0.1:11211'])
mc.set('user:19', 'Simple is better than complex.')
True
mc.get('user:19')
'Simple is better than complex.'





You can see that the interface here is very much like that of a Python dictionary. When you submit a string as a
value like this, the string gets written directly to Memcached as UTF-8 and is then decoded again when you fetch it
later. Any other kind of Python object besides a simple string will trigger the memcache module to auto-pickle the value
for you (see Chapter 5) and store the binary pickle in Memcached. Keep this difference in mind in case you ever write
a Python application that is sharing a Memcached cache with clients written in other languages. Only the values you
save as strings will be decipherable to clients written in other languages.
Always keep in mind that data stored in Memcached can be thrown away at the server’s discretion. The cache is
designed to speed up operations by remembering results that are expensive to recompute. It is not designed to store
data that you cannot reconstruct from other sources of information! If the previous commands were run against a
busy enough Memcached and if enough time elapsed between the set() and the get() operation, then the get()
could easily find that the string had expired from the cache and was no longer present.
Listing 8-1 shows the basic pattern by which Memcached is used from Python. Before embarking on an
(artificially) expensive integer-squaring operation, this code checks Memcached to see whether the answer is already
stored in the cache. If so, then the answer can be returned immediately without needing to be recomputed. If not,
then it is computed and stored in the cache before being returned.

Free download pdf