go實(shí)現(xiàn)Redis讀寫分離示例詳解
我們?yōu)槭裁葱枰私釸ESP協(xié)議?
本篇文章目的為探究RESP
協(xié)議,而非編寫讀寫中間件,這點(diǎn)要清楚。
關(guān)于這個(gè)問(wèn)題,我想通過(guò)一個(gè)實(shí)例來(lái)解釋,我們編寫Redis
中間件,為什么需要了解RESP
協(xié)議。
以上代碼是編寫了一個(gè)非常簡(jiǎn)單的TCP
服務(wù)器,我們監(jiān)聽(tīng)8888
端口,嘗試使用redis-cli -p 8888
連接服務(wù)器后,而后查看打印出來(lái)的應(yīng)用層報(bào)文。
我們嘗試執(zhí)行下該代碼,并且輸入redis-cli -p 8888
進(jìn)行連接。
我們編寫的服務(wù)器獲取redis
客戶端的報(bào)文為:
*1
$7
COMMAND
上面這個(gè)就是RESP
協(xié)議的內(nèi)容了,所以說(shuō),我們要編寫一個(gè)Redis
的中間件,我們需要先了解一下RESP
協(xié)議才行。
什么是RESP協(xié)議
官網(wǎng)有相關(guān)的解釋: https://redis.io/docs/reference/protocol-spec/
RESP
協(xié)議創(chuàng)建之初是專門為了Redis
服務(wù)器和客戶端的通信而設(shè)計(jì)的,該協(xié)議在Redis 1.2
中引入,并且在Redis 2.0
中,成為Redis
通信的標(biāo)準(zhǔn)協(xié)議。該協(xié)議有如下優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡(jiǎn)單
- 快速解析
- 直接可閱讀
RESP
根據(jù)其協(xié)議前綴,可以序列化不同的數(shù)據(jù)類型,例如: 整數(shù)、字符串、數(shù)組 等,還能標(biāo)注 正常輸出 和 錯(cuò)誤輸出等。除了流水線和發(fā)布訂閱以外,RESP
協(xié)議應(yīng)該是最簡(jiǎn)單的請(qǐng)求-響應(yīng)協(xié)議了。關(guān)于更多介紹,大佬們可以看看上面注釋的官方文檔。
RESP協(xié)議規(guī)范
RESP
協(xié)議不同的部分使用\r\n
(換行符)來(lái)進(jìn)行分割,其支持5種數(shù)據(jù)類型,分別為: 簡(jiǎn)單字符串、錯(cuò)誤、整數(shù)、復(fù)雜字符串 和 數(shù)組組成,我們列個(gè)表格來(lái)講下。
類型 | 前綴 | 備注 |
---|---|---|
簡(jiǎn)單字符串 | + | 簡(jiǎn)單字符串以+開(kāi)頭 |
錯(cuò)誤數(shù)據(jù) | - | 錯(cuò)誤數(shù)據(jù)以-開(kāi)頭 |
整數(shù) | : | 整數(shù)以:開(kāi)頭 |
復(fù)雜字符串 | $ | 復(fù)雜字符串以$開(kāi)頭 |
數(shù)組 | * | 數(shù)組以*開(kāi)頭 |
我當(dāng)初看到這個(gè)的時(shí)候,也是迷迷糊糊的,到底什么意思呢? 哎,我們舉個(gè)例子你就明白了。
若我們想執(zhí)行
set juejinName pdudo
若使用RESP
協(xié)議應(yīng)當(dāng)如何編寫呢?應(yīng)當(dāng)編寫如下:
*3 $3 set $10 juejinName $5 pdudo
那我們來(lái)解釋一下*3
代表有3個(gè)數(shù)組,而$3
代表復(fù)雜字符串有長(zhǎng)度為3,值為set
, $10
代表復(fù)雜字符串長(zhǎng)度為10,值為juejinName
, $5
代表復(fù)雜字符串長(zhǎng)度為5,值為pdudo
。
我們結(jié)合上述信息,可以畫一張圖。
這就是協(xié)議的內(nèi)容了。
而協(xié)議前綴+
、-
、:
則要簡(jiǎn)單的多,直接跟數(shù)據(jù)即可,
例如:
+
+OK
-
-ERR syntax error
:
:3
如何使用該協(xié)議請(qǐng)求Redis
我們已經(jīng)學(xué)習(xí)了相關(guān)的RESP
協(xié)議,那么我們?nèi)绾螌W(xué)習(xí)呢? 我們可以使用telnet
命令來(lái)操作即可。
在此,我們準(zhǔn)備幾條命令,我們會(huì)將其轉(zhuǎn)換為RESP
格式,且將其發(fā)送到redis
服務(wù)器。
命令
set name pdudo get name lpush pn 1 llen pn
轉(zhuǎn)換為RESP
格式
*3 $3 set $4 name $5 pdudo *2 $3 get $4 name *3 $5 lpush $2 pn $1 1 *2 $4 llen $2 pn
我們將其放置到telnet
中執(zhí)行一下呢
現(xiàn)在回頭看看官網(wǎng)文檔所提及的,該協(xié)議實(shí)現(xiàn)簡(jiǎn)單,直接可閱讀,是不是理解的更加深刻了呢?
使用go編寫Redis中間件實(shí)現(xiàn)讀寫分離
本篇暫不解釋代碼,而后單獨(dú)開(kāi)一篇談?wù)撝虚g件代碼。
實(shí)現(xiàn)該功能,其實(shí)本質(zhì)上是區(qū)分命令是查詢還是寫入,若是查詢,則直接轉(zhuǎn)發(fā)到從庫(kù),而寫入,則轉(zhuǎn)發(fā)到主庫(kù)即可,其架構(gòu)圖可以理解為如下:
我們已經(jīng)有了目前的架構(gòu)。
主機(jī) | 端口 | 密碼 | 角色 |
---|---|---|---|
127.0.0.1 | 6379 | 無(wú) | 主庫(kù) |
127.0.0.1 | 7380 | 無(wú) | 從庫(kù) |
相關(guān)代碼已經(jīng)放到了 gitee.com/pdudo/golea…
我們來(lái)看看實(shí)際效果呢:
總結(jié)
其實(shí)本篇文章核心的點(diǎn)是探究RESP
協(xié)議,而我們使用go
編寫了一個(gè)軟件,用于解析RESP
協(xié)議,從而獲取執(zhí)行的命令,再根據(jù)命令屬性,從而轉(zhuǎn)發(fā)從庫(kù)或者主庫(kù),以此來(lái)達(dá)到讀寫分離的效果。再次提及一下核心點(diǎn)是拆解RESP
協(xié)議。
怎么樣,好玩吧,動(dòng)動(dòng)你的小手指,快來(lái)試試吧。
以上就是go實(shí)現(xiàn)Redis讀寫分離示例詳解的詳細(xì)內(nèi)容,更多關(guān)于go Redis讀寫分離的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解prometheus監(jiān)控golang服務(wù)實(shí)踐記錄
這篇文章主要介紹了詳解prometheus監(jiān)控golang服務(wù)實(shí)踐記錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11Apache?IoTDB開(kāi)發(fā)系統(tǒng)之Go原生接口方法
這篇文章主要為大家介紹了?Apache?IoTDB開(kāi)發(fā)系統(tǒng)之Go原生接口方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09golang中import cycle not allowed解決的一種思路
這篇文章主要給大家介紹了關(guān)于golang中import cycle not allowed解決的一種思路,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08使用Go語(yǔ)言實(shí)現(xiàn)遠(yuǎn)程傳輸文件
本文主要介紹如何利用Go語(yǔ)言實(shí)現(xiàn)遠(yuǎn)程傳輸文件的功能,有需要的小伙伴們可以參考學(xué)習(xí)。下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)。2016-08-08Go語(yǔ)言特點(diǎn)及基本數(shù)據(jù)類型使用詳解
這篇文章主要為大家介紹了Go語(yǔ)言特點(diǎn)及基本數(shù)據(jù)類型使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03Golang Mutex實(shí)現(xiàn)互斥的具體方法
Mutex是Golang常見(jiàn)的并發(fā)原語(yǔ),在開(kāi)發(fā)過(guò)程中經(jīng)常使用到,本文主要介紹了Golang Mutex實(shí)現(xiàn)互斥的具體方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-04-04