原文: 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的时候,我们的脑海中自然出现了底层实际发送数据流向的画面, 自然以后排查错误就知根知底了知其然,更要知其所以然。我觉得这个对于我们学习是很有帮助的。