网络协议之:redis protocol 详解( 二 )


使用pipline可以一次性发送多条指令,从而有效避免空间的切换行为 。
Redis中的Pub/Sub和Pub/Sub相关的命令是SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 。
为什么要用Pub/Sub呢?其主要的目的就是解耦,在Pub/Sub中消息发送方不需要知道具体的接收方的地址,同样的对于消息接收方来说,也不需要知道具体的消息发送方的地址 。他们只需要知道关联的主题即可 。
subscribe和publish的命令比较简单,我们举一个例子,首先是客户端subscribe topic:
redis-cli -h 127.0.0.1127.0.0.1:6379> subscribe topicReading messages... (press Ctrl-C to quit)1) "subscribe"2) "topic"3) (integer) 1然后在另外一个终端,调用publish命令:
redis-cli -h 127.0.0.1127.0.0.1:6379> publish topic "what is your name?"(integer) 1可以看到客户端会收到下面的消息:
1) "message"2) "topic"3) "what is your name?"RESP protocolRESP协议有5种类型,分别是imple Strings, Errors, Integers, Bulk Strings 和 Arrays 。
不同的类型以消息中的第一个byte进行区分,如下所示:
类型第一个byteSimple Strings+Errors-Integers:Bulk Strings$Arrays*protocol中不同的部分以 "\r\n" (CRLF)来进行区别 。
Simple StringsSimple Strings的意思是简单的字符串 。
通常用在服务器端的返回中,这种消息的格式就是"+"加上文本消息,最后以"\r\n"结尾 。
比如服务器端返回OK,那么对应的消息就是:
"+OK\r\n"上面的消息是一个非二进制安全的消息,如果想要发送二进制安全的消息,则可以使用Bulk Strings 。
什么是非二进制安全的消息呢?对于Simple Strings来说,因为消息是以"\r\n"结尾,所以消息中间不能包含"\r\n"这两个特殊字符,否则就会产生错误的含义 。
Bulk StringsBulk Strings是二进制安全的 。这是因为Bulk Strings包含了一个字符长度字段,因为是根据长度来判断字符长度的,所以并不存在根据字符中某个特定字符来判断是否字符结束的缺点 。
具体而言Bulk Strings的结构是"$"+字符串长度+"\r\n"+字符串+"\r\n" 。
以OK为例,如果以Bulk Strings来表示,则如下所示:
"$2\r\nok\r\n"Bulk Strings还可以包含空字符串:
"$0\r\n\r\n"当然还可以表示不存在的Null值:
"$-1\r\n"RESP Integers这是redis中的整数表示,具体的格式是":"+整数+"\r\n" 。
比如18这个整数就可以用下面的格式来表示:
":18\r\n"RESP Arraysredis的多个命令可以以array来表示,服务器端返回的多个值也可以用arrays来表示 。
RESP Arrays的格式是"*"+数组中的元素个数+其他类似的数据 。
所以RESP Arrays是一个复合结构的数据 。比如一个数组中包含了两个Bulk Strings:"redis","server"则可以用下面的格式来表示:
"*2\r\n$5\r\nredis\r\n$6\r\nserver\r\n"RESP Arrays中的原始不仅可以使用不同类型,还能包含RESP Arrays,也就是array的嵌套:
"*3\r\n$5\r\nredis\r\n$6\r\nserver\r\n*1\r\n$4\r\ngood\r\n"为了方便观察,我们将上面的消息格式一下:
"*3\r\n$5\r\nredis\r\n$6\r\nserver\r\n*1\r\n$4\r\ngood\r\n"上面的消息是一个包含三个元素的数组,前面两个元素是Bulk Strings,最后一个是包含一个元素的数组 。
RESP Errors最后,RESP还可以表示错误消息 。RESP Errors的消息格式是"-"+字符串,如下所示:
"-Err something wrong\r\n"一般情况下,"-"后面的第一个单词表示的是错误类型,但是这只是一个约定俗成的规定,并不是RESP协议中的强制要求 。
另外,经过对比,大家可能会发现RESP Errors和Simple Strings是消息格式是差不多的 。

经验总结扩展阅读