Redis竟然還有自定義網(wǎng)絡(luò)通信協(xié)議?
凡是網(wǎng)絡(luò)通信,皆需要雙方遵守一致的協(xié)議才能互聯(lián)。Redis協(xié)議在如下幾點(diǎn)之間做出了折衷:
- 實(shí)現(xiàn)簡(jiǎn)單
- 被計(jì)算機(jī)快速解析
- 有一定的可讀性
網(wǎng)絡(luò)層
Redis在TCP端口6379上監(jiān)聽到來的連接,客戶端連接到來時(shí),Redis服務(wù)器為此創(chuàng)建一個(gè)TCP連接。在客戶端與服務(wù)器端之間傳輸?shù)拿總€(gè)Redis命令或者數(shù)據(jù)都以\r\n結(jié)尾。
請(qǐng)求
Redis接收由不同參數(shù)組成的命令。一旦收到命令,將會(huì)立刻被處理,并響應(yīng)給客戶端。
新的統(tǒng)一請(qǐng)求協(xié)議
新的統(tǒng)一協(xié)議在Redis 1.2中引入,在Redis 2.0中,成為與Redis服務(wù)器通訊的標(biāo)準(zhǔn)方式。
在這個(gè)統(tǒng)一協(xié)議里,發(fā)送給Redis服務(wù)端的所有參數(shù)都是二進(jìn)制安全的。
如下是通用形式:
- *<number of arguments> CR LF
- $<number of bytes of argument 1> CR LF
- <argument data> CR LF
- ...
- $<number of bytes of argument N> CR LF
- <argument data> CR LF
示例:
- ➜ ~ nc localhost 6379
- keys *
- *2
- $18
- user:sign:5:202101
- $18
- seckill_vouchers:6
上面的命令看上去像是單引號(hào)字符串,所以可在查詢中看到每個(gè)字節(jié)的準(zhǔn)確值:
- "*2\r\n$18\r\nuser:sign:5:202101\r\n$18\r\nseckill_vouchers:6\r\n"
在Redis的響應(yīng)中也使用這樣的格式。批量回復(fù)時(shí),這種格式用于每個(gè)參數(shù)。實(shí)際的統(tǒng)一請(qǐng)求協(xié)議是Redis用于返回列表項(xiàng),并調(diào)用 Multi-bulk回復(fù)。僅僅是N個(gè)以以*\r\n為前綴的不同批量回復(fù),是緊隨的參數(shù)(批量回復(fù))數(shù)目。
響應(yīng)
Redis用不同的響應(yīng)類型回復(fù)命令。它可能從服務(wù)器發(fā)送的第一個(gè)字節(jié)開始校驗(yàn)回復(fù)類型:
單行響應(yīng)
響應(yīng)的第一個(gè)字節(jié)將是+
- set java edge
- +OK
錯(cuò)誤消息
響應(yīng)的第一個(gè)字節(jié)是-
- keys*
- -ERR unknown command `keys*`, with args beginning with:
整型數(shù)字
響應(yīng)的第一個(gè)字節(jié)將是:
批量響應(yīng)
第一個(gè)字節(jié)將是$
- keys *
- *2
- $18
- user:sign:5:202101
- $18
- seckill_vouchers:6
多個(gè)批量響應(yīng)
- 響應(yīng)的第一個(gè)字節(jié)將是*