RHEL 5 MEMCACHE 部署

1. 什么是Memcache

Memcached是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度, 目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。它可以应对任意多个连接,使用非阻塞的网络IO。它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached管理这些HashTable。

许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。

Memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

2. Memcache工作原理

首先 memcached 是以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,客户端可以由各种语言编写,目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。客户端在与 memcached 服务建立连接之后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符 key,存取操作均通过这个 key 进行,保存到 memcached 中的对象实际上是放置内存中的,并不是保存在 cache 文件中的,这也是为什么 memcached 能够如此高效快速的原因。注意,这些对象并不是持久的,服务停止之后,里边的数据就会丢失。

与许多 cache 工具类似,Memcached 的原理并不复杂。它采用了C/S的模式,在 server 端启动服务进程,在启动时可以指定监听的 ip,自己的端口号,所使用的内存大小等几个关键参数。一旦启动,服务就一直处于可用状态。Memcached 的目前版本是通过C实现,采用了单进程,单线程,异步I/O,基于事件 (event_based) 的服务方式.使用 libevent 作为事件通知实现。多个 Server 可以协同工作,但这些 Server 之间是没有任何通讯联系的,每个 Server 只是对自己的数据进行管理。Client 端通过指定 Server 端的 ip 地址(通过域名应该也可以)。需要缓存的对象或数据是以 key->value 对的形式保存在Server端。key 的值通过 hash 进行转换,根据 hash 值把 value传递到对应的具体的某个 Server 上。当需要获取对象数据时,也根据 key 进行。首先对 key 进行 hash,通过获得的值可以确定它被保存在了哪台 Server 上,然后再向该 Server 发出请求。Client 端只需要知道保存 hash(key) 的值在哪台服务器上就可以了。

简单来说,memcache 的工作就是在专门的机器的内存里维护一张巨大的 hash 表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。

3. 安装部署

1. 本机环境

SYSTEM RHEL 5.4 32bit

PHP php-5.3.2

NYSQL mysql-5.1.45。

2. 所需软件包

libevent 事件通讯软件 (最新版libevent-1.4.14-stable)

http://www.monkey.org/~provos/libevent/

memcache php扩展组件,memcache 客户端(最新版memcache-2.2.5)

http://pecl.php.net/package/memcache

memcached memcache服务端(最新版 memcached-1.4.0) 

http://danga.com/memcached/dist/

3. 安装

1. 安装libevent

#tar -zxf libevent-1.4.14a-stable.tar.gz

#cd libevent-1.4.14-stable/

#./configure --prefix=/usr/local/libevent

#make && make install

#系统可能已经安装有rpm包的libevent,但建议使用源码包的libevent

2. 安装memcached

#tar -zxf memcached-1.4.0.tar.gz

#cd memcached-1.4.0

#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

#make && make install

#建立memcache用户
#useradd –M memcache

#启动服务
#memcached -d -m 10 -u memcache -l 192.168.10.3 -p 11211 -c 256 -P /tmp/memcached.pid
参数说明

? -p 指定端口号(默认11211)

? -m 指定最大使用内存大小(默认64MB)

? -t 线程数(默认4)

? -l 连接的IP地址, 默认是本机

? -d 选项是启动一个守护进程

? -d restart|stop重启|关闭正在运行的memcached服务

? -m 最大内存使用,单位MB。默认64MB  

? -M 内存耗尽时返回错误,而不是删除项

? -c 选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定

? -f 块大小增长因子,默认是1.25

? -n 最小分配空间,key+value+flags默认是48

? -P是设置保存Memcache的pid文件

设置开机自启动memcache

vi /etc/rc.local

/usr/local/memcached/bin/memcached -d -m 100 -u memcache -l 192.168.10.3 -p 11211 -c 256 -P /tmp/memcached.pid

关闭 memcache

# kill `cat /tmp/memcached.pid`

3. 安装memcache php扩展模块

#tar -zxf memcache-2.2.5.tgz
#cd memcache-2.2.5

#find / -name phpize #确定phpize位置,生成编译环境

#/usr/local/php/bin/phpize
#./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir
#make && make install

此时你会看到如下提示:

Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/

你修改php.ini,做如下2步操作:

; extension_dir = "./"

将上面这行修改为

extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"

再新增加一行,内容如下:

extension=memcache.so

#重启apache服务

#/usr/local/apache-2.15/bin/apachectl restart

测试是否安装成功

#编辑首页信息,简单测试了如下2种情况

vi index.php

<?php

phpinfo()

?>

RHEL 5.4上配置memcache_RHEL

vi index.php

