前言
Redis的客户端与服务端采用叫做 RESP(Redis Serialization Protocol)的网络通信协议交换数据,客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 。客户端和服务器发送的命令或数据一律以 (CRLF)结尾。
RESP支持五种数据类型
状态回复(status reply):以“+”开头,表示正确的状态信息,”+”后就是具体信息,比如:
redis 127.0.0.1:6379> set ss sdfOK
其实它真正回复的数据是:+OK
错误回复(error reply):以”-“开头,表示错误的状态信息,”-“后就是具体信息,比如:
redis 127.0.0.1:6379> incr ss(error) ERR value is not an integer or out of range
整数回复(integer reply):以”:”开头,表示对某些操作的回复比如DEL, EXISTS, INCR等等
redis 127.0.0.1:6379> incr aa(integer) 1
批量回复(bulk reply):以”$”开头,表示下一行的字符串长度,具体字符串在下一行中
多条批量回复(multi bulk reply):以”*”开头,表示消息体总共有多少行(不包括当前行)”*”是具体行数
redis 127.0.0.1:6379> get ss"sdf"客户端->服务器*2$3get$2ss服务器->客户端$3sdf
注:以上写的都是XX回复,并不是说协议格式只是适用于服务器->客户端,客户端->服务器端也同样使用以上协议格式,其实双端协议格式的统一更加方便扩展
回到正题,我们这里是通过netty来模拟redis服务器,可以整理一下思路大概分为这么几步:
1.需要一个底层的通信框架,这里选择的是netty4.0.252.需要对客户端穿过来的数据进行解码(Decoder),其实就是分别处理以上5种数据类型3.解码以后我们封装成更加利于理解的命令(Command),比如:set foo hello4.有了命令以后就是处理命令(execute),其实我们可以去连接正在的redis服务器,不过这里只是简单的模拟5.处理完之后就是封装回复(Reply),然后编码(Encoder),需要根据不同的命令分别返回以后5种数据类型6.测试验证,通过redis-cli去连接netty模拟的redis服务器,看能否返回正确的结果
以上思路参考github上的一个项目:https://github.com/spullara/redis-protocol,测试代码也是在此基础上做了一个简化
第一步:通信框架netty
io.nettynetty-all4.0.25.F