欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis协议,简单实现Jedis客户端

程序员文章站 2022-05-19 14:14:13
...

说明:本人linux的redis设置了密码,所以还是选择了windows的redis,性质都一样

目录

一、Redis协议--RESP

二、Redis协议查看及分析

三、简单手写Jedis客户端


一、Redis协议--RESP

Redis 的客户端和服务端之间采取了一种独立名为 RESP(Redis Serialization Protocol) 的协议,作者主要考虑了以下几个点:

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

注意:RESP 虽然是为 Redis 设计的,但是同样也可以用于其他 C/S 的软件。

 

二、Redis协议查看及分析

1、写一个假的服务器端来接收Jedis传来的信息,并启动

package com;

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

/**
 * @Description
 * 假的Redis服务端
 * @Author xuexue
 * @Date 2019/10/1121:14
 */
public class JedisServer {

    public static void main(String[] args) throws IOException {
        //默认为本机(127.0.0.1),假的服务端
        ServerSocket serverSocket = new ServerSocket(6379);

        //接收来自端口6379的信息
        Socket accept = serverSocket.accept();

        //定义字节数组接收来自Jedis发收过来的信息
        byte[] t = new byte[2048];
        accept.getInputStream().read(t);

        //打印信息
        System.out.println(new String(t));


    }
}

Redis协议,简单实现Jedis客户端

2、运行Jedis代码

	@Test
	public void test1() {
		//建立连接 需要关闭防火墙 用密码连接
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		
		//插入一个字符键age 20
		jedis.set("age", "20");
		
		//关闭连接
		jedis.close();
	}

3、查看结果

Redis协议,简单实现Jedis客户端

4、分析

对指令jedis.set("age", "20")分析,其实就是set(key,value)

*3 *后面数字表示几组命令,这里三组分别表示set、key、value
$3 $后面表示指令的长度,这里SET表示长度为3
SET 表示指令一set
$3 $后面表示指令内容的长度,这里key的内容是age,表示长度为3
age 表示指令二key的内容
$2 $后面表示指令内容的长度,这里value的内容是20,表示长度2
20 表示指令三value的内容

这就是RESP协议简单的分析,当然还有很多复杂的,这里就不介绍(特点简单,人类可读)

 

三、简单手写Jedis客户端

过程

1、手写Jedis客户端set功能(拼接RESP协议,向服务器发送RESP协议,协议内容主要是插入,接收服务器响应信息)

2、手写Jedis客户端get功能(拼接RESP协议,向服务器发送RESP协议,协议内容主要是请求内容,接收服务器返回key的内容)

3、手写Jedis客户端,发送Socket跟服务器通信

直接贴代码,解析很详细

package com;

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

/**
 * @Description
 * 模拟Jedis,实现字符串set/get方法
 * 要点:RESP协议
 * @Author xuexue
 * @Date 2019/10/11 20:24
 */
public class MyJedisClient {

    /**
     * 实现Jedis的set方法
     * 手写Jedis客户端set功能(拼接RESP协议,向服务器发送RESP协议,协议内容主要是插入,接收服务器响应信息)
     * @return String 服务器响应信息
     */
    public static String set(Socket socket, String key, String value) throws IOException {
        //定义一个变成字符串,用于拼接符合RESP字符串指令
        StringBuffer stf = new StringBuffer();

        //拼接指令长度SET(key,value)三个指令,长度为3,就是*3
        stf.append("*3").append("\r\n");

        //拼接指令SET字符串,拼接SET指令长度为$3
        stf.append("$3").append("\r\n");
        stf.append("SET").append("\r\n");

        //拼接key指令内容长度$key.length(),拼接指令key字符串,
        stf.append("$").append(key.length()).append("\r\n");
        stf.append(key).append("\r\n");

        //拼接指令value.getBytes()字符串,拼接key指令内容长度$key.length()
        stf.append("$").append(value.length()).append("\r\n");
        stf.append(value).append("\r\n");
        byte[] b = new byte[2048];
        socket.getOutputStream().write(stf.toString().getBytes());
        socket.getInputStream().read(b);
        return new String(b);
    }

    /**
     * 实现Jedis的get方法
     * 手写Jedis客户端get功能
     * (拼接RESP协议,向服务器发送RESP协议,协议内容主要是请求内容,接收服务器返回内容)
     * @return String 服务器返回key的内容
     */
    public static String get(Socket socket, String key) throws IOException {
        //定义一个变成字符串,用于拼接符合RESP字符串指令
        StringBuffer stf = new StringBuffer();

        //拼接指令长度SET(key,value)三个指令,长度为3,就是*3
        stf.append("*2").append("\r\n");

        //拼接指令SET字符串,拼接SET指令长度为$3
        stf.append("$3").append("\r\n");
        stf.append("GET").append("\r\n");

        //拼接key指令内容长度$key.length(),拼接指令key字符串,
        stf.append("$").append(key.length()).append("\r\n");
        stf.append(key).append("\r\n");

        byte[] b = new byte[2048];
        socket.getOutputStream().write(stf.toString().getBytes());
        socket.getInputStream().read(b);
        return new String(b);
    }

    public static void main(String[] args) throws IOException {

        //手写Jedis客户端,发送Socket跟服务器通信
        Socket socket = new Socket("127.0.0.1",6379);
        String lisi = MyJedisClient.set(socket, "lisi", "333");
        System.out.println(lisi);
        System.out.println(MyJedisClient.get(socket,"lisi"));
    }
}

打开windows的redis

Redis协议,简单实现Jedis客户端

运行代码

Redis协议,简单实现Jedis客户端

运行windowsRedis客户端,检查是否插入

Redis协议,简单实现Jedis客户端

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关标签: Redis协议 RESP