<?php
$mem = new Memcache;
$mem->connect("192.168.10.3", 11211)or die ("Could not connect");
$mem-&gt;set('key', 'This is a test!', 0, 60);
$val = $mem-&gt;get('key');
echo $val;
?&gt;

#未启用memcache时

RHEL 5.4上配置memcache_RHEL_02

#su – memcache

#/usr/local/bin/memcached –d   (不加参数表示以默认方式启动)

RHEL 5.4上配置memcache_RHEL_03

RHEL 5.4上配置memcache_职场_04

4. 安装memcache 小工具

#wget http://livebookmark.net/memcachephp/memcachephp.zip

#unzip memcachephp.zip

#mv memcache.php /usr/local/apache-2.15/htdocs/

#vi /usr/local/apache-2.15/htdocs/memcache.php

根据你的配置修改:

RHEL 5.4上配置memcache_memcache_05

RHEL 5.4上配置memcache_休闲_06

RHEL 5.4上配置memcache_休闲_07

4. 常见问题:

1. /usr/local/bin/memcached: error while loading shared libraries: libevent-1.4.so.1: cannot open shared object file: No such file or directory ,缺少库文件的解决方法。

1.1. 首先 find / -name libevent-1.4.so.1 找到缺少的链接文件到底在那儿。

#find / -name libevent-1.4.so.1
/usr/local/src/libevent-1.4.14-stable/.libs/libevent-1.4.so.1
/usr/local/libevent/lib/libevent-1.4.so.1

1.2. 查看出错原因在哪

#LD_DEBUG=libs /usr/local/bin/memcached -v
     10617:     find library=libevent-1.4.so.1 [0]; searching
     10617:      search cache=/etc/ld.so.cache
     10617:      search path=/lib/tls/i686/sse2:/lib/tls/i686:/lib/tls/sse2:/lib/tls:/lib/i686/sse2:/lib/i686:/lib/sse2:/lib:/usr/lib/tls/i686/sse2:/usr/lib/tls/i686:/usr/lib/tls/sse2:/usr/lib/tls:/usr/lib/i686/sse2:/usr/lib/i686:/usr/lib/sse2:/usr/lib            (system search path)
     10617:       trying file=/lib/tls/i686/sse2/libevent-1.4.so.1
     10617:       trying file=/lib/tls/i686/libevent-1.4.so.1
     10617:       trying file=/lib/tls/sse2/libevent-1.4.so.1
     10617:       trying file=/lib/tls/libevent-1.4.so.1
     10617:       trying file=/lib/i686/sse2/libevent-1.4.so.1
     10617:       trying file=/lib/i686/libevent-1.4.so.1
     10617:       trying file=/lib/sse2/libevent-1.4.so.1
     10617:       trying file=/lib/libevent-1.4.so.1
     10617:       trying file=/usr/lib/tls/i686/sse2/libevent-1.4.so.1
     10617:       trying file=/usr/lib/tls/i686/libevent-1.4.so.1
     10617:       trying file=/usr/lib/tls/sse2/libevent-1.4.so.1
     10617:       trying file=/usr/lib/tls/libevent-1.4.so.1
     10617:       trying file=/usr/lib/i686/sse2/libevent-1.4.so.1
     10617:       trying file=/usr/lib/i686/libevent-1.4.so.1
     10617:       trying file=/usr/lib/sse2/libevent-1.4.so.1
     10617:       trying file=/usr/lib/libevent-1.4.so.1
     10617:
/usr/local/bin/memcached: error while loading shared libraries: libevent-1.4.so.1: cannot open shared object file: No such file or directory

1.3. 通过trying file=/usr/lib/libevent-1.4.so.1得知我们需要做个软连接到这,因为这个文件的真实位置在 /usr/local/lib/libevent-1.4.so.2

#ln -s /usr/local/libevent/lib/libevent-1.4.so.1 /usr/lib/libevent-1.4.so.1

1.4. 错误消除,类似的问题都可以这样解决。

5. Memcache 其他相关资料,转自互联网,感谢原作者

1. Memcahce 协议(中英对照)

源自 http://www.gaobo.info/read.php/447.htm

 

协议

Protocol

memcached 的客户端使用TCP链接 与 服务器通讯。(UDP接口也同样有效,参考后文的 “UDP协议” )一个运行中的memcached服务器监视一些(可设置)端口。客户端连接这些端口,发送命令到服务器,读取回应,最后关闭连接。

Clients of memcached communicate with server through TCP connections. (A UDP interface is also available; details are below under "UDP protocol.") A given running memcached server listens on some (configurable) port; clients connect to that port, send commands to the server, read responses, and eventually close the connection.

