How to incorporate memcached into your environment?
Before we start installing and using using memcached, we need to understand how to incorporate memcached into your environment. While memcached can be used anywhere, I've found that memcached tends to be most useful when I need to perform a few frequent queries in the database layer. I often set up a series of memcached instances between the database and application servers, and use a simple pattern to read and write to these servers. Figure 1 can help you understand how to set up your application architecture:
Figure 1. Example application architecture using memcached
The architecture is fairly easy to understand. I've set up a web tier that includes some Apache instances. The next layer is the application itself. This layer typically runs on top of Apache Tomcat or other open source application servers. One further layer down is where the memcached instance is configured—that is, between the application server and the database server. When using this configuration, database reads and writes need to be performed in a slightly different way.
The order in which I do the read operation is to get the request from the web tier (which needs to perform a database query) and check the result of the query previously stored in the cache. If I find the desired value, I return it. If not found, execute the query and store the result in the cache before returning the result to the web tier.
When writing data to the database, first perform a database write operation and then invalidate any previously cached results affected by this write operation. This process helps prevent data inconsistencies between the cache and the database.
memcached supports several operating systems, including Linux®, Windows®, Mac OS, and Solaris. In this article, I'll detail how to build and install memcached from source. The main reason for doing it this way is so that I can look at the source code when I have a problem.
libevent is the only prerequisite for memcached to be installed. It is the asynchronous event notification library that memcached relies on. You can find the source files for libevent at monkey.org . Next, find the source files for its latest version. For this article, we use the stable 1.4.11 version. Once you have the archive, extract it to a convenient location and execute the command in Listing 1:
Listing 1. Building and installing libevent
cd libevent-1.4.11-stable/ ./configure make make install |
Get the memcached source files from Danga Interactive , still choosing the latest distribution. As of this writing, its latest version is 1.4.0. Extract the tar.gz to a convenient location and execute the command in Listing 2:
Listing 2. Generating and installing memcached
cd memcached-1.4.0/ ./configure make make install |
After completing these steps, you should have a working copy of memcached installed and ready to use. Let's do a brief introduction and then use it.
To start using memcached, you first need to start the memcached server and then connect to it using a telnet client.
To start memcached, execute the command in Listing 3:
./memcached -d -m 2048 -l 10.0.0.40 -p 11211 |
This starts memcached as a daemon ( -d
), allocates 2GB of memory to it ( -m 2048
), and specifies to listen on localhost, which is port 11211. You can modify these values as needed, but the above settings are sufficient for the exercises in this article. Next, you need to connect to memcached. You will use a simple telnet client to connect to the memcached server.
Most operating systems provide a built-in telnet client, but if you are using a Windows-based operating system, you will need to download a third-party client. I recommend using PuTTy .
After installing the telnet client, execute the command in Listing 4:
Listing 4. Connecting to memcached
telnet localhost 11211 |
If all is well, you should get a telnet response indicating Connected to localhost . If you don't get this response, you should go back to the previous steps and make sure that the source files for libevent and memcached were generated successfully.
You are now logged into the memcached server. After this, you will be able to communicate with memcached through a series of simple commands. The nine memcached client commands can be divided into three categories:
- basic
- advanced
- manage
Basic memcached client commands
You will use the five basic memcached commands to perform the simplest operations. These commands and actions include:
set
add
replace
get
delete
The first three commands are standard modification commands for manipulating key-value pairs stored in memcached. They are all very simple to use, and they all use the syntax shown in Listing 5:
Listing 5. Modify command syntax
command <key> <flags> <expiration time> <bytes> <value> |
Table 1 defines the parameters and usage of the memcached modification command.
Table 1. memcached modify command parameters
key | key is used to look up the cached value |
flags | An integer parameter that can include key-value pairs, which the client uses to store additional information about the key-value pair |
expiration time | The length of time (in seconds, 0 means forever) to keep key-value pairs in the cache |
bytes | Byte points stored in the cache |
value | Stored value (always on second row) |
Now, let's look at these commands in action.
The set command is used to add new key-value pairs to the cache. If the key already exists, the previous value will be replaced. set
Note the following interaction, which uses the command: set
set userId 0 0 5 12345 STORED |
If the key-value pair is set correctly using the command, the server will respond with the word STORED . This example adds a key-value pair to the cache whose key is and whose value is . and set the expiration time to 0, which will notify memcached that you want this value to be stored in the cache until it is deleted. set
userId
12345
The add command adds a key-value pair to the cache only if the key does not already exist in the cache. If the key already exists in the cache, the previous value will still remain the same and you will get the response NOT_STORED . add
Here is the standard interaction using the command: add
set userId 0 0 5 12345 STORED add userId 0 0 5 55555 NOT_STORED add companyId 0 0 3 564 STORED |
The replace command replaces a key in the cache only if the key already exists . If the key does not exist in the cache, you will receive a NOT_STORED response from the memcached server. replace
Here is the standard interaction using the command: replace
replace accountId 0 0 5 67890 NOT_STORED set accountId 0 0 5 67890 STORED replace accountId 0 0 5 55555 STORED |
最后两个基本命令是 get
和 delete
。这些命令相当容易理解,并且使用了类似的语法,如下所示:
command <key> |
接下来看这些命令的应用。
get get
命令用于检索与之前添加的键值对相关的值。您将使用 get
执行大多数检索操作。
下面是使用 get
命令的典型交互:
set userId 0 0 5 12345 STORED get userId VALUE userId 0 5 12345 END get bob END |
如您所见,get
命令相当简单。您使用一个键来调用 get
,如果这个键存在于缓存中,则返回相应的值。如果不存在,则不返回任何内容。
delete
最后一个基本命令是 delete
。delete
命令用于删除 memcached 中的任何现有值。您将使用一个键调用 delete
,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条 NOT_FOUND 消息。
下面是使用 delete
命令的客户机服务器交互:
set userId 0 0 5 98765 STORED delete bob NOT_FOUND delete userId DELETED get userId END |
可以在 memcached 中使用的两个高级命令是 gets
和 cas
。gets
和 cas
命令需要结合使用。您将使用这两个命令来确保不会将现有的名称/值对设置为新值(如果该值已经更新过)。我们来分别看看这些命令。
gets gets
命令的功能类似于基本的 get
命令。两个命令之间的差异在于,gets
返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
下面是使用 gets
命令的客户机服务器交互:
set userId 0 0 5
12345
STORED
get userId
VALUE userId 0 5
12345
END
gets userId
VALUE userId 0 5 4
12345
END
|
考虑 get
和 gets
命令之间的差异。gets
命令将返回一个额外的值 — 在本例中是整型值 4,用于标识名称/值对。如果对此名称/值对执行另一个 set
命令,则 gets
返回的额外值将会发生更改,以表明名称/值对已经被更新。清单 6 显示了一个例子:
set userId 0 0 5
33333
STORED
gets userId
VALUE userId 0 5 5
33333
END
|
您看到 gets
返回的值了吗?它已经更新为 5。您每次修改名称/值对时,该值都会发生更改。
cas cas
(check 和 set)是一个非常便捷的 memcached 命令,用于设置名称/值对的值(如果该名称/值对在您上次执行 gets
后没有更新过)。它使用与 set
命令相类似的语法,但包括一个额外的值:gets
返回的额外值。
注意以下使用 cas
命令的交互:
set userId 0 0 5 55555 STORED gets userId VALUE userId 0 5 6 55555 END cas userId 0 0 5 6 33333 STORED |
如您所见,我使用额外的整型值 6 来调用 gets
命令,并且操作运行非常顺序。现在,我们来看看清单 7 中的一系列命令:
set userId 0 0 5 55555 STORED gets userId VALUE userId 0 5 8 55555 END cas userId 0 0 5 6 33333 EXISTS |
注意,我并未使用 gets
最近返回的整型值,并且 cas
命令返回 EXISTS 值以示失败。从本质上说,同时使用 gets
和 cas
命令可以防止您使用自上次读取后经过更新的名称/值对。
最后两个 memcached 命令用于监控和清理 memcached 实例。它们是 stats
和 flush_all
命令。
stats stats
命令的功能正如其名:转储所连接的 memcached 实例的当前统计数据。在下例中,执行 stats
命令显示了关于当前 memcached 实例的信息:
stats STAT pid 63 STAT uptime 101758 STAT time 1248643186 STAT version 1.4.11 STAT pointer_size 32 STAT rusage_user 1.177192 STAT rusage_system 2.365370 STAT curr_items 2 STAT total_items 8 STAT bytes 119 STAT curr_connections 6 STAT total_connections 7 STAT connection_structures 7 STAT cmd_get 12 STAT cmd_set 12 STAT get_hits 12 STAT get_misses 0 STAT evictions 0 STAT bytes_read 471 STAT bytes_written 535 STAT limit_maxbytes 67108864 STAT threads 4 END |
此处的大多数输出都非常容易理解。稍后在讨论缓存性能时,我还将详细解释这些值的含义。至于目前,我们先来看看输出,然后再使用新的键来运行一些 set
命令,并再次运行 stats
命令,注意发生了哪些变化。
flush_all flush_all
是最后一个要介绍的命令。这个最简单的命令仅用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all
能提供很大的用处。下面是一个使用 flush_all
的例子:
set userId 0 0 5 55555 STORED get userId VALUE userId 0 5 55555 END flush_all OK get userId END |
在本文的最后,我将讨论如何使用高级 memcached 命令来确定缓存的性能。stats
命令用于调优缓存的使用。需要注意的两个最重要的统计数据是 et_hits 和 get_misses。这两个值分别指示找到名称/值对的次数(get_hits)和未找到名称/值对的次数(get_misses)。
结合这些值,我们可以确定缓存的利用率如何。初次启动缓存时,可以看到 get_misses 会自然地增加,但在经过一定的使用量之后,这些 get_misses 值应该会逐渐趋于平稳 — 这表示缓存主要用于常见的读取操作。如果您看到 get_misses 继续快速增加,而 get_hits 逐渐趋于平稳,则需要确定一下所缓存的内容是什么。您可能缓存了错误的内容。
确定缓存效率的另一种方法是查看缓存的命中率(hit ratio)。缓存命中率表示执行 get
的次数与错过 get
的次数的百分比。要确定这个百分比,需要再次运行 stats
命令,如清单 8 所示:
stats STAT pid 6825 STAT uptime 540692 STAT time 1249252262 STAT version 1.2.6 STAT pointer_size 32 STAT rusage_user 0.056003 STAT rusage_system 0.180011 STAT curr_items 595 STAT total_items 961 STAT bytes 4587415 STAT curr_connections 3 STAT total_connections 22 STAT connection_structures 4 STAT cmd_get 2688 STAT cmd_set 961 STAT get_hits 1908 STAT get_misses 780 STAT evictions 0 STAT bytes_read 5770762 STAT bytes_written 7421373 STAT limit_maxbytes 536870912 STAT threads 1 END |
现在,用 get_hits 的数值除以 cmd_gets。在本例中,您的命中率大约是 71%。在理想情况下,您可能希望得到更高的百分比 — 比率越高越好。查看统计数据并不时测量它们可以很好地判定缓存策略的效率。
常有命令如下:
start/
stop memcached -d -m 10 -u root -l 192.168.0.122 -p 11200 -c 256 -P /tmp/memcached.pid
-d option is to start a daemon process, -m is the amount of memory allocated to Memcache , the unit is MB, here is 10MB -u is the user running Memcache, here is root -l is the IP address of the listening server, if there are multiple addresses, the IP address of the server is specified here 192.168.0.122 -p is to set Memcache The listening port is set to 12000 here, preferably a port above 1024 -c option is the maximum number of concurrent connections running, the default is 1024, here is 256, set according to the load of your server -P is to save the settings Memcache pid file kill `cat /tmp/memcached.pid`
Get running status
echo stats | nc 192.168.1.123 11200
watch "echo stats | nc 192.168.1.123 11200" (real-time status)