twemproxyMemcache协议解析探索——剖析twemproxy代码正编补充

memcache是一种和redis类似的高速缓存服务器,但是memcache只提供键值对这种简单的存储方式,相对于redis支持的存储方式多样化,memcache就比较简单了。memcache通过tcp或者udp连接来实现memcache客户端和服务端的交互。memcache的协议是自定的,也分为两种:一种是文本协议(这是我们今天讨论的重点),另一种是二进制协议(在我们今天讨论的范围),这里仅仅介绍用tcp连接以及文本协议通信的memcache协议。如有描述不当的地方请大家指出。

memcache文本协议

存储命令

add/replace/set/append/prepend命令格式如下:

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

<data block>\r\n

格式的介绍如下:

<command name>可以是add(即增加不存在的键值对),replace(即替换存在的键值对),set(上述两种的功能都具有),append(在存在的键对应的值后增加对应的内容)以及prepend(在存在的键对应的值之前增加对应的内容)。

<key> 是数据项的键名。

<flags>是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号整形(用十进制来书写),一般为0。

<exptime> 是有效时间。如果为0,该项永不过期,如果非0,该项将在<exptime> 后删除。

<bytes>是<data block>的长度,是数据项的长度。

<data block>是数据项的数据。

add/replace/set/append/prepend命令回复

"STORED\r\n"表明存储成功。

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

cas命令格式如下:

cas <key> <flags> <exptime> <bytes> <cas unique> [noreply]\r\n

<data block>\r\n

<key> ,<flags>,<exptime>, <bytes>以及<data block>同add/replace/set/append/prepend命令

<cas unique> 是一个与已存数据条目相关的全局唯一的64位数。客户端应该使用"gets"命令返回的该值来进行"cas"更新操作。

[noreply]是可选项指示不要回复。注意:如果请求行格式错误,服务器不一定能可靠地解析"noreply"选项。在此种情况下,它可能会发送错误信息给客户端,如果客户端没有读取该信息的话会带来问题。客户端应该只构造合法的请求。

cas命令回复如下:

"EXIST\r\n" 指示要更新的数据自你上次取过后已经过修改。

"NO_FOUND\r\n" 指示要修改的数据并不存在。

delete格式命令如下:

delete <key> <time>\r\n

delete是删除对应的键名。

<key> 是需要删除的键名。

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

delete命令回复如下:

"DELETED\r\n"表示执行成功

"NOT_FOUND\r\n"表示没有找到这项内容

读取命令

get/gets命令格式如下:

get/gets <key>*\r\n

<key>*指的是多个以空格分割的键名。

get/gets命令回复如下:

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

<data block>\r\n

<key>是数据项的键名

<flags>是由存储命令设置的flags,一般为0

<bytes>是数据块的长度

<cas unique>是一个64位整数,唯一标识了一个特定的数据项。

<data block>是数据项的数据。

这里的所有数据以"END"结束。

incr/desc命令格式如下:

incr/desc <key> <value> [noreply]\r\n

<key>是数据项的键名

<value>是对数据项incr(递增)/desc(递减)的值。它是一个64位的无符号十进制整数。

[norply]是可选参数,不要回复。

incr/desc命令回复:

"NOT_FOUND\r\n" 指示这个数据项找不到。

"<value>\r\n", 其中<value>是这个数据项在经过递增/递减操作后的新值。

memcache文本协议的请求的解析

这个是在proto/memcache.c里的memcache_parse_req函数

它也是用有限状态机去完成解析的

 1     enum {
 2         SW_START,
 3         SW_REQ_TYPE,
 4         SW_SPACES_BEFORE_KEY,
 5         SW_KEY,
 6         SW_SPACES_BEFORE_KEYS,
 7         SW_SPACES_BEFORE_FLAGS,
 8         SW_FLAGS,
 9         SW_SPACES_BEFORE_EXPIRY,
10         SW_EXPIRY,
11         SW_SPACES_BEFORE_VLEN,
12         SW_VLEN,
13         SW_SPACES_BEFORE_CAS,
14         SW_CAS,
15         SW_RUNTO_VAL,
16         SW_VAL,
17         SW_SPACES_BEFORE_NUM,
18         SW_NUM,
19         SW_RUNTO_CRLF,
20         SW_CRLF,
21         SW_NOREPLY,
22         SW_AFTER_NOREPLY,
23         SW_ALMOST_DONE,
24         SW_SENTINEL
25     } state;

这里的有限状态机图如下:

storage就是存储命令,即add/replace/set/append/prepend/cas命令,retreval就是读取命令,即get\gets命令,other就是除了存储命令,get\gets命令,touch命令,incr/desc命令之外的命令。

例如get\gets命令,先是SW_REQ_TYPE,就是get\gets字符串,再是SW_SPACES_BEFORE_KEY,即空格,然后使SW_KEY,就是键名,接着回到SW_SPACES_BEFORE_KEY,不断往复。

memcache文本协议的回复的解析

这个是在proto/memcache.c里的memcache_parse_rsp函数

它也是用有限状态机去完成解析的,下面是这些状态。

 1    enum {
 2         SW_START,
 3         SW_RSP_NUM,
 4         SW_RSP_STR,
 5         SW_SPACES_BEFORE_KEY,
 6         SW_KEY,
 7         SW_SPACES_BEFORE_FLAGS,     /* 5 */
 8         SW_FLAGS,
 9         SW_SPACES_BEFORE_VLEN,
10         SW_VLEN,
11         SW_RUNTO_VAL,
12         SW_VAL,                     /* 10 */
13         SW_VAL_LF,
14         SW_END,
15         SW_RUNTO_CRLF,
16         SW_CRLF,
17         SW_ALMOST_DONE,             /* 15 */
18         SW_SENTINEL
19     } state; 

