【redis知识点整理】 --- RESP协议 + 手写一个简单的redis客户端

RESP协议官网:https://redis.io/topics/protocol
RESP协议中文官网:http://www.redis.cn/topics/protocol.html
本文代码对应的github地址:https://github.com/nieandsun/redis-study



1 RESP协议简介

RESP( REdis Serialization Protocol) 是Redis客户端与Redis服务器间进行通讯的协议。其主要特点如下:

  • 容易实现
  • 解析快
  • 人类可读

RESP 底层采用的是 TCP 的连接方式, 通过 tcp 进行数据传输, 然后根据解析规则解析相应信息, 完成交互。

我们可以测试下, 首先运行一个 serverSocket 监听 6379, 来接收 redis 客户端的请求信息, 实现如下:

//模拟redis服务器
public class ServerRedis {
    public static void main(String[] args) {
        try {
            //监听6379端口
            ServerSocket serverSocket = new ServerSocket(6379);
            Socket rec = serverSocket.accept();
            byte[] result = new byte[2048];
            rec.getInputStream().read(result);
            System.out.println(new String(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

再通过redis的客户端jedis给6379端口发送请求:

public class ClientRedis {

    /***
     * 使用redis客户端jedis给6379端口发送消息
     * @param args
     */
    public static void main(String[] args) {

        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.set("name", "lisonLength");
        jedis.close();
    }
}

测试发现,服务端打印的信息如下:
在这里插入图片描述
这就是Resp协议的结构 — 》 AOF存储的就是这些命令,有兴趣的可以回看一下我的文章《【redis知识点整理】 — Redis的持久化》。


2 自己手写一个简单的redis客户端

1中可以看到,其实Jedis就是将我们的key 和 Value拼装成满足RESP协议的字符串通过Socket发送给了Redis服务器来完成与Redis服务器的交互。

这时候我们肯定会想,假如我们自己按照RESP的规范,拼装一个字符串,然后通过Socket发送给redis服务器,能不能完成存储和查询呢???

其实是可以的,举例如下:

package com.nrsc.redis.learning.resp;

import java.io.IOException;
import java.net.Socket;

public class SelfRedisClient {
    /*
    *3
    $3
    SET
    $4
    name
    $6
    rehash
     */
    public static String set(Socket socket, String key, String value) throws IOException {
        //按照RESP协议拼接字符串
        StringBuffer str = new StringBuffer();
        str.append("*3").append("\r\n");
        str.append("$3").append("\r\n");
        str.append("SET").append("\r\n");
        str.append("$").append(key.getBytes().length).append("\r\n");
        str.append(key).append("\r\n");
        str.append("$").append(value.getBytes().length).append("\r\n");
        str.append(value).append("\r\n");

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

    }

    /*
    *2
    $3
    GET
    $4
    name
     */
    public static String get(Socket socket, String key) throws IOException {
        //按照RESP协议拼接字符串
        StringBuffer str = new StringBuffer();
        str.append("*2").append("\r\n");
        str.append("$3").append("\r\n");
        str.append("GET").append("\r\n");
        str.append("$").append(key.getBytes().length).append("\r\n");
        str.append(key).append("\r\n");
        socket.getOutputStream().write(str.toString().getBytes());
        byte[] response = new byte[2048];
        socket.getInputStream().read(response);
        return new String(response);
    }

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 6379);
        String set = set(socket, "shaka", "loveStus");
        System.out.println(set);
        System.out.println(get(socket, "shaka"));
    }
}

测试结果如下,可以看到用我们自己写的客户端确实可以与redis服务器进行交互,完成存储和读取数据。
在这里插入图片描述


end!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nrsc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值