简介

用过缓存零碎的必定都听过memcached的小名,memcached是一个十分优良的分布式内存缓存零碎,利用十分的宽泛。Memcached不仅仅是Web缓存,它更是一个通用的数据缓存,基本上你能够将任何货色存入memcached中,它的分布式设计具备很好的可扩展性和灵活性。

Memcached是一个客户端-服务器端的架构模式。一般来说,在服务器上搭建好Memcached的服务器端,接下来就能够应用Memcached的客户端和服务器端进行替换了。

作为客户端和服务器端的模型,两者的通信必定是有特定的协定的,实用于memcached的协定就叫做memcached protocol。

memcached的协定有两种,别离是text协定和binary协定。本文将会具体解说memcached text protocol的定义。

memcached protocol介绍

memcached能够看做是一个简略的key-value的存储系统,客户端通过key来申请服务器端的数据,服务器端通过key的hash值来查找对应的数据,而后返回给客户端。

memcached中的key长度个别不能超过250个字符。key不能蕴含控制字符或空白字符。

为了保障客户端和服务器端的音讯通信顺畅,一般来说都会制订非凡的客户端和服务器端的通信协定,这个协定就叫做protocol。

什么是protocol呢?protocol听起来很浅近很神秘,然而实际上protocol就是约定好的单方交互的音讯格局。

对于memcached来说,memcached同时反对UDP和TCP协定,并且提供了两种协定形式,别离是“文本协定”和“二进制协定”。

其中文本协定是在第一个版本就反对的协定,而二进制协定是在v1.4之后才反对的。

文本协定和二进制协定都反对同样的命令,两者的惟一区别就是二进制协定具备更低的性能提早和更好的可扩展性,而文本协定的有点就是它的可调试性能更好。

memcached text协定蕴含两局部数据,文本行和非结构化数据。前者是来自客户端的命令或来自服务器的响应,后者代表客户端拜访的数据。命令以\r\n结尾,数据能够用\r、\n或\r\n,示意数据局部的完结。

memcached反对的命令

memcached反对三种命令,别离是存储命令,读取命令和其余命令。

存储命令

memcached中的存储命令总共有6个,别离是“set”、“add”、“replace”、“append”、"prepend" 和 "cas"。

首先,客户端发送如下所示的命令行:

command key [flags] [exptime] length [noreply]

另外cas命令的格局和其余几个不太一样:

cas key [flags] [exptime] length [casunique] [noreply]

下面的命令中,command代表的是命令的名字,也就是下面的“set”、“add”、“replace”、“append”和"prepend"。

set示意给key设置一个值。

Add示意如果key不存在的话,就增加。

replace用来替换已知key的value。

append示意将提供的值附加到现有key的value之后,是一个附加操作。

prepend将以后key对应的value增加到提供的值前面。

cas是一个原子操作,只有当casunique匹配的时候,才会设置对应的值。

flags是一个十分乏味的参数,这个参数对于memcached server来说是通明的,这个参数只是用来标记客户端命令的类型,并不会被服务器端辨认。另外flags的长度在不同的memcached版本中也有所不同,在memcached 1.2.0或者依据低级的版本中,flags是一个16-bit的整数。在memcached 1.2.1或以上的版本,flags是一个32-bit的整数。

exptime是过期工夫,0示意不会过期。

length是以byte示意的value的长度,这个值并不蕴含value中的结束符"\r\n"。

casunique是一个64-bit的现有entry的惟一值。

noreply通知服务器端,这是个不须要reply的命令。

在发送完命令行之后,客户端还须要发送数据块:

<data block>\r\n

举个例子,咱们想要将jack这个值设置到student这个key上,那么对应的命令应该如下所示:

set student 0 0 4\r\njack\r\n

对应的客户端收到的服务器端的返回可能有这些值:

  • "STORED\r\n",示意存储胜利。
  • "NOT_STORED\r\n" 示意数据因为某些谬误未存储胜利。这通常意味着不满足“add”或“replace”命令的条件。
  • "EXISTS\r\n" 示意要设置的值在上次进行cas操作之后曾经被批改了。
  • "NOT_FOUND\r\n" 示意要设置的值用在cas。

读取命令

memcached的读取命令有4个,别离是“get”、“gets”、“gat”和“gats,这些命令的格局如下:

get <key>*\r\ngets <key>*\r\ngat <exptime> <key>*\r\ngats <exptime> <key>*\r\n

memcached中的读取命令前面不须要跟额定的数据块。

