Redis原始碼研究 Redis的RESP協議

2021-09-12 23:56:22 字數 1871 閱讀 8802

redis客戶端和服務端互動使用的是redis作者制定的乙個協議,叫resp(redis serialization protocol)。

具體分如下幾個層次

客戶端發給服務端的命令都會序列化為array,而服務端返回給客戶端的可以為如上任意一種型別,各簡單舉例如下

具體介紹參考:

請求響應模式有兩種特殊情況

我們拿redis-cli客戶端試一下執行subscribe

127.0.0.1:6379> subscribe foo

reading messages... (press ctrl-c to quit)

1) "subscribe"

2) "foo"

3) (integer) 1

可以看到,redis-cli會阻塞,當另起乙個客戶端,publish訊息後,會收到該訊息並列印

~$redis-cli

127.0.0.1:6379> publish foo bar

(integer) 1

~$redis-cli

127.0.0.1:6379> subscribe foo

reading messages... (press ctrl-c to quit)

1) "subscribe"

2) "foo"

3) (integer) 1

1) "message"

2) "foo"

3) "bar"

直觀感覺是服務端阻塞了,沒有返回資料給客戶端。但看redis原始碼,實際服務端並沒有阻塞,並且可以在連線上繼續接收並處理命令

void subscribecommand(client *c)
當客戶端置了clinet_pubsub標記後,命令處理會做如下特殊邏輯

int processcommand(client *c) 

...}

如上文所示,當客戶端執行subscribe命令後,實際上是可以繼續訂閱或者取消訂閱渠道,並且可以執行ping命令。redis-cli客戶端實際上是自己阻塞了,如下**:

if (config.pubsub_mode) 

}

那麼,我們可以拿go寫乙個不阻塞的版本,並且可以測試redis的subscribe 模式。效果如下

>bogon:godis-cli $ go run godis-cli.go

> set k1 v1

ok> get k1

v1> subscribe foo

subscribe foo 1

[sub]>subscribe foo1//sub模式下可以繼續訂閱其他渠道

subscribe foo1 2

[sub]> unsubscribe foo1//取消訂閱

unsubscribe foo1 1

[sub]> ping//sub模式也可以執行ping

pong

[sub]> get k1 //sub模式下不能執行get命令

redis error: only (p)subscribe / (p)unsubscribe / ping / quit allowed in this context

[sub]> exit

exit sub pattern....

>get k1//退出sub模式後可以繼續正常執行get命令

v1> exit

由於godis-cli直接實現了resp協議,雖然只是為了觀察subscribe pattern的效果,但實際上可以支援所有redis命令的執行

具體**位址見:

Redis原始碼研究 雜湊表

前面提到 redis是個key value儲存系統,學過資料結構的人都知道,key value最簡單的資料結果就是雜湊表 當然,還有其他方式,如b 樹,二叉平衡樹等 hash表的效能取決於兩個因素 hash表的大小和解決衝突的方法。這兩個是矛盾的 hash表大,則衝突少,但是用記憶體過大 而hash...

redis原始碼 (九)Redis

前些天主要看了redis底層依賴的一些資料結構和事件管理庫的 比較零散,但大體上了解了作者的設計思路.對不同規模 n 的資料採用不同的資料結構以實現對記憶體利用的 最優 這裡的最優我想作者也沒有做過嚴格的實驗,不同的應用場景在redis上的表現肯定有所不同,如果有必要,可以再配置檔案中對一些閾值做調...

Redis 原始碼學習之 Redis 事務Nosql

redis事務提供了一種將多個命令請求打包,然後一次性 按照順序地執行多個命令的機制,並且在事務執行的期間,伺服器不會中斷事務而去執行其他不在事務中的命令請求,它會把事務中所有的命令都執行完畢才會去執行其他的命令。howredis中提供了multi discard exec watch unwatc...