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


这种对不同消息类型的处理是在客户端进行区分的 。
Inline commands如果完全按RESP协议的要求,当我们连接到服务器端的时候需要包含RESP中定义消息的所有格式,但是这些消息中包含了额外的消息类型和回车换行符,所以直接使用协议来执行的话会比较困惑 。
于是redis还提供一些内联的命令,也就是协议命令的精简版本,这个精简版本去除了消息类型和回车换行符 。
我们以"get world"这个命令为例 。来看下不同方式的连接情况 。
首先是使用redis-cli进行连接:
redis-cli -h 127.0.0.1127.0.0.1:6379> get world"hello"因为redis-cli是redis的客户端,所以可以直接使用inline command来执行命令 。
如果使用telnet,我们也可以使用同样的命令来获得结果:
telnet 127.0.0.1 6379Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.get world$5hello可以看到返回的结果是"$5\r\nhello\r\n" 。
如果要使用协议消息来请求redis服务器应该怎么做呢?
我们要请求的命令是"get world",将其转换成为RESP的消息则是:
"*2\r\n$3\r\nget\r\n$5\r\nworld\r\n"我们尝试一下将上述命令使用nc传递到redis server上:
(printf "*2\r\n$3\r\nget\r\n$5\r\nworld\r\n"; sleep 1) |nc localhost 6379-ERR Protocol error: expected '$', got ' '很遗憾我们得到了ERR,那么是不是不能直接使用RESP消息格式进行传输呢?当然不是,上面的问题在于$符号是一个特殊字符,我们需要转义一下:
(printf "*2\r\n\$3\r\nget\r\n\$5\r\nworld\r\n"; sleep 1) |nc localhost 6379$5hello可以看到输出的结果和直接使用redis-cli一致 。
总结以上就是RESP协议的基本内容和手动使用的例子,有了RESP,我们就可以根据协议中定义的格式来创建redis客户端 。
可能大家又会问了,为什么只是redis客户端呢?有了协议是不是redis服务器端也可以创建呢?答案当然是肯定的,只需要按照协议进行消息传输即可 。主要的问题在于redis服务器端的实现比较复杂,不是那么容易实现的 。

经验总结扩展阅读