Redis協議,簡單實現Jedis客戶端

說明:本人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));


    }
}

2、運行Jedis代碼

	@Test
	public void test1() {
		//建立連接 需要關閉防火牆 用密碼連接
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		
		//插入一個字符鍵age 20
		jedis.set("age", "20");
		
		//關閉連接
		jedis.close();
	}

3、查看結果

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

運行代碼

運行windowsRedis客戶端,檢查是否插入

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章