Redis通信协议RESP及模拟RedisClient

RESP协议

RESP(即Redis Serialization Protocol)是Redis底层的通信协议。Redis客户端连接到Redis服务器,以创建与端口6379的TCP连接,通过RESP协议进行通信。

RESP 是基于请求-响应模型的。Redis接受由不同参数组成的命令。收到命令后,将对其进行处理并将答复发送回客户端。
但是有两个例外:
1、Redis支持管道模式(pipeline)。客户端可以一次发送多个命令,并在以后等待答复。
2、当Redis客户端订阅Pub / Sub通道时,该协议会更改语义并成为推送协议,也就是说,客户端不再需要发送命令,因为服务器会自动向客户端发送新消息(对于客户端的通道被订阅)。
除了上述两个例外,Redis协议是一种简单的请求-响应协议。

 

请求报文

get请求

get key1

对应的RESP协议报文:

*2
$3
get
$4
key1

其中 

*2 

表示有2个参数

$3
get

表示第1个参数长度为3,值为'get'

$4
key1

表示第2个参数长度为4,值为'key1'

 

set请求

set key1 value1

对应的RESP协议报文:

*3
$3
set
$4
key1
$6
value1

其中 

*3

表示有3个参数

$3
set

表示第1个参数长度为3,值为'set'

$4
key1

表示第2个参数长度为4,值为'key1'

$6
value1

表示第3个参数长度为6,值为'value1'

类似的redis命令都可以通过这种格式生成请求报文。

 

响应报文

根据数据类型不同,响应报文的开头共有5种类型:

  1. 单行字符串 以 + 符号开头。
  2. 多行字符串 以 $ 符号开头,后跟字符串长度。 
  3. 整数值 以 : 符号开头,后跟整数的字符串形式。 
  4. 错误消息 以 - 符号开头。 
  5. 数组 以 * 号开头,后跟数组的长度。

如:

+value1\r\n

表示字符串

-WRONGTYPE Operation against a key holding the wrong kind of value\r\n

 表示错误消息

 

模拟Redis-Client

通过Socket模拟,传输RESP报文,来实现一个简单的get,set请求。

    public static String get(Socket socket, String key) throws IOException {
        StringBuffer str = new StringBuffer();
        str.append("*2").append("\r\n");
        str.append("$3").append("\r\n");
        str.append("set").append("\r\n");
        // key
        str.append("$").append(key.getBytes().length).append("\r\n");
        str.append(key).append("\r\n");

        // 发送resp
        socket.getOutputStream().write(str.toString().getBytes());
        byte[] response = new byte[2048];
        socket.getInputStream().read(response);
        return new String(response);
    }
    public static String set(Socket socket, String key, String value) throws IOException {
        StringBuffer str = new StringBuffer();
        // 一共3个参数
        str.append("*3").append("\r\n");
        // 第一个set
        str.append("$3").append("\r\n");
        str.append("set").append("\r\n");
        // key
        str.append("$").append(key.getBytes().length).append("\r\n");
        str.append(key).append("\r\n");
        // value
        str.append("$").append(value.getBytes().length).append("\r\n");
        str.append(value).append("\r\n");

        // 发送resp
        socket.getOutputStream().write(str.toString().getBytes());
        byte[] response = new byte[2048];
        socket.getInputStream().read(response);
        return new String(response);
    }

以此类推,其他简单的Redis命令也能通过手写RESP来实现。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值