redis client protocol 解析

在官网http://redis.io/topics/protocol有对redis通信协议有做说明。

基于下面的一些原因,我想解析redis client protocol:

1、足够了解通信协议,有助于做出更好的系统设计。

2、学习RESP的设计思想,不仅能扩展我的思维,也许将来能应用于我的代码中。

3、因为有些人想将redis client直接并入自己已有的系统中;包括我在内。这个将在我下一篇文章再做说明。

下面我翻译一下http://redis.io/topics/protocol一些我认为重要的内容:

Redis clients communicate with the Redis server using a protocol called RESP (REdis Serialization Protocol). While the protocol was designed specifically for Redis, it can be used for other client-server software projects.

RESP is a compromise between the following things:

  • Simple to implement.
  • Fast to parse.
  • Human readable.

RESP can serialize different data types like integers, strings, arrays. There is also a specific type for errors. Requests are sent from the client to the Redis server as arrays of strings representing the arguments of the command to execute. Redis replies
with a command-specific data type.

RESP is binary-safe and does not require processing of bulk data transferred from one process to another, because it uses prefixed-length to transfer bulk data.

Note: the protocol outlined here is only used for client-server communication. Redis Cluster uses a different binary protocol in order to exchange messages between nodes.

译:

redis客户端和redis服务端用一种名叫RESP(REdis Serialization Protocol)的协议通信。虽然这种协议专门为redis设计,但是它能被用于其它基于C/S模型的软件项目中。

RESP是基于下面一些事实的一种折衷方案:

  • 易于实现
  • 快速解释
  • 人类可读

RESP能序列化不同的数据类型,例如整型,字符串,数组,还有专门的错误类型。客户端发送字符串数组请求到服务端,而字符串数组表示命令参数去执行。Redis会用专门的命令类型回复。

RESP是二进制安全的,同时过程转换中不需要大量的数据处理,因为它使用了前缀长度去转换批量数据。

注意:在这里概述的协议只用于客户端-服务端通信。而Redis集群为了不同节点交换消息使用了一种不同的二进制协议。

RESP is actually a serialization protocol that supports the following data types: Simple Strings, Errors, Integers, Bulk Strings and Arrays.

The way RESP is used in Redis as a request-response protocol is the following:

  • Clients send commands to a Redis server as a RESP Array of Bulk Strings.
  • The server replies with one of the RESP types according to the command implementation.

In RESP, the type of some data depends on the first byte:

  • For Simple Strings the first byte of the reply is "+"
  • For Errors the first byte of the reply is "-"
  • For Integers the first byte of the reply is ":"
  • For Bulk Strings the first byte of the reply is "$"
  • For Arrays the first byte of the reply is "*"

Additionally RESP is able to represent a Null value using a special variation of Bulk Strings or Array as specified later.

In RESP different parts of the protocol are always terminated with "\r\n" (CRLF).

译:

RESP实际上是一种支持下面数据类型的序列化协议:短字符串,错误,整数,长字符串和数组。

RESP作为一种请求-回应协议,在Redis中的使用方法如下:

  • 客户端发送一种犹如RESP中长字符串数组的命令到Redis服务端。
  • Redis服务端根据命令实现回复其中一种RESP类型。

在RESP中,一种数据类型基于第一个字节:

  • 对于短字符串,回复的第一个字节是"+"
  • 对于错误,回复的第一个字节是"-"
  • 对于整数,回复的第一个字节是":"
  • 对于长字符串,回复的第一个字节是"$"
  • 对于数组,回复的第一个字节是"*"

另外RESP能用指定的长字符串或数组的特殊变量来表示空值。

在RESP中,协议的不同部分总是以"\r\n"(CRLF)作为结束。

前面说到的协议,我有强调了是client,就是说server回复client请求时用到的协议;client请求server时,只需要在命令后面加上"\r\n"。

下面是5种类型的返回实例:

假设在redis server中存在以下键值对:
name1	cat
age1	10

短字符串
"set name2 fish\r\n"
"+OK\r\n"

错误
"seet name3 dog"
"-ERR unknown command 'seet'\r\n"

整数
"incr age1"
":11"

长字符串
①
"get name1\r\n"
"$3\r\ncat\r\n"
②
"get name3\r\n"
"$-1\r\n"