这里的有限状态机图如下:

例如,如果是get和gets的回复就会先进入SW_RSP_STR,即“VALUE”,接着进入SW_SPACES_BEFOER_KEY这条线,知道这行的结束SW_RUNTO_CRLF,然后进入数据块SW_RUNTO_VAL这条线,知道SW_RSP_STR,直至到SW_RSP_STR中解析出“END”,会到SW_CRLF这条线。

总结

本文主要介绍了memcache的文本协议以及tweproxy如何解析memcache请求包和memcache回复包。

时间: 2024-09-29 17:28:23

twemproxyMemcache协议解析探索——剖析twemproxy代码正编补充的相关文章

twemproxyRedis协议解析探索——剖析twemproxy代码正编

这篇文章会对twemproxyRedis协议解析代码部分进行一番简单的分析,同时给出twemproxy目前支持的所有Redis命令.在这篇文章开始前,我想大家去简单地理解一下有限状态机,当然不理解也是没有问题的,有限状态机仅仅能帮助我们更好地理解twemproxyRedis协议解析代码部分. redis 协议 这边我们首先需要简单介绍一下redis协议.参考自https://redis.io/topics/protocol redis协议即RESP 的数据类型有5类,简单字符串.错误.整数.大字

twemproxy发送流程探索——剖析twemproxy代码正编

本文想要完成对twemproxy发送流程--msg_send的探索,对于twemproxy发送流程的数据结构已经在<twemproxy接收流程探索--剖析twemproxy代码正编>介绍过了,msg_send和msg_recv的流程大致类似.请在阅读代码时,查看注释,英文注释是作者对它的代码的注解,中文注释是我自己的感悟. 函数msg_send 1 rstatus_t 2 msg_send(struct context *ctx, struct conn *conn) 3 { 4 rstatu

通用轻量级二进制格式协议解析器

在通信协议中,经常碰到使用私有协议的场景,报文内容是肉眼无法直接看明白的二进制格式.由于协议的私有性质,即使大名鼎鼎的 Wireshark,要解析其内容,也无能为力. 面对这种情况,开发人员通常有两个办法:第一,对照报文内容和协议规范进行人工分析(假设内容没有经过加密.压缩):第二,编程实现协议报文的解析(源于程序员的懒惰 ^_^). 很明显,第二条道路是主流.目前比较常见的实现方式是开发对应的 Wireshark 插件,包括 C.Lua 等插件.当然,插件完成后需要运行 Wireshark 才

协议解析Bug分析

协议解析Bug分析 源自邮件协议RPC(远程过程调用)处理的Request请求数据包的bug.        一.Bug描述 腾讯收购的Foxmail客户端可以作为outlook客户端的替代品与Exchange服务端进行交互完成邮件收发.而我们所要做的就是让邮件经过我们代理的优化处理. 这时候问题来了,Outlook客户端经由我们代理没有任何问题:但是换成Foxmail就会有错误弹窗,错误号:0x000006BE.但是如果不经过代理,Foxmail收发邮件一切正常. 很明显,是代理出了问题.  

视音频数据处理入门:UDP-RTP协议解析

===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理入门:PCM音频采样数据处理 视音频数据处理入门:H.264视频码流解析 视音频数据处理入门:AAC音频码流解析 视音频数据处理入门:FLV封装格式解析 视音频数据处理入门:UDP-RTP协议解析 ===================================================

i2c知识总结及协议解析

知识总结部分: 一. 技术性能: 工作速率有100K和400K两种: 支持多机通讯: 支持多主控模块,但同一时刻只允许有一个主控: 由数据线SDA和时钟SCL构成的串行总线: 每个电路和模块都有唯一的地址: 每个器件可以使用独立电源 二. 基本工作原理: 以启动信号START来掌管总线,以停止信号STOP来释放总线: 每次通讯以START开始,以STOP结束: 启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R. /W位为0表示由主控向被控器件写

CJ/T-188 冷热量表协议解析2

本文具体阐述JY公司冷热量表(记热量)传输协议,并以此说明CJ/T-188协议在厂家具体应用时,并不一致.本文及后续文章将对这些不同点予以总结(文中所述协议与日志"CJ/T-188 冷热量表协议解析1"http://user.qzone.qq.com/2756567163/blog/1437462157的不同之处,将用红色予以标识).以下数据未经特殊说明,均指十六进制. 数据发送: FE FE FE FE 68 20 32 41 31 40 00 00 00 01 03 90 1F 0

经常使用传感器协议3:CJ/T-188 冷热量表协议解析2

????本文详细阐述JY公司冷热量表(记热量)传输协议.并以此说明CJ/T-188协议在厂家详细应用时,并不一致. 本文及兴许文章将对这些不同点予以总结(文中所述协议与日志"CJ/T-188 冷热量表协议解析1"http://user.qzone.qq.com/2756567163/blog/1437462157的不同之处,将用红色予以标识).下面数据未经特殊说明.均指十六进制. ????数据发送: ????????FE FE FE FE?68 20 32 41 31 40 00 00

AOSP中的HLS协议解析

[时间:2018-04] [状态:Open] [关键词:流媒体,stream,HLS, AOSP, 源码分析,HttpLiveSource, LiveSession,PlaylistFetcher] 1. 引言 本文作为HLS综述的后续文章,也是我之前对Nuplayer源码分析中GenericSource源码解析的姊妹篇.当然本文侧重于结合HLS原理来分析NuPlayer中相关实现逻辑.如果你对NuPlayer不是很了解,建议先简单了解下. 本文重点关注的是NuPlayer中的HttpLiveS