Redis通信协议

原文: https://blog.csdn.net/xyz_dream/article/details/94494884





1.前言


redis日常开发多多少少都有使用过。不过大多数都停留在get set等基本操作,存数据,取数据等简单操作。对于redis的通信协议基本上都没怎么留意过,所以自己有必要通过博文记录一番。了解相对底层的东西,有助于我们更好的使用redis以及排查错误。



2.redis通信协议的基本内容


协议,无外乎就是信息内容的格式要client和server端遵守的某种规范。这个我们可以类比以前学习http协议的时候,是怎么来了解这个协议内容的。http协议分2大模块来研究,无外乎就是请求报文和响应报文的格式,以及其中参数的各种意义是什么,使用之后会产生什么效果罢了。那么我们也大致从这个思路来了解redis的通信协议。 暂且就叫 “请求报文” 和 “响应报文”吧。

详细文档信息,参考: http://doc.redisfans.com/topic/protocol.html

原官方文档参考: https://redis.io/topics/protocol


3.client请求报文



1. 基本语法格式如下:

<参数个数n> #表示接下来有几个参数
$<param_num> #第一个参数的长度
参数内容


$<param_num> #第n个参数的长度

(注: redis的每个命令必须都是\r\n结尾。)


2. 举例:

select 0
set name zhangsan

真实报文内容:
2 \r\n # 接下来有2个参数
$5 \r\n #第一个参数长度是5 (select)
select \r\n
$1 \r\n #第二个参数是1 (0)
0 \r\n
3 \r\n #接下来有3个参数
$3 \r\n#第一个参数 长度是3 (set)
set \r\n
$4 \r\n #第二个参数 长度是4 (name)
name \r\n
$8 \r\n #第三个参数 长度是8 (zhangsan)
zhangsan\r\n


4.server响应报文



基本语法解释:

server端响应的第一个字节代表含义如下:

1.正确状态回复 +

举例:
set name zhangsan # +OK\r\n (set成功)

2.错误状态回复 -

举例:
gets name # - command error\r\n

3.整数信息回复 :

举例:
zcard collection # 获取集合的总数 :10\r\n

4.批量信息回复 $

举例:
get name # $8\r\nzhangsan\r\n

5.多批量信息回复

举例:
keys # 3\r\n$3abc\r\n$4name\r\n (集合存在 abc,name 2个key)


5.telnet连接redis


由于我们现在知道了redis采用明文安全二进制文本的redis序列化协议实现通信。 那么可以通过telnet连接server。 类似 我们在使用memcached的时候,由于memcached使用存文本明文协议通信, 通过telnet充当客户端使用即可。 假如你本地没有安装redis官方客户端, 那么可以使用telnet充当客户端完全没有问题。


telnet  server  6379


>select 0
>+OK
>set name zhangsan
>+OK
>get name
>$8\r\nzhangsan\r\n (\r\n在屏幕上以及被显示成回车换行了,这里只是还原server端原文信息)



6.总结



无论是java的客户端Jredis 还是说 针对php的redis客户端扩展,原理其实是一样的。这些客户端只是把我们的命令翻译成为了redis请求报文格式,发送给server端的6379端口,server端响应请求之后, 客户端拿到信息 ,解析成为java变量或者php变量等等而已, 这些工具包所提供的功能经此而已。


我们自己完全可以使用socket进行编程, 按照redis客户端请求报文规范,一样能访问和操作redis。只不过,我们的主要精力在工作的业务代码逻辑上,而非是在处理redis的操作上,所以没必要自己去搞一个工具库。不过,这样能够让你对于理解redis客户端和服务端通信过程更加深刻和理解。 每当操作redis的时候,我们的脑海中自然出现了底层实际发送数据流向的画面, 自然以后排查错误就知根知底了


知其然,更要知其所以然。我觉得这个对于我们学习是很有帮助的。