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...