1.Memcached协议定义:
查看memached源码头文件:http://bazaar.launchpad.net/~tangent-trunk/libmemcached/1.2/view/head:/libmemcached/memcached/protocol_binary.h Memcached对操作类型定义了一个枚举类型,如下:
typedef enum { PROTOCOL_BINARY_CMD_GET = 0x00, PROTOCOL_BINARY_CMD_SET = 0x01, PROTOCOL_BINARY_CMD_ADD = 0x02, PROTOCOL_BINARY_CMD_REPLACE = 0x03, PROTOCOL_BINARY_CMD_DELETE = 0x04, PROTOCOL_BINARY_CMD_INCREMENT = 0x05, PROTOCOL_BINARY_CMD_DECREMENT = 0x06, PROTOCOL_BINARY_CMD_QUIT = 0x07, PROTOCOL_BINARY_CMD_FLUSH = 0x08, PROTOCOL_BINARY_CMD_GETQ = 0x09, PROTOCOL_BINARY_CMD_NOOP = 0x0a, PROTOCOL_BINARY_CMD_VERSION = 0x0b, PROTOCOL_BINARY_CMD_GETK = 0x0c, PROTOCOL_BINARY_CMD_GETKQ = 0x0d, PROTOCOL_BINARY_CMD_APPEND = 0x0e, PROTOCOL_BINARY_CMD_PREPEND = 0x0f, PROTOCOL_BINARY_CMD_STAT = 0x10, PROTOCOL_BINARY_CMD_SETQ = 0x11, PROTOCOL_BINARY_CMD_ADDQ = 0x12, PROTOCOL_BINARY_CMD_REPLACEQ = 0x13, PROTOCOL_BINARY_CMD_DELETEQ = 0x14, PROTOCOL_BINARY_CMD_INCREMENTQ = 0x15, PROTOCOL_BINARY_CMD_DECREMENTQ = 0x16, PROTOCOL_BINARY_CMD_QUITQ = 0x17, PROTOCOL_BINARY_CMD_FLUSHQ = 0x18, PROTOCOL_BINARY_CMD_APPENDQ = 0x19, PROTOCOL_BINARY_CMD_PREPENDQ = 0x1a, PROTOCOL_BINARY_CMD_VERBOSITY = 0x1b, PROTOCOL_BINARY_CMD_TOUCH = 0x1c, PROTOCOL_BINARY_CMD_GAT = 0x1d, PROTOCOL_BINARY_CMD_GATQ = 0x1e, PROTOCOL_BINARY_CMD_GATK = 0x23, PROTOCOL_BINARY_CMD_GATKQ = 0x24, PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 0x20, PROTOCOL_BINARY_CMD_SASL_AUTH = 0x21, PROTOCOL_BINARY_CMD_SASL_STEP = 0x22, PROTOCOL_BINARY_CMD_RGET = 0x30, PROTOCOL_BINARY_CMD_RSET = 0x31, PROTOCOL_BINARY_CMD_RSETQ = 0x32, PROTOCOL_BINARY_CMD_RAPPEND = 0x33, PROTOCOL_BINARY_CMD_RAPPENDQ = 0x34, PROTOCOL_BINARY_CMD_RPREPEND = 0x35, PROTOCOL_BINARY_CMD_RPREPENDQ = 0x36, PROTOCOL_BINARY_CMD_RDELETE = 0x37, PROTOCOL_BINARY_CMD_RDELETEQ = 0x38, PROTOCOL_BINARY_CMD_RINCR = 0x39, PROTOCOL_BINARY_CMD_RINCRQ = 0x3a, PROTOCOL_BINARY_CMD_RDECR = 0x3b, PROTOCOL_BINARY_CMD_RDECRQ = 0x3c, PROTOCOL_BINARY_CMD_SET_VBUCKET = 0x3d, PROTOCOL_BINARY_CMD_GET_VBUCKET = 0x3e, PROTOCOL_BINARY_CMD_DEL_VBUCKET = 0x3f, PROTOCOL_BINARY_CMD_TAP_CONNECT = 0x40, PROTOCOL_BINARY_CMD_TAP_MUTATION = 0x41, PROTOCOL_BINARY_CMD_TAP_DELETE = 0x42, PROTOCOL_BINARY_CMD_TAP_FLUSH = 0x43, PROTOCOL_BINARY_CMD_TAP_OPAQUE = 0x44, PROTOCOL_BINARY_CMD_TAP_VBUCKET_SET = 0x45, PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_START = 0x46, PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_END = 0x47, PROTOCOL_BINARY_CMD_LAST_RESERVED = 0xef, PROTOCOL_BINARY_CMD_SCRUB = 0xf0 } protocol_binary_command; |
memcached协议的实现见:https://github.com/memcached/memcached/wiki/BinaryProtocolRevamped, 这里有详细的协议描述。
2 分析Memcached的Get操作实现:
php-memcached扩展连接memcached执行一次Get操作的完整数据包如下, 抓包工具可以分析, 非常清晰:
0x0000: 4502 0051 44b2 4000 4006 0000 7f00 0001 E..QD.@.@....... 0x0010: 7f00 0001 f624 2bcc 9791 7255 c792 0c06 .....$+...rU.... 0x0020: 8018 31d7 fe45 0000 0101 080a 7164 6249 ..1..E......qdbI 0x0030: 7164 6249 800d 0005 0000 0000 0000 0005 qdbI............ 0x0040: 0001 0000 0000 0000 0000 0000 4865 6c6c ............Hell 0x0050: 6f GetKQ 0x0000: 4502 004c 8d28 4000 4006 0000 7f00 0001 E..L.(@.@....... 0x0010: 7f00 0001 f624 2bcc 9791 7272 c792 0c06 .....$+...rr.... 0x0020: 8018 31d7 fe40 0000 0101 080a 7164 6249 ..1..@......qdbI 0x0030: 7164 6249 800a 0000 0000 0000 0000 0000 qdbI............ 0x0040: 0002 0000 0000 0000 0000 0000 No-op 0x0000: 4502 005a f688 4000 4006 0000 7f00 0001 E..Z..@.@....... 0x0010: 7f00 0001 2bcc f624 c792 0c06 9791 728a ....+..$......r. 0x0020: 8018 31d5 fe4e 0000 0101 080a 7164 6249 ..1..N......qdbI 0x0030: 7164 6249 810d 0005 0400 0000 0000 000e qdbI............ 0x0040: 0001 0000 0000 0000 0000 0001 0000 0000 ................ 0x0050: 4865 6c6c 6f57 6f72 6c64 响应GetKQ 0x0000: 4502 004c fc54 4000 4006 0000 7f00 0001 E..L.T@.@....... 0x0010: 7f00 0001 2bcc f624 c792 0c2c 9791 728a ....+..$...,..r. 0x0020: 8018 31d5 fe40 0000 0101 080a 7164 6249 ..1..@......qdbI 0x0030: 7164 6249 810a 0000 0000 0000 0000 0000 qdbI............ 0x0040: 0002 0000 0000 0000 0000 0000 ............ 响应No-op 0x0000: 4502 004c 5a00 4000 4006 0000 7f00 0001 E..LZ.@.@....... 0x0010: 7f00 0001 f624 2bcc 9791 728a c792 0c44 .....$+...r....D 0x0020: 8018 31d5 fe40 0000 0101 080a 7164 6249 ..1..@......qdbI 0x0030: 7164 6249 8007 0000 0000 0000 0000 0000 qdbI............ 0x0040: 0003 0000 0000 0000 0000 0000 ............ Quit 0x0000: 4502 004c ce6b 4000 4006 0000 7f00 0001 E..L.k@.@....... 0x0010: 7f00 0001 2bcc f624 c792 0c44 9791 72a2 ....+..$...D..r. 0x0020: 8018 31d4 fe40 0000 0101 080a 7164 6249 ..1..@......qdbI 0x0030: 7164 6249 8107 0000 0000 0000 0000 0000 qdbI............ 0x0040: 0003 0000 0000 0000 0000 0000 响应 Quit |
这是一次get('Hello'),响应‘World’的完整数据包, get操作的协议类型是GetKQ,执行GetKQ之后会紧急着一次No-op。这些数据包的内容