go實現(xiàn)Redis讀寫分離示例詳解
我們?yōu)槭裁葱枰私釸ESP協(xié)議?
本篇文章目的為探究RESP協(xié)議,而非編寫讀寫中間件,這點要清楚。
關(guān)于這個問題,我想通過一個實例來解釋,我們編寫Redis中間件,為什么需要了解RESP協(xié)議。

以上代碼是編寫了一個非常簡單的TCP服務器,我們監(jiān)聽8888端口,嘗試使用redis-cli -p 8888連接服務器后,而后查看打印出來的應用層報文。
我們嘗試執(zhí)行下該代碼,并且輸入redis-cli -p 8888進行連接。

我們編寫的服務器獲取redis客戶端的報文為:
*1
$7
COMMAND
上面這個就是RESP協(xié)議的內(nèi)容了,所以說,我們要編寫一個Redis的中間件,我們需要先了解一下RESP協(xié)議才行。
什么是RESP協(xié)議
官網(wǎng)有相關(guān)的解釋: https://redis.io/docs/reference/protocol-spec/
RESP協(xié)議創(chuàng)建之初是專門為了Redis服務器和客戶端的通信而設計的,該協(xié)議在Redis 1.2中引入,并且在Redis 2.0中,成為Redis通信的標準協(xié)議。該協(xié)議有如下優(yōu)點:
- 實現(xiàn)簡單
- 快速解析
- 直接可閱讀
RESP根據(jù)其協(xié)議前綴,可以序列化不同的數(shù)據(jù)類型,例如: 整數(shù)、字符串、數(shù)組 等,還能標注 正常輸出 和 錯誤輸出等。除了流水線和發(fā)布訂閱以外,RESP協(xié)議應該是最簡單的請求-響應協(xié)議了。關(guān)于更多介紹,大佬們可以看看上面注釋的官方文檔。
RESP協(xié)議規(guī)范
RESP協(xié)議不同的部分使用\r\n(換行符)來進行分割,其支持5種數(shù)據(jù)類型,分別為: 簡單字符串、錯誤、整數(shù)、復雜字符串 和 數(shù)組組成,我們列個表格來講下。
| 類型 | 前綴 | 備注 |
|---|---|---|
| 簡單字符串 | + | 簡單字符串以+開頭 |
| 錯誤數(shù)據(jù) | - | 錯誤數(shù)據(jù)以-開頭 |
| 整數(shù) | : | 整數(shù)以:開頭 |
| 復雜字符串 | $ | 復雜字符串以$開頭 |
| 數(shù)組 | * | 數(shù)組以*開頭 |
我當初看到這個的時候,也是迷迷糊糊的,到底什么意思呢? 哎,我們舉個例子你就明白了。
若我們想執(zhí)行
set juejinName pdudo
若使用RESP 協(xié)議應當如何編寫呢?應當編寫如下:
*3 $3 set $10 juejinName $5 pdudo
那我們來解釋一下*3代表有3個數(shù)組,而$3代表復雜字符串有長度為3,值為set, $10代表復雜字符串長度為10,值為juejinName, $5代表復雜字符串長度為5,值為pdudo。
我們結(jié)合上述信息,可以畫一張圖。

這就是協(xié)議的內(nèi)容了。
而協(xié)議前綴+、-、:則要簡單的多,直接跟數(shù)據(jù)即可,
例如:
+
+OK
-
-ERR syntax error
:
:3
如何使用該協(xié)議請求Redis
我們已經(jīng)學習了相關(guān)的RESP協(xié)議,那么我們?nèi)绾螌W習呢? 我們可以使用telnet命令來操作即可。
在此,我們準備幾條命令,我們會將其轉(zhuǎn)換為RESP格式,且將其發(fā)送到redis服務器。
命令
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é)議實現(xiàn)簡單,直接可閱讀,是不是理解的更加深刻了呢?
使用go編寫Redis中間件實現(xiàn)讀寫分離
本篇暫不解釋代碼,而后單獨開一篇談論中間件代碼。
實現(xiàn)該功能,其實本質(zhì)上是區(qū)分命令是查詢還是寫入,若是查詢,則直接轉(zhuǎn)發(fā)到從庫,而寫入,則轉(zhuǎn)發(fā)到主庫即可,其架構(gòu)圖可以理解為如下:

我們已經(jīng)有了目前的架構(gòu)。
| 主機 | 端口 | 密碼 | 角色 |
|---|---|---|---|
| 127.0.0.1 | 6379 | 無 | 主庫 |
| 127.0.0.1 | 7380 | 無 | 從庫 |
相關(guān)代碼已經(jīng)放到了 gitee.com/pdudo/golea…
我們來看看實際效果呢:

總結(jié)
其實本篇文章核心的點是探究RESP協(xié)議,而我們使用go編寫了一個軟件,用于解析RESP協(xié)議,從而獲取執(zhí)行的命令,再根據(jù)命令屬性,從而轉(zhuǎn)發(fā)從庫或者主庫,以此來達到讀寫分離的效果。再次提及一下核心點是拆解RESP協(xié)議。
怎么樣,好玩吧,動動你的小手指,快來試試吧。
以上就是go實現(xiàn)Redis讀寫分離示例詳解的詳細內(nèi)容,更多關(guān)于go Redis讀寫分離的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解prometheus監(jiān)控golang服務實踐記錄
這篇文章主要介紹了詳解prometheus監(jiān)控golang服務實踐記錄,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
Apache?IoTDB開發(fā)系統(tǒng)之Go原生接口方法
這篇文章主要為大家介紹了?Apache?IoTDB開發(fā)系統(tǒng)之Go原生接口方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
golang中import cycle not allowed解決的一種思路
這篇文章主要給大家介紹了關(guān)于golang中import cycle not allowed解決的一種思路,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧2018-08-08