服务器端会依据接管到的key进行查问,每个key返回一条数据,格局如下:

VALUE <key> <flags> <bytes> [<cas unique>]\r\n<data block>\r\n

在所有的数据都传输结束之后,服务器端会发送"END\r\n"示意传输结束。

这里的key示意查问传入的key。

flags是存储命令传入的flags。

bytes是前面data block的长度。

cas unique是以后item的惟一标记,在gets或者gats命令中返回。

data block是以后item具体的返回值。

下面咱们提到了4个读取的命令,那么他们有什么区别呢?

首先是get和gets的区别,get 用于获取key的value值,若key不存在,返回空。反对多个key。 gets 用于获取key的带有CAS令牌值的value值,若key不存在,返回空。反对多个key。 他们的区别在于gets会返回多一个cas unique值。

gat和get的区别是,gat是get+touch的命令综合体,除了返回以后值之外,还会更新key的过期工夫。

罕用的其余命令

除了存储和获取之外,还有一些罕用的其余命令。为什么这些命令被叫做第三类命令呢?这是因为这些命令只须要一个命令行即可,并不需要向服务器端传入额定的数据块。

上面是删除命令的格局:

delete <key> [noreply]\r\n

key是要删除的对象。

noreply示意是否须要收到服务器的返回值。

对应的服务器端返回值可能有两个:

  • "DELETED\r\n" 示意删除胜利
  • "NOT_FOUND\r\n" 示意要删除的对象并不存在。

上面是Increment/Decrement命令的格局:

incr <key> <value> [noreply]\r\ndecr <key> <value> [noreply]\r\n

key是要批改的对象。

value是要增加或者缩小的值,它必须是一个64-bit无符号整数。

noreply示意是否须要收到服务器的返回值。

服务器端的返回可能有两个:

  • "NOT_FOUND\r\n" 示意要批改的对象没有找到
  • "value\r\n" 返回批改胜利之后的值

还有一个罕用的是批改key过期工夫的touch命令:

touch <key> <exptime> [noreply]\r\n

key是要批改的对象。

exptime是过期工夫。

noreply示意是否须要收到服务器的返回值。

服务器端的返回值有两种:

  • "TOUCHED\r\n" 示意批改胜利。
  • "NOT_FOUND\r\n" 示意要批改的对象不存在。

当然memcached反对的命令远不止下面所讲的这些。咱们只是从中挑选出了最罕用的一些命令进行解说。

memcached服务器的返回值

下面在解说具体的命令的时候有提到服务器的返回值,这里再总结一下,memcached服务器端的返回值有上面几种:

返回值阐明
STORED值存储胜利
NOT_STORED值存储失败
EXISTScas中要存储的对象已存在
NOT_FOUND要批改的对象不存在
ERROR提交了未知的命令
CLIENT_ERROR errorstring客户端输出有误,具体的错误信息寄存在 errorstring
SERVER_ERROR errorstring服务器端异样
VALUE keys flags length返回要查问的key对应的对象
DELETED对象曾经被删除
STAT name value统计信息
END服务器端返回完结

留神,下面所有的返回值都以"\r\n"结尾。

反对UDP协定

下面咱们讲的都是TCP协定的报文格式。事实上memcached还反对UDP协定。

然而因为UDP不保障可靠性的特色,所以应用UDP的场合个别在做缓存的查问利用中,即便查问失败,也只是被看做是缓存没有被命中而已,并不会影响到数据的准确性。

事实上UDP的数据包和TCP的数据包格局根本一样,只不过多了一个简略的帧头。并且所有的申请都必须在单个UDP数据包中实现。

留神,这里只有申请才有这个要求,服务器端的返回并没有这个限度。

在UDP中帧头长8个字节,其中0-1个字节示意的是申请ID,申请ID是由客户端生成的一个枯燥递增的值。服务器端将会应用这个ID来标记是对哪个申请的响应。特地是在有服务器端有多个响应的状况下。

2-3个字节示意的是序列号,它的取值范畴是0到n-1,其中n是音讯中总的报文个数,也就是4-5个字节所示意的。

最初的6-7字节是保留字节,以备未来应用,当初设置为0。

总结

以上就是对memcached协定的介绍,通常来说咱们应用memcached都是通过memcached客户端来进行的,如果有仔细的敌人可能会发现,客户端应用的命令和协定中的命令差异不大,这是因为客户端就是对这些底层协定的封装,而后裸露给用户一个更加简略易操作的接口。

更多内容请参考 http://www.flydean.com/23-memcached-text-protocol/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!