Redis協(xié)議具體用法詳解
前言
我們用過很多redis的客戶端,有沒有相過自己擼一個redis客戶端?其實(shí)很簡單,基于socket,監(jiān)聽6379端口,解析數(shù)據(jù)就可以了。
redis協(xié)議
解析數(shù)據(jù)的過程主要依賴于redis的協(xié)議了。我們寫個簡單例子看下redis的協(xié)議:
public class RedisTest { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.set("eat", "I want to eat"); }}
監(jiān)聽socket:
public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(6379); Socket socket = server.accept(); byte[] chars = new byte[64]; socket.getInputStream().read(chars); System.out.println(new String(chars)); }
看下數(shù)據(jù):
*3$3SET$3eat$13I want to eat
參照官方協(xié)議文檔https://redis.io/topics/protocol,解析下數(shù)據(jù)。
(1)簡單字符串 Simple Strings, 以 "+"加號 開頭(2)錯誤 Errors, 以"-"減號 開頭(3)整數(shù)型 Integer, 以 ":" 冒號開頭(4)大字符串類型 Bulk Strings, 以 "$"美元符號開頭,長度限制512M(5)組類型 Arrays,以 "*"星號開頭并且,協(xié)議的每部分都是以 "\r\n" (CRLF) 結(jié)尾的。
所以上面的數(shù)據(jù)的含義是:
*3 數(shù)組包含3個元素,分別是SET、eat、I want to eat$3 是一個字符串,且字符串長度為3SET 字符串的內(nèi)容$3 是一個字符串,且字符串長度為3eat 字符串的內(nèi)容$13 是一個字符串,且字符串長度為13I want to eat 字符串的內(nèi)容
執(zhí)行g(shù)et 'eat'的數(shù)據(jù)如下:
*2$3GET$3eat
擼一個客戶端
掌握了redis協(xié)議,socket之后,我們就可以嘗試擼一個客戶端了。
socket:
public RedisClient(String host, int port){ try { this.socket = new Socket(host,port); this.outputStream = this.socket.getOutputStream(); this.inputStream = this.socket.getInputStream(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
set協(xié)議:
public String set(final String key, String value) { StringBuilder sb = new StringBuilder(); //雖然輸出的時候,會被轉(zhuǎn)義,然而我們傳送的時候還是要帶上\r\n sb.append("*3").append("\r\n"); sb.append("$3").append("\r\n"); sb.append("SET").append("\r\n"); sb.append("$").append(key.length()).append("\r\n"); sb.append(key).append("\r\n"); sb.append("$").append(value.length()).append("\r\n"); sb.append(value).append("\r\n"); byte[] bytes= new byte[1024]; try { outputStream.write(sb.toString().getBytes()); inputStream.read(bytes); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new String(bytes); }
測試:
RedisClient redisClient = new RedisClient("127.0.0.1", 6379); String result = redisClient.set("eat", "please eat"); System.out.println(result);
執(zhí)行結(jié)果:
+OK
更多Redis相關(guān)技術(shù)文章,請?jiān)L問Redis教程欄目進(jìn)行學(xué)習(xí)!
相關(guān)文章
使用redis-plus-plus庫連接redis的實(shí)現(xiàn)方法
本文主要介紹了使用redis-plus-plus庫連接redis的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
redis實(shí)現(xiàn)延時隊(duì)列的兩種方式(小結(jié))
這篇文章主要介紹了redis實(shí)現(xiàn)延時隊(duì)列的兩種方式(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Redis系列之底層數(shù)據(jù)結(jié)構(gòu)SDS詳解
SDS(簡單動態(tài)字符串)是Redis使用的核心數(shù)據(jù)結(jié)構(gòu),用于替代C語言的字符串,以解決長度獲取慢、內(nèi)存溢出等問題,SDS通過預(yù)分配與惰性釋放策略優(yōu)化內(nèi)存使用,增強(qiáng)安全性,且能存儲文本與二進(jìn)制數(shù)據(jù),可查看源碼src/sds.h和src/sds.c了解更多2024-11-11
redis做websocket分布式消息推送服務(wù)的實(shí)現(xiàn)
本文介紹了使用Redis作為消息隊(duì)列實(shí)現(xiàn)WebSocket分布式消息推送服務(wù)的方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
基于Redis實(shí)現(xiàn)雙加密Token的示例代碼
在現(xiàn)代分布式系統(tǒng)中,Token管理是身份驗(yàn)證和授權(quán)的核心部分,本文將深入分析一個基于Redis的Token管理實(shí)現(xiàn),探討其設(shè)計(jì)思路、關(guān)鍵代碼邏輯以及實(shí)現(xiàn)細(xì)節(jié),通過對源碼的逐層剖析,幫助讀者更好地理解Token管理的實(shí)現(xiàn)原理,需要的朋友可以參考下2025-01-01
異步redis隊(duì)列實(shí)現(xiàn) 數(shù)據(jù)入庫的方法
今天小編就為大家分享一篇異步redis隊(duì)列實(shí)現(xiàn) 數(shù)據(jù)入庫的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10