结束会话不要发送任何命令,当不需要memcached服务时,要客户端可以在任何时候关闭连接。需要注意的是,鼓励客户端缓存这些连接,而不是每次需要存取数据时都重新打开连接。这是因为memcached 被特意设计成及时开启很多连接也能够高效的工作(数百个,上千个如果需要的话)。缓存这些连接,可以消除建立连接所带来的开销(/*/相对而言,在服务器端建立一个新连接的准备工作所带来的开销,可以忽略不计。)。

There is no need to send any command to end the session. A client may just close the connection at any moment it no longer needs it. Note, however, that clients are encouraged to cache their connections rather than reopen them every time they need to store or retrieve data. This is because memcached is especially designed to work very efficiently with a very large number (many hundreds, more than a thousand if necessary) of open connections. Caching connections will eliminate the overhead associated with establishing a TCP connection (the overhead of preparing for a new connection on the server side is insignificant compared to this).

在memcache协议中发送的数据分两种:文本行 和 自由数据。 文本行被用于来自客户端的命令和服务器的回应。自由数据用于客户端从服务器端存取数据时。同样服务器会以字节流的方式传回自由数据。/*/服务器不用关心自由数据的字节顺序。自由数据的特征没有任何限制;但是通过前文提到的文本行,这项数据的接受者(服务器或客户端),便能够精确地获知所发送的数据库的长度。

There are two kinds of data sent in the memcache protocol: text lines
and unstructured data. Text lines are used for commands from clients
and responses from servers. Unstructured data is sent when a client
wants to store or retrieve data. The server will transmit back
unstructured data in exactly the same way it received it, as a byte
stream. The server doesn't care about byte order issues in
unstructured data and isn't aware of them. There are no limitations on
characters that may appear in unstructured data; however, the reader
of such data (either a client or a server) will always know, from a
preceding text line, the exact length of the data block being
transmitted.

文本行固定以“\r\n”(回车符紧跟一个换行符)结束。 自由数据也是同样会以“\r\n”结束,但是 \r(回车符)、\n(换行符),以及任何其他8位字符,均可出现在数据中。因此,当客户端从服务器取回数据时,必须使用数据区块的长度来确定数据区块的结束位置,而不要依据数据区块末尾的“\r\n”,即使它们固定存在于此。

Text lines are always terminated by \r\n. Unstructured data is _also_
terminated by \r\n, even though \r, \n or any other 8-bit characters
may also appear inside the data. Therefore, when a client retrieves
data from a server, it must use the length of the data block (which it
will be provided with) to determine where the data block ends, and not
the fact that \r\n follows the end of the data block, even though it
does.

键值

Keys

存储在memcached中的数据通过键值来标识。键值是一个文本字符串,对于需要存取这项数据的客户端而言,它必须是唯一的。键值当前的长度限制设定为250字符(当然,客户端通常不会用到这么长的键);键值中不能使用制表符和其他空白字符(例如空格,换行等)。

Data stored by memcached is identified with the help of a key. A key
is a text string which should uniquely identify the data for clients
that are interested in storing and retrieving it. Currently the
length limit of a key is set at 250 characters (of course, normally
clients wouldn't need to use such long keys); the key must not include
control characters or whitespace.

命令

Commands

所有命令分为3种类型

There are three types of commands.

存储命令(有3项:’set’、’add’、’repalce’)指示服务器储存一些由键值标识的数据。客户端发送一行命令,后面跟着数据区块;然后,客户端等待接收服务器回传的命令行,指示成功与否。

Storage commands (there are three: "set", "add" and "replace") ask the
server to store some data identified by a key. The client sends a
command line, and then a data block; after that the client expects one
line of response, which will indicate success or faulure.

取回命令(只有一项:’get’)指示服务器返回与所给键值相符合的数据(一个请求中右一个或多个键值)。客户端发送一行命令,包括所有请求的键值;服务器每找到一项内容,都会发送回客户端一行关于这项内容的信息,紧跟着是对应的数据区块;直到服务器以一行“END”回应命令结束。

Retrieval commands (there is only one: "get") ask the server to
retrieve data corresponding to a set of keys (one or more keys in one
request). The client sends a command line, which includes all the
requested keys; after that for each item the server finds it sends to
the client one response line with information about the item, and one
data block with the item's data; this continues until the server
finished with the "END" response line.

/*?*/其他的命令都不能携带自由数据。在这些命令中,客户端发送一行命令,然后等待(由命令所决定)一行回应,或最终以一行“END”结束的多行命令。

All other commands don't involve unstructured data. In all of them,
the client sends one command line, and expects (depending on the
command) either one line of response, or several lines of response
ending with "END" on the last line.

一行命令固定以命令名称开始,接着是以空格隔开的参数(如果有参数的话)。命令名称大小写敏感,并且必须小写。

A command line always starts with the name of the command, followed by
parameters (if any) delimited by whitespace. Command names are
lower-case and are case-sensitive.

一些客户端发送给服务器的命令会包含一些时限(针对内容或客户端请求的操作)。这时,时限的具体内容既可以是Unix时间戳(从1970年1月1日开始的秒钟数),或当前时间开始的秒钟数。对后者而言,不能超过 60*60*24*30(30天);如果超出,服务器将会理解为Unix时间戳,而不是从当前时间起的秒偏移。

Some commands involve a client sending some kind of expiration time
(relative to an item or to an operation requested by the client) to
the server. In all such cases, the actual value sent may either be
Unix time (number of seconds since January 1, 1970, as a 32-bit
value), or a number of seconds starting from current time. In the
latter case, this number of seconds may not exceed 60*60*24*30 (number
of seconds in 30 days); if the number sent by a client is larger than
that, the server will consider it to be real Unix time value rather
than an offset from current time.

错误字串

Error strings

每一个由客户端发送的命令,都可能收到来自服务器的错误字串回复。这些错误字串会以三种形式出现:

Each command sent by a client may be answered with an error string
from the server. These error strings come in three types:

- "ERROR\r\n"

意味着客户端发送了不存在的命令名称。

means the client sent a nonexistent command name.

- "CLIENT_ERROR <error>\r\n"

意味着输入的命令行里存在一些客户端错误,例如输入未遵循协议。<error>部分是人类易于理解的错误解说……

means some sort of client error in the input line, i.e. the input
doesn't conform to the protocol in some way. <error> is a
human-readable error string.

- "SERVER_ERROR <error>\r\n"

意味着一些服务器错误,导致命令无法执行。<error>部分是人类易于理解的错误解说。在一些严重的情形下(通常应该不会遇到),服务器将在发送这行错误后关闭连接。这是服务器主动关闭连接的唯一情况。

means some sort of server error prevents the server from carrying
out the command. <error> is a human-readable error string. In cases
of severe server errors, which make it impossible to continue
serving the client (this shouldn't normally happen), the server will
close the connection after sending the error line. This is the only
case in which the server closes a connection to a client.

在后面每项命令的描述中,这些错误行不会再特别提到,但是客户端必须考虑到这些它们存在的可能性。

In the descriptions of individual commands below, these error lines
are not again specifically mentioned, but clients must allow for their
possibility.

存储命令

Storage commands

首先,客户端会发送一行像这样的命令:

First, the client sends a command line which looks like this:

<command name> <key> <flags> <exptime> <bytes>\r\n

- <command name> 是 set, add, 或者 repalce

- <command name> is "set", "add" or "replace"

  • set 意思是 “储存此数据”
  • add 意思是 “储存此数据,只在服务器*未*保留此键值的数据时”
  • replace意思是 “储存此数据,只在服务器*曾*保留此键值的数据时”
  • "set" means "store this data".
  • "add" means "store this data, but only if the server *doesn't* already
    hold data for this key".
  • "replace" means "store this data, but only if the server *does*
    already hold data for this key".

- <key> 是接下来的客户端所要求储存的数据的键值

- <key> is the key under which the client asks to store the data

- <flags> 是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号×××(用十进制来书写)。客户端可以用它作为“位域”来存储一些特定的信息;它对服务器是不透明的。

- <flags> is an arbitrary 16-bit unsigned integer (written out in
decimal) that the server stores along with the data and sends back
when the item is retrieved. Clients may use this as a bit field to
store data-specific information; this field is opaque to the server.

- <exptime> 是终止时间。如果为0,该项永不过期(虽然它可能被删除,以便为其他缓存项目腾出位置)。如果非0(Unix时间戳或当前时刻的秒偏移),到达终止时间后,客户端无法再获得这项内容。

- <exptime> is expiration time. If it's 0, the item never expires
(although it may be deleted from the cache to make place for other
items). If it's non-zero (either Unix time or offset in seconds from
current time), it is guaranteed that clients will not be able to
retrieve this item after the expiration time arrives (measured by
server time).

- <bytes> 是随后的数据区块的字节长度,不包括用于分野的“\r\n”。它可以是0(这时后面跟随一个空的数据区块)。

- <bytes> is the number of bytes in the data block to follow, *not*
including the delimiting \r\n. <bytes> may be zero (in which case
it's followed by an empty data block).

在这一行以后,客户端发送数据区块。

After this line, the client sends the data block:

<data block>\r\n

- <data block> 是大段的8位数据,其长度由前面的命令行中的<bytes>指定。

- <data block> is a chunk of arbitrary 8-bit data of length <bytes>
from the previous line.

发送命令行和数据区块以后,客户端等待回复,可能的回复如下:

After sending the command line and the data blockm the client awaits
the reply, which may be:

- "STORED\r\n"

表明成功.

to indicate success.

- "NOT_STORED\r\n"

表明数据没有被存储,但不是因为发生错误。这通常意味着add 或 replace命令的条件不成立,或者,项目已经位列删除队列(参考后文的“delete”命令)。

to indicate the data was not stored, but not
because of an error. This normally means that either that the
condition for an "add" or a "replace" command wasn't met, or that the
item is in a delete queue (see the "delete" command below).

取回命令

Retrieval command

一行取回命令如下:

The retrieval command looks like this:

get <key>*\r\n

- <key>* 表示一个或多个键值,由空格隔开的字串

- <key>* means one or more key strings separated by whitespace.

这行命令以后,客户端的等待0个或多个项目,每项都会收到一行文本,然后跟着数据区块。所有项目传送完毕后,服务器发送以下字串:

After this command, the client expects zero or more items, each of
which is received as a text line followed by a data block. After all
the items have been transmitted, the server sends the string

"END\r\n"

来指示回应完毕。

to indicate the end of response.

服务器用以下形式发送每项内容:

Each item sent by the server looks like this:

VALUE <key> <flags> <bytes>\r\n
<data block>\r\n

- <key> 是所发送的键名

- <key> is the key for the item being sent

- <flags> 是存储命令所设置的记号

- <flags> is the flags value set by the storage command

- <bytes> 是随后数据块的长度,*不包括* 它的界定符“\r\n”

- <bytes> is the length of the data block to follow, *not* including
its delimiting \r\n

- <data block> 是发送的数据

- <data block> is the data for this item.

如果在取回请求中发送了一些键名,而服务器没有送回项目列表,这意味着服务器没这些键名(可能因为它们从未被存储,或者为给其他内容腾出空间而被删除,或者到期,或者被已客户端删除)。

If some of the keys appearing in a retrieval request are not sent back
by the server in the item list this means that the server does not
hold items with such keys (because they were never stored, or stored
but deleted to make space for more items, or expired, or explicitly
deleted by a client).

删除

Deletion

命令“delete”允许从外部删除内容:

The command "delete" allows for explicit deletion of items:

delete <key> <time>\r\n

- <key> 是客户端希望服务器删除的内容的键名

- <key> is the key of the item the client wishes the server to delete

- <time> 是一个单位为秒的时间(或代表直到某一刻的Unix时间),在该时间内服务器会拒绝对于此键名的“add”和“replace”命令。此时内容被放入delete队列,无法再通过“get”得到该内容,也无法是用“add”和“replace”命令(但是“set”命令可用)。直到指定时间,这些内容被最终从服务器的内存中彻底清除。

- <time> is the amount of time in seconds (or Unix time until which)
the client wishes the server to refuse "add" and "replace" commands
with this key. For this amount of item, the item is put into a
delete queue, which means that it won't possible to retrieve it by
the "get" command, but "add" and "replace" command with this key
will also fail (the "set" command will succeed, however). After the
time passes, the item is finally deleted from server memory.

<time>参数 是可选的,缺省为0(表示内容会立刻清除,并且随后的存储命令均可用)。

The parameter <time> is optional, and, if absent, defaults to 0
(which means that the item will be deleted immediately and further
storage commands with this key will succeed).

此命令有一行回应:

The response line to this command can be one of:

- "DELETED\r\n"

表示执行成功

to indicate success

- "NOT_FOUND\r\n"

表示没有找到这项内容

to indicate that the item with this key was not found.

参考随后的“flush_all”命令使所有内容无效

See the "flush_all" command below for immediate invalidation
of all existing items.

增加/减少

Increment/Decrement

命令 “incr” 和 “decr”被用来修改数据,当一些内容需要 替换、增加 或减少时。这些数据必须是十进制的32位无符号整新。如果不是,则当作0来处理。修改的内容必须存在,当使用“incr”/“decr”命令修改不存在的内容时,不会被当作0处理,而是操作失败。

Commands "incr" and "decr" are used to change data for some item
in-place, incrementing or decrementing it. The data for the item is
treated as decimal representation of a 32-bit unsigned integer. If the
current data value does not conform to such a representation, the
commands behave as if the value were 0. Also, the item must already
exist for incr/decr to work; these commands won't pretend that a
non-existent key exists with value 0; instead, they will fail.

客户端发送命令行:

The client sends the command line:

incr <key> <value>\r\n

decr <key> <value>\r\n

- <key> 是客户端希望修改的内容的建名

- <key> is the key of the item the client wishes to change

- <value> 是客户端要增加/减少的总数。

- <value> is the amount by which the client wants to increase/decrease
the item. It is a decimal representation of a 32-bit unsigned integer.

回复为以下集中情形:

The response will be one of:

- "NOT_FOUND\r\n"

指示该项内容的值,不存在。

to indicate the item with this value was not found

- <value>\r\n ,<value>是 增加/减少 。

- <value>\r\n , where <value> is the new value of the item's data,
after the increment/decrement operation was carried out.

注意"decr"命令发生下溢:如果客户端尝试减少的结果小于0时,结果会是0。"incr" 命令不会发生溢出。

Note that underflow in the "decr" command is caught: if a client tries
to decrease the value below 0, the new value will be 0. Overflow in
the "incr" command is not checked.

……

Note also that decrementing a number such that it loses length isn't
guaranteed to decrement its returned length. The number MAY be
space-padded at the end, but this is purely an implementation
optimization, so you also shouldn't rely on that.

状态

Statistics

命令"stats" 被用于查询服务器的运行状态和其他内部数据。有两种格式。不带参数的:

The command "stats" is used to query the server about statistics it
maintains and other internal data. It has two forms. Without
arguments:

stats\r\n

这会在随后输出各项状态、设定值和文档。另一种格式带有一些参数:

it causes the server to output general-purpose statistics and
settings, documented below. In the other form it has some arguments:

stats <args>\r\n

通过<args>,服务器传回各种内部数据。因为随时可能发生变动,本文不提供参数的种类及其传回数据。

Depending on <args>, various internal data is sent by the server. The
kinds of arguments and the data sent are not documented in this vesion
of the protocol, and are subject to change for the convenience of
memcache developers.

各种状态

General-purpose statistics

受到无参数的"stats"命令后,服务器发送多行内容,如下:

Upon receiving the "stats" command without arguments, the server sents
a number of lines which look like this:

STAT <name> <value>\r\n

服务器用以下一行来终止这个清单:

The server terminates this list with the line

END\r\n

在每行状态中,<name> 是状态的名字,<value> 使状态的数据。 以下清单,是所有的状态名称,数据类型,和数据代表的含义。

In each line of statistics, <name> is the name of this statistic, and
<value> is the data. The following is the list of all names sent in
response to the "stats" command, together with the type of the value
sent for this name, and the meaning of the value.

在“类型”一列中,"32u"表示32位无符号整型,"64u"表示64位无符号整型,"32u:32u"表示用冒号隔开的两个32位无符号整型。

In the type column below, "32u" means a 32-bit unsigned integer, "64u"
means a 64-bit unsigner integer. '32u:32u' means two 32-but unsigned
integers separated by a colon.

名称/Name

类型/Type

含义/Meaning

pid

32u

服务器进程ID

Process id of this server process

uptime

32u

服务器运行时间,单位秒

Number of seconds this server has been running

time

32u

服务器当前的UNIX时间

current UNIX time according to the server

version

string

服务器的版本号

Version string of this server

rusage_user

32u:32u

该进程累计的用户时间
(秒:微妙)

Accumulated user time for this process
(seconds:microseconds)

rusage_system

32u:32u

该进程累计的系统时间
(秒:微妙)

Accumulated system time for this process
(seconds:microseconds)

curr_items

32u

服务器当前存储的内容数量

Current number of items stored by the server

total_items

32u

服务器启动以来存储过的内容总数

Total number of items stored by this server
ever since it started

bytes

64u

服务器当前存储内容所占用的字节数

Current number of bytes used by this server
to store items

curr_connections

32u

连接数量

Number of open connections

total_connections

32u

服务器运行以来接受的连接总数

Total number of connections opened since
the server started running

connection_structures

32u

服务器分配的连接结构的数量

Number of connection structures allocated
by the server

cmd_get

32u

取回请求总数

Cumulative number of retrieval requests

cmd_set

32u

存储请求总数

Cumulative number of storage requests

get_hits

32u

请求成功的总次数

Number of keys that have been requested and
found present

get_misses

32u

请求失败的总次数

Number of items that have been requested
and not found

bytes_read

64u

服务器从网络读取到的总字节数

Total number of bytes read by this server
from network

bytes_written

64u

服务器向网络发送的总字节数

Total number of bytes sent by this server to
network

limit_maxbytes

32u

服务器在存储时被允许使用的字节总数

Number of bytes this server is allowed to
use for storage.

其它命令

Other commands

“flush_all”命令有一个可选的数字参数。它总是执行成功,服务器会发送“OK\r\n”回应。它的效果是使已经存在的项目立即失效(缺省),或在指定的时间后。此后执行取回命令,将不会有任何内容返回(除非重新存储同样的键名)。flush_all 实际上没有立即释放项目所占用的内存,而是在随后陆续有新的项目被储存时执行。flush_all 效果具体如下:它导致所有更新时间早于flush_all所设定时间的项目,在被执行取回命令时命令被忽略。

"flush_all" is a command with an optional numeric argument. It always succeeds, and the server sends "OK\r\n" in response. Its effect is to invalidate all existing items immediately (by default) or after the expiration specified. After invalidation none of the items will be returned in response to a retrieval command (unless it's stored again under the same key *after* flush_all has invalidated the items). flush_all doesn't actually free all the memory taken up by existing items; that will happen gradually as new items are stored. The most precise definition of what flush_all does is the following: it causes all items whose update time is earlier than the time at which flush_all was set to be executed to be ignored for retrieval purposes.

“version”命令没有参数:

"version" is a command with no arguments:

version\r\n

在回应中,服务器发送:

In response, the server sends

"VERSION <version>\r\n"

<version> 是服务器的版本字串。

where <version> is the version string for the server.

“quit”命令没有参数:

"quit" is a command with no arguments:

quit\r\n

接收此命令后,服务器关闭连接。不过,客户端可以在不再需要时,简单地关闭连接就行,并不一定需要发送这个命令。

Upon receiving this command, the server closes the connection. However, the client may also simply close the connection when it no longer needs it, without issuing this command.

UDP 协议

UDP protocol

当来自客户端的连接数远大于TCP连接的上限时,可以使用基于UDP的接口。UDP接口不能保证传输到位,所以只有在不要求成功的操作中使用;比如被用于一个“get”请求时,会因不当的缓存处理而发生错误或回应有遗失。

For very large installations where the number of clients is high enough that the number of TCP connections causes scaling difficulties, there is also a UDP-based interface. The UDP interface does not provide guaranteed delivery, so should only be used for operations that aren't required to succeed; typically it is used for "get" requests where a missing or incomplete response can simply be treated as a cache miss.

每个UDP数据包都包含一个简单的帧头,数据之后的内容与TCP协议的描述类似。在执行所产生的数据流中,请求必须被包含在单独的一个UDP数据包中,但是回应可能跨越多个数据包。(只有“get”和“set”请求例外,跨越了多个数据包)

Each UDP datagram contains a simple frame header, followed by data in the same format as the TCP protocol described above. In the current implementation, requests must be contained in a single UDP datagram, but responses may span several datagrams. (The only common requests that would span multiple datagrams are huge multi-key "get" requests and "set" requests, both of which are more suitable to TCP transport for reliability reasons anyway.)

帧头有8字节长,如下(均由16位整数组成,网络字节顺序,高位在前):

The frame header is 8 bytes long, as follows (all values are 16-bit integers in network byte order, high byte first):

  • 0-1 请求ID
  • 2-3 序号
  • 4-5 该信息的数据包总数
  • 6-7 保留位,必须为0
  • 0-1 Request ID
  • 2-3 Sequence number
  • 4-5 Total number of datagrams in this message
  • 6-7 Reserved for future use; must be 0

请求ID有客户端提供。一般它会是一个从随机基数开始的递增值,不过客户端想用什么样的请求ID都可以。服务器的回应会包含一个和请求中的同样的ID。客户端使用请求ID来区分每一个回应。任何一个没有请求ID的数据包,可能是之前的请求遭到延迟而造成的,应该被丢弃。

The request ID is supplied by the client. Typically it will be a monotonically increasing value starting from a random seed, but the client is free to use whatever request IDs it likes. The server's response will contain the same ID as the incoming request. The client uses the request ID to differentiate between responses to outstanding requests if there are several pending from the same server; any datagrams with an unknown request ID are probably delayed responses to an earlier request and should be discarded.

序号的返回是从0到n-1,n是该条信息的数据包数量。

The sequence number ranges from 0 to n-1, where n is the total number of datagrams in the message. The client should concatenate the payloads of the datagrams for a given response in sequence number order; the resulting byte stream will contain a complete response in the same format as the TCP protocol (including terminating \r\n sequences).

 

2. Php的memcache应用方法及简单实例

原文链接:http://edu.codepub.com/2010/0427/22348.php

 

Memcache::add // 添加一个值,如果已经存在,则返回false

Memcache::addServer // 添加Memcache地址

Memcache::close // 关闭一个Memcache的连接

Memcache::connect // 打开一个到Memcache的连接

Memcache::decrement // 对保存的某个key中的值进行减法操作

Memcache::delete // 删除一个Memcache上的key值

Memcache::flush // 刷新所有Memcache上保存的项目(类似于删除所有的保存的项目)

Memcache::get // 从Memcache上获取一个key值

Memcache::getExtendedStats // 获取进程池中所有进程的运行系统统计

Memcache::getServerStatus // 获取运行服务器的参数

Memcache::getStats //获取当前Memcache服务器运行的状态

Memcache::getVersion // 返回运行的Memcache的版本信息

Memcache::increment // 对保存的某个key中的值进行加法操作

Memcache::pconnect // 打开一个到Memcache的长连接

Memcache::replace // 替换一个已经存在Memcache服务器上的项目(功能类似Memcache::set)

Memcache::set // 向Memcache添加一个值,如果已经存在,则覆写

Memcache::setCompressThreshold // 对大于某一大小的数据进行压缩

Memcache::setServerParams // 在运行时修改服务器的参数

下面是一些简单的用法实例,仅供参考:

<?php

$mem = new Memcache;

$mem->connect("127.0.0.1", 12000);

//Memcache::set方法有四个参数,第一个参数是key,第二个参数是value,第三个参数可选,表示是否压缩保存,第四个参数可选,用来设置一个过期自动销毁的时间。

$mem-&gt;set('test','123',0,60);

//Memcache::add方法的作用和Memcache::set方法类似,区别是如果 Memcache::add方法的返回值为false,表示这个key已经存在,而Memcache::set方法则会直接覆写。

$mem-&gt;add('test','123',0,60);

//Memcache::get方法的作用是获取一个key值,Memcache::get方法有一个参数,表示key。

$mem-&gt;get('test');//输出为'123'

//Memcache::replace 方法的作用是对一个已有的key进行覆写操作,Memcache::replace方法有四个参数,作用和Memcache::set方法的相同。

$mem-&gt;replace('test','456',0,60);

//Memcache::delete方法的作用是删除一个key值,Memcache::delete方法有两个参数,第一个参数表示key,第二个参数可选,表示删除延迟的时间。

$mem-&gt;delete('test',60);

?&gt;

 

 

3. Memcache基础篇 Memcache和mysql交互流程操作原理

作者:biuuu,来源:http://www.biuuu.com/?p=234

 

对于大型网站如facebook,ebay等网站,如果没有Memcache做为中间缓存层,数据访问不可能吃得消,对于一般网站,只要具备独立的服务器,完全可以通过配置Memcache提高网站访问速度和减少数据库压力,这里主要讨论一下Memcache和MySQL数据库交互过程的流程关系,了解Memcache的中间缓存层作用,从而深入了解Memcache机制原理。
RHEL 5.4上配置memcache_休闲_08
Memcache和MySQL交互流程图

如上图,传统的查询方法是直接查询数据库,数据库将结果返回给查询语句,而当有Memcache中间缓存层时,查询的是Memcache缓存数据,下面详细了解Memcache各类数据操作原理:

1,查询数据(select),首先通过指定的Key查询(get)Memcache中间缓存层数据,如果存在相对应数据,则直接获取出数据结果,查询过程完全不需要查询数据库。如果不存在,则查询MySQL数据库,并以key对应value的形式将查询结果存储在Memcache缓存数据中,然后将结果返回给查询语句。

2,更新数据(update),首先更新数据,然后删除相关的memcache数据(delete)。

3,增加数据(add),首先删除相关缓存数据,然后增加数据。

4,删除数据(delete),删除数据,并删除Memcache数据。

对MySQL的数据操作,主要涉及到的Memcache方法如下:

RHEL 5.4上配置memcache_职场_09

1,获取:get(key)
2,设置:set(key, value [, expiry])
3,删除:delete(key [, time])

实例:
假设一个贴子,获取贴子ID为2009的值,其Memcache与MySQL交互流程如下:

$key = 'biuuu_thread_';//key前缀
$cachetime = 100;//缓存有效时间(秒)
$id = 2009;

Memcache基本操作过程
1,查询:$result = get($key.$id);如果$result为空,则查询MySQL数据库,然后set($key.$id,$value,0,$cachetime)
2,更新:delete($key.$id);
3,增加:delete($key.$id);
4,删除:delete($key.$id);
RHEL 5.4上配置memcache_RHEL_10
通过直观图和实例应该对Memcache与MySQL的交互有一个基础的掌握,其实对于应用来说,基本上就已经足够,但如果要涉及到命名空间等相对复杂的情况,Memcache的操作方式会有所不同,但不管什么样的操作,还是离不开基础操作命令,由于这是Memcache基础篇,主要是讨论Memcache和mysql交互操作流程,当Memcache原理清楚以后,Memcache基本操作就是这么简单。