站長資訊網
        最全最豐富的資訊網站

        redis通信協議(protocol)

        redis通信協議(protocol)

        redis的ping pong

        登錄redis cli客戶端后, 輸入ping, 服務器會返回pong, 來表示連接狀況是完好的, 也表示了服務器大體上是正常運轉的.

        redis通信協議(protocol)

        其中的第一行是我用docker 啟動的客戶端, 大家如果不是docker的話, 自己正常啟動redis -cli就行..

        ping之后就會收到pong

        使用Java socket 來實現 Redis 的ping pong

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務器寫         os.write("PINGrn".getBytes());           //從redis服務器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

        返回的結果如下:

        redis通信協議(protocol)

        為什么會有一個 '+'符號 呢? redis -cli里是沒有這個加號的呀?

        這個和通信協議有關, 一會兒再介紹具體的含義. 不過redis -cli只是把這個'+'符號吞掉處理了, 沒顯示出來罷了。

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務器寫         os.write("PINGrn".getBytes());           //從redis服務器讀,到bytes中         byte[] bytes = new byte[1024];         if(is.read()=='+'){             // to string 輸出一下             int len = is.read(bytes);             System.out.println(new String(bytes,0,len));         }         // else if $         // else if *         // else     }

        這樣就跟redis -cli里的一樣啦.就只是pong了

        redis通信協議(protocol)

        實現SET 和 GET

        set:

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務器寫         os.write("set hello world123rn".getBytes());           //從redis服務器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

        get:

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.310", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務器寫         os.write("get hellorn".getBytes());           //從redis服務器讀,到bytes中         byte[] bytes = new byte[1024];         int len = is.read(bytes);           // to string 輸出一下         System.out.println(new String(bytes,0,len));     }

        redis通信協議(protocol)

        解釋上面例子中的+和$符號

        加號'+' 是來表示狀態回復的, 在redis服務端向客戶端返回狀態信息時, 就會先發送一個`+`符號來開頭.

        接下來是相應的狀態信息, 例如'OK'什么的.

        最后, 要以'rn' 來結尾… 咱們看一下代碼就明白了

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         InputStream is = socket.getInputStream();           // 向redis服務器寫         os.write("set hello world123rn".getBytes());           //從redis服務器讀,到bytes中         byte[] bytes = new byte[1024];         if (is.read() == '+') {             System.out.println("這是一個狀態回復哦! 怎么知道的呢? `+` 號就表示 '狀態回復' 了");             int len = is.read(bytes);             System.out.println("回復的狀態是: " + new String(bytes, 0, len));         }           // 大家想不想看看bytes里面到底有幾個字符嗎?         System.out.println(Arrays.toString(bytes));         // 輸出的是 [79, 75, 13, 10, 0, 0, 0, 0, 0,....]         // 其中 79 75 是 `OK`         // 其中 13 10 是 `rn`         // 后面的一串0 是 表示沒有后續內容, 已經讀完.     }

        $ 表示批量讀取, 一般格式是: $<數字>, 數字來表示正文的內容的字節數

        redis通信協議(protocol)

        抓包后是這樣的, 客戶端向服務端發送了"get hello", 服務端向客戶端發送了藍色的這兩行.

        public static void main(String[] args) throws Exception {         // socket         Socket socket = new Socket("140.143.135.210", 6379);           // oi流         OutputStream os = socket.getOutputStream();         // 為了解析'rn'方便, 我就用改為字符流了         BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));           // 向redis服務器寫         os.write("get hellorn".getBytes());           // 緩沖數組         char[] chars = new char[1024];           //從redis服務器讀,到bytes中         if (br.read() == '$') {             System.out.println("這是一個批量回復哦! 怎么知道的呢? `$` 號就表示 '批量回復' 了");             System.out.println("$ 后面會跟一個數字, 來表示正文內容的大小");             // readLine直接能判斷'r' 'n'             int len = Integer.parseInt(br.readLine());             System.out.println("$后面跟著的數字是: " + len + ", 表示正文是" + len + "個字節, 接下來只要讀取" + len + "個字節就好了");               // 接下來只讀取len個字符就ok了  (其實單位應該是字節, 但是我中途為了readLine省事, 改用了字符流, 個數是不變的)             br.read(chars, 0, len);             System.out.println("get到的結果是: " + new String(chars, 0, len) + ", 數一數真的是" + len + "個字符");         }     }

        Redis通信協議就只是這樣?

        no!!!剛才客戶端向服務端發送的 "get hello" , 這種只是"內聯命令", 而不是Redis真正的通信協議.

        問: 什么意思呢? 答: 就是說你可以像之前那樣給服務端發, 服務器端接受到后, 會遍歷一遍你發送的內容, 最后根據空格來分析你所發的內容的含義.

        問: 這樣有什么不好的嗎? 答: 如果這樣的話, 你就把解析的工作交給了服務器來做, 會加大服務器的工作量.

        問: 那怎么樣才是符合規范的呢? 符合協議的話真的會提高服務器的效率? 答: 首先看一下符合協議的客戶端和服務端之間的交互把.如下例子:

        例: set java python ,抓到包之后是這樣的:

        redis通信協議(protocol)

        紅色是客戶端發送的內容, 藍色是服務器端返回的內容.

        咱們一起解析一下:

        *3表示 , 客戶端即將發送3段內容

        哪三段呢? 第一段: '$3 SET' 第二段: '$4 java' 第三段: '$6 python'

        更嚴格地說: 第一段: '$3rnSETrn' 第二段:'$4rnjavarn' 第三段:'$6rnpythonrn'

        $符號的意思在上一小節就已經提到過了, 表示下文的內容的長度, 方便服務器進行讀取.

        例如: $6就已經把python的長度給匯報出來了, 服務器只需要截取區間[index, index+6]就好了, 不需要去找空格在什么地方(找空格的時間復雜度是O(n), 而$6這種寫法是O(1) )

        Jedis

        其實Jedis做的工作大體就是把SET key value 這樣的格式轉化為下面這種格式, 然后發到Redis服務端:

        *3rn $3rn SETrn $3rn keyrn $5rn valuern

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 日韩精品国产自在欧美| 亚洲乱码精品久久久久..| 久久精品国产精品亜洲毛片| 国产午夜精品一区二区三区漫画 | 日本精品自产拍在线观看中文| 国产精品99久久精品| 日韩精品一区二区三区中文 | www亚洲欲色成人久久精品| 蜜芽亚洲av无码精品色午夜| 日韩精品无码久久一区二区三 | 亚洲国产精品第一区二区| 国产精品无码无需播放器| 亚洲国产精品一区二区第一页| 完整观看高清秒播国内外精品资源 | 欧美精品一区二区三区视频| 国产欧美精品一区二区三区| 亚洲精品无码Av人在线观看国产| 久久99精品九九九久久婷婷| 国产99视频精品免费视频76| 思思99热在线观看精品| 国产高清国产精品国产专区| 国产精品久久久久AV福利动漫| 久久影院综合精品| 日产精品久久久一区二区| 无码人妻丰满熟妇精品区| 无码国内精品久久人妻蜜桃| 亚洲精品无码鲁网中文电影| 中文无码久久精品| 无码精品久久久天天影视| 色妞ww精品视频7777| 人妻少妇精品视中文字幕国语| 日韩人妻无码精品一专区| 日韩精品无码一区二区中文字幕 | 成人国产精品高清在线观看| 99久久99久久久精品齐齐 | 亚洲av午夜成人片精品电影| 久久精品国产99国产精品| 国产成人综合久久精品尤物| 国产精品美女网站在线观看| 国产亚洲精品拍拍拍拍拍| 久久97久久97精品免视看秋霞|