数组
①
"mget name1 age1\r\n"
"*2\r\n$3\r\ncat\r\n$2\r\n11\r\n"
②
"mget name2 age2\r\n"
"*2\r\n$4\r\nfish\r\n$-1\r\n"
③
其它情况会返回"*-1\r\n"和"*0\r\n",具体参考redis官方文档;

时间: 2024-12-27 09:40:04

redis client protocol 解析的相关文章

redis client protocol 实现

在官网中http://redis.io/clients有许多已经实现好的redis client:有需要可以参考一下. 其实前一篇http://blog.csdn.net/yitouhan/article/details/46612925 redis client protocol 解析,我已经对RESP做主要的解析. 下面是解析RESP的所有函数,其中对外函数是RedisProtocol::Decode: https://github.com/XJM2013/GameEngine/blob/m

【轮子狂魔】手把手教你自造Redis Client

为什么做Redis Client? Redis Client顾名思义,redis的客户端,主要是封装了一些对于Redis的操作. 而目前用的比较广泛的 ServiceStack.Redis 不学好,居然开始收费了. 作为轮子狂魔,是可忍孰不可忍啊.于是我决定自己造轮子了. Redis通信协议 先给个Redis官方的通信协议地址:http://redisdoc.com/topic/protocol.html 关键是我截图的部分,我们可以得到以下几个信息: 1.tcp协议 2.默认端口6379 3.

Redis client Python usage

mport redis r_server = redis.Redis('localhost') #this line creates a new Redis object and #connects to our redis server r_server.set('test_key', 'test_value') #with the created redis object we can #submits redis commands as its methods print 'previou

redis源码解析之事件驱动

Redis 内部有个小型的事件驱动,它主要处理两项任务: 文件事件:使用I/O多路复用技术处理多个客户端请求,并返回执行结果. 时间事件:维护服务器的资源管理,状态检查. 主要的数据结构包括文件事件结构体,时间事件结构体,触发事件结构体,事件循环结构体 /* File event structure */ typedef struct aeFileEvent { int mask; /* one of AE_(READABLE|WRITABLE) */ aeFileProc *rfileProc

Redis源码解析——双向链表

相对于之前介绍的字典和SDS字符串库,Redis的双向链表库则是非常标准的.教科书般简单的库.但是作为Redis源码的一部分,我决定还是要讲一讲的.(转载请指明出于breaksoftware的csdn博客) 基本结构 首先我们看链表元素的结构.因为是双向链表,所以其基本元素应该有一个指向前一个节点的指针和一个指向后一个节点的指针,还有一个记录节点值的空间 typedef struct listNode { struct listNode *prev; struct listNode *next;

lettuce--Advanced Redis client

redis官方提供的java client: git地址:https://github.com/mp911de/lettuceAdvanced Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.http://redis.paluch.biz Introduction Lettuce is a scalable thread

StackExchange.Redis Client

StackExchange.Redis Client 这期我们来看StackExchange.Redis,这是redis 的.net客户端之一.Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务.目前有不少人在使用ServiceStack.Redis这个.net客户端,但是这个的最新版本目前已经变成了商业软件.对于ServiceStack.Redis这种行为,我们没有什么好说的,留给我们的选择是使用低版本的开源版本或者转向其他的客户端. 要说到StackExchange.

redis源码解析之内存管理

zmalloc.h的内容如下: 1 void *zmalloc(size_t size); 2 void *zcalloc(size_t size); 3 void *zrealloc(void *ptr, size_t size); 4 void zfree(void *ptr); 5 char *zstrdup(const char *s); 6 size_t zmalloc_used_memory(void); 7 void zmalloc_enable_thread_safeness(v

Redis源码解析之ziplist

Ziplist是用字符串来实现的双向链表,对于容量较小的键值对,为其创建一个结构复杂的哈希表太浪费内存,所以redis 创建了ziplist来存放这些键值对,这可以减少存放节点指针的空间,因此它被用来作为哈希表初始化时的底层实现.下图即ziplist 的内部结构. Zlbytes是整个ziplist 所占用的空间,必要时需要重新分配. Zltail便于快速的访问到表尾节点,不需要遍历整个ziplist. Zllen表示包含的节点数. Entries表示用户增加上去的节点. Zlend是一个255