最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

redis?protocol通信協(xié)議及使用詳解

 更新時(shí)間:2022年07月15日 10:34:03   作者:程序那些事  
這篇文章主要為大家介紹了redis?protocol通信協(xié)議及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

簡(jiǎn)介

redis是一個(gè)非常優(yōu)秀的軟件,它可以用作內(nèi)存數(shù)據(jù)庫(kù)或者緩存。因?yàn)樗膬?yōu)秀性能,redis被應(yīng)用在很多場(chǎng)合中。

redis是一個(gè)客戶端和服務(wù)器端的模式,客戶端和服務(wù)器端是通過(guò)TCP協(xié)議進(jìn)行連接的,客戶端將請(qǐng)求數(shù)據(jù)發(fā)送到服務(wù)器端,服務(wù)器端將請(qǐng)求返回給客戶端。這樣一個(gè)請(qǐng)求流程就完成了。

當(dāng)然在最開(kāi)始的時(shí)候,因?yàn)橛玫娜撕苌?,系統(tǒng)還不夠穩(wěn)定,通過(guò)TCP協(xié)議傳輸?shù)臄?shù)據(jù)不規(guī)范的。但是當(dāng)用的人越來(lái)越多,尤其是希望開(kāi)發(fā)適用于不同語(yǔ)言和平臺(tái)的redis客戶端的時(shí)候,就要考慮到兼容性的問(wèn)題了。

這時(shí)候客戶端和服務(wù)器端就需要一個(gè)統(tǒng)一的交互協(xié)議,對(duì)于redis來(lái)說(shuō)這個(gè)通用的交互協(xié)議就叫做Redis serialization protocol(RESP)。

RESP是在Redis 1.2版本中引入的,并在Redis 2.0中成為了與 Redis 服務(wù)器通信的標(biāo)準(zhǔn)方式。

這就是說(shuō),從Redis 2.0之后,就可以基于redis protocol協(xié)議開(kāi)發(fā)出自己的redis客戶端了。

redis的高級(jí)用法

一般來(lái)說(shuō),redis的客戶端和服務(wù)器端組成的是一個(gè)請(qǐng)求-響應(yīng)的模式,也就是說(shuō)客戶端向服務(wù)器端發(fā)送請(qǐng)求,然后得到服務(wù)器端的響應(yīng)結(jié)果。

請(qǐng)求和響應(yīng)是redis中最簡(jiǎn)單的用法。熟悉redis的朋友可能會(huì)想到了兩個(gè)redis的高級(jí)用法,這兩個(gè)用法并不是傳統(tǒng)意義上的請(qǐng)求-響應(yīng)模式。

到底是哪兩種用法呢?

第一種就是redis支持pipline,也就是管道操作,管道的好處就是redis客戶端可以一次性向服務(wù)器端發(fā)送多條命令,然后等待服務(wù)器端的返回。

第二種redis還支持Pub/Sub,也就是廣播模型,在這一種情況下,就不是請(qǐng)求和響應(yīng)的模式了,在Pub/Sub下,切換成了服務(wù)器端推送的模式。

Redis中的pipline

為什么要用pipline呢?

因?yàn)閞edis是一個(gè)典型的請(qǐng)求響應(yīng)模式,我們來(lái)舉個(gè)常見(jiàn)的incr命令的例子:

Client: INCR X Server: 1 Client: INCR X Server: 2 Client: INCR X Server: 3 Client: INCR X Server: 4

事實(shí)上客戶端只想得到最終的結(jié)果,但是每次客戶端都需要等待服務(wù)器端返回結(jié)果之后,才能發(fā)送下一次的命令。這樣就會(huì)導(dǎo)致一個(gè)叫做RTT(Round Trip Time)的時(shí)間浪費(fèi)。

雖然每次RTT的時(shí)間不長(zhǎng),但是累計(jì)起來(lái)也是一個(gè)非??陀^的數(shù)字。

那么可不可以將所有的客戶端命令放在一起發(fā)送給服務(wù)器呢? 這個(gè)優(yōu)化就叫做Pipeline。

piepline的意思就是客戶端可以在沒(méi)有收到服務(wù)器端返回的時(shí)候繼續(xù)向服務(wù)器端發(fā)送命令。

上面的命令可以用pipline進(jìn)行如下改寫(xiě):

(printf "INCR X\r\nINCR X\r\nINCR X\r\nINCR X\r\n"; sleep 1) | nc localhost 6379
:1
:2
:3
:4

因?yàn)閞edis服務(wù)器支持TCP協(xié)議進(jìn)行連接,所以我們可以直接用nc連到redis服務(wù)器中執(zhí)行命令。

在使用pipline的時(shí)候有一點(diǎn)要注意,因?yàn)閞edis服務(wù)器會(huì)將請(qǐng)求的結(jié)果緩存在服務(wù)器端,等到pipline中的所有命令都執(zhí)行完畢之后再統(tǒng)一返回,所以如果服務(wù)器端返回的數(shù)據(jù)比較多的情況下,需要考慮內(nèi)存占用的問(wèn)題。

那么pipline僅僅是為了減少RTT嗎?

熟悉操作系統(tǒng)的朋友可能有聽(tīng)說(shuō)過(guò)用戶空間和操作系統(tǒng)空間的概念,從用戶輸入讀取數(shù)據(jù)然后再寫(xiě)入到系統(tǒng)空間中,這里涉及到了一個(gè)用戶空間的切換,在IO操作中,這種空間切換或者拷貝是比較耗時(shí)的,如果頻繁的進(jìn)行請(qǐng)求和響應(yīng),就會(huì)造成這種頻繁的空間切換,從而降低了系統(tǒng)的效率。

使用pipline可以一次性發(fā)送多條指令,從而有效避免空間的切換行為。

Redis中的Pub/Sub

和Pub/Sub相關(guān)的命令是SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH。

為什么要用Pub/Sub呢?其主要的目的就是解耦,在Pub/Sub中消息發(fā)送方不需要知道具體的接收方的地址,同樣的對(duì)于消息接收方來(lái)說(shuō),也不需要知道具體的消息發(fā)送方的地址。他們只需要知道關(guān)聯(lián)的主題即可。

subscribe和publish的命令比較簡(jiǎn)單,我們舉一個(gè)例子,首先是客戶端subscribe topic:

redis-cli -h 127.0.0.1
127.0.0.1:6379> subscribe topic
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "topic"
3) (integer) 1

然后在另外一個(gè)終端,調(diào)用publish命令:

redis-cli -h 127.0.0.1
127.0.0.1:6379> publish topic "what is your name?"
(integer) 1

可以看到客戶端會(huì)收到下面的消息:

1) "message"
2) "topic"
3) "what is your name?"

RESP protocol

RESP協(xié)議有5種類(lèi)型,分別是imple Strings, Errors, Integers, Bulk Strings 和 Arrays。

不同的類(lèi)型以消息中的第一個(gè)byte進(jìn)行區(qū)分,如下所示:

類(lèi)型第一個(gè)byte
Simple Strings+
Errors-
Integers:
Bulk Strings$
Arrays*

protocol中不同的部分以 "\r\n" (CRLF)來(lái)進(jìn)行區(qū)別。

Simple Strings

Simple Strings的意思是簡(jiǎn)單的字符串。

通常用在服務(wù)器端的返回中,這種消息的格式就是"+"加上文本消息,最后以"\r\n"結(jié)尾。

比如服務(wù)器端返回OK,那么對(duì)應(yīng)的消息就是:

"+OK\r\n"

上面的消息是一個(gè)非二進(jìn)制安全的消息,如果想要發(fā)送二進(jìn)制安全的消息,則可以使用Bulk Strings。

什么是非二進(jìn)制安全的消息呢?對(duì)于Simple Strings來(lái)說(shuō),因?yàn)橄⑹且?quot;\r\n"結(jié)尾,所以消息中間不能包含"\r\n"這兩個(gè)特殊字符,否則就會(huì)產(chǎn)生錯(cuò)誤的含義。

Bulk Strings

Bulk Strings是二進(jìn)制安全的。這是因?yàn)锽ulk Strings包含了一個(gè)字符長(zhǎng)度字段,因?yàn)槭歉鶕?jù)長(zhǎng)度來(lái)判斷字符長(zhǎng)度的,所以并不存在根據(jù)字符中某個(gè)特定字符來(lái)判斷是否字符結(jié)束的缺點(diǎn)。

具體而言Bulk Strings的結(jié)構(gòu)是"$"+字符串長(zhǎng)度+"\r\n"+字符串+"\r\n"。

以O(shè)K為例,如果以Bulk Strings來(lái)表示,則如下所示:

"$2\r\nok\r\n"

Bulk Strings還可以包含空字符串:

"$0\r\n\r\n"

當(dāng)然還可以表示不存在的Null值:

"$-1\r\n"

RESP Integers

這是redis中的整數(shù)表示,具體的格式是":"+整數(shù)+"\r\n"。

比如18這個(gè)整數(shù)就可以用下面的格式來(lái)表示:

":18\r\n"

RESP Arrays

redis的多個(gè)命令可以以array來(lái)表示,服務(wù)器端返回的多個(gè)值也可以用arrays來(lái)表示。

RESP Arrays的格式是"*"+數(shù)組中的元素個(gè)數(shù)+其他類(lèi)似的數(shù)據(jù)。

所以RESP Arrays是一個(gè)復(fù)合結(jié)構(gòu)的數(shù)據(jù)。比如一個(gè)數(shù)組中包含了兩個(gè)Bulk Strings:"redis","server"則可以用下面的格式來(lái)表示:

"*2\r\n$5\r\nredis\r\n$6\r\nserver\r\n"

RESP Arrays中的原始不僅可以使用不同類(lèi)型,還能包含RESP Arrays,也就是array的嵌套:

"*3\r\n$5\r\nredis\r\n$6\r\nserver\r\n*1\r\n$4\r\ngood\r\n"

為了方便觀察,我們將上面的消息格式一下:

"*3\r\n
$5\r\nredis\r\n
$6\r\nserver\r\n
*1\r\n
$4\r\ngood\r\n"

上面的消息是一個(gè)包含三個(gè)元素的數(shù)組,前面兩個(gè)元素是Bulk Strings,最后一個(gè)是包含一個(gè)元素的數(shù)組。

RESP Errors

最后,RESP還可以表示錯(cuò)誤消息。RESP Errors的消息格式是"-"+字符串,如下所示:

"-Err something wrong\r\n"

一般情況下,"-"后面的第一個(gè)單詞表示的是錯(cuò)誤類(lèi)型,但是這只是一個(gè)約定俗成的規(guī)定,并不是RESP協(xié)議中的強(qiáng)制要求。

另外,經(jīng)過(guò)對(duì)比,大家可能會(huì)發(fā)現(xiàn)RESP Errors和Simple Strings是消息格式是差不多的。

這種對(duì)不同消息類(lèi)型的處理是在客戶端進(jìn)行區(qū)分的。

Inline commands

如果完全按RESP協(xié)議的要求,當(dāng)我們連接到服務(wù)器端的時(shí)候需要包含RESP中定義消息的所有格式,但是這些消息中包含了額外的消息類(lèi)型和回車(chē)換行符,所以直接使用協(xié)議來(lái)執(zhí)行的話會(huì)比較困惑。

于是redis還提供一些內(nèi)聯(lián)的命令,也就是協(xié)議命令的精簡(jiǎn)版本,這個(gè)精簡(jiǎn)版本去除了消息類(lèi)型和回車(chē)換行符。

我們以"get world"這個(gè)命令為例。來(lái)看下不同方式的連接情況。

首先是使用redis-cli進(jìn)行連接:

redis-cli -h 127.0.0.1
127.0.0.1:6379> get world
"hello"

因?yàn)閞edis-cli是redis的客戶端,所以可以直接使用inline command來(lái)執(zhí)行命令。

如果使用telnet,我們也可以使用同樣的命令來(lái)獲得結(jié)果:

telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get world
$5
hello

可以看到返回的結(jié)果是"$5\r\nhello\r\n"。

如果要使用協(xié)議消息來(lái)請(qǐng)求redis服務(wù)器應(yīng)該怎么做呢?

我們要請(qǐng)求的命令是"get world",將其轉(zhuǎn)換成為RESP的消息則是:

"*2\r\n$3\r\nget\r\n$5\r\nworld\r\n"

我們嘗試一下將上述命令使用nc傳遞到redis server上:

(printf "*2\r\n$3\r\nget\r\n$5\r\nworld\r\n"; sleep 1) |  nc localhost 6379
-ERR Protocol error: expected '$', got ' '

很遺憾我們得到了ERR,那么是不是不能直接使用RESP消息格式進(jìn)行傳輸呢?當(dāng)然不是,上面的問(wèn)題在于$符號(hào)是一個(gè)特殊字符,我們需要轉(zhuǎn)義一下:

(printf "*2\r\n\$3\r\nget\r\n\$5\r\nworld\r\n"; sleep 1) |  nc localhost 6379
$5
hello

可以看到輸出的結(jié)果和直接使用redis-cli一致。

總結(jié)

以上就是RESP協(xié)議的基本內(nèi)容和手動(dòng)使用的例子,有了RESP,我們就可以根據(jù)協(xié)議中定義的格式來(lái)創(chuàng)建redis客戶端。

可能大家又會(huì)問(wèn)了,為什么只是redis客戶端呢?有了協(xié)議是不是redis服務(wù)器端也可以創(chuàng)建呢?答案當(dāng)然是肯定的,只需要按照協(xié)議進(jìn)行消息傳輸即可。主要的問(wèn)題在于redis服務(wù)器端的實(shí)現(xiàn)比較復(fù)雜,不是那么容易實(shí)現(xiàn)的。

以上就是redis protocol通信協(xié)議及使用詳解的詳細(xì)內(nèi)容,更多關(guān)于redis protocol通信協(xié)議的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • redis中使用redis-dump導(dǎo)出、導(dǎo)入、還原數(shù)據(jù)實(shí)例

    redis中使用redis-dump導(dǎo)出、導(dǎo)入、還原數(shù)據(jù)實(shí)例

    這篇文章主要介紹了redis中使用redis-dump導(dǎo)出、導(dǎo)入、還原數(shù)據(jù)實(shí)例,本文直接給出操作命令,并給出注釋加以說(shuō)明,需要的朋友可以參考下
    2014-11-11
  • redis3.2配置文件redis.conf詳細(xì)說(shuō)明

    redis3.2配置文件redis.conf詳細(xì)說(shuō)明

    redis3.2配置詳解,Redis啟動(dòng)的時(shí)候,可以指定配置文件,詳細(xì)說(shuō)明請(qǐng)看本文說(shuō)明
    2018-03-03
  • 淺談Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案

    淺談Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案

    項(xiàng)目中有遇到這個(gè)問(wèn)題,跟MySQL中的數(shù)據(jù)不一致,記錄一下,本文主要介紹了Redis跟MySQL的雙寫(xiě)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Redis?定長(zhǎng)隊(duì)列探索及實(shí)踐

    Redis?定長(zhǎng)隊(duì)列探索及實(shí)踐

    這篇文章主要介紹了Redis?定長(zhǎng)隊(duì)列探索及實(shí)踐,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • 如何使用redis中的zset實(shí)現(xiàn)滑動(dòng)窗口限流

    如何使用redis中的zset實(shí)現(xiàn)滑動(dòng)窗口限流

    滑動(dòng)窗口限流是一種常見(jiàn)的流量控制方法,它限制了在一定時(shí)間窗口內(nèi)的請(qǐng)求數(shù)量,下面是使用Redis ZSet實(shí)現(xiàn)滑動(dòng)窗口限流的一個(gè)簡(jiǎn)單示例,需要的朋友可以參考下
    2023-09-09
  • redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&的問(wèn)題及解決

    redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&的問(wèn)題及解決

    這篇文章主要介紹了redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Redis事務(wù)處理的使用操作方法

    Redis事務(wù)處理的使用操作方法

    Redis保證一個(gè)事務(wù)中的所有命令要么都執(zhí)行,要么都不執(zhí)行(原子性),如果客戶端發(fā)送了EXEC命令,所有的命令就都會(huì)被執(zhí)行,即使此后客戶端斷線也沒(méi)關(guān)系,因?yàn)镽edis中已經(jīng)記錄了所有要執(zhí)行的命令,下面通過(guò)本文給大家介紹Redis事務(wù)處理的使用操作,感興趣的朋友一起看看吧
    2021-10-10
  • 你了解Redis事務(wù)嗎

    你了解Redis事務(wù)嗎

    說(shuō)到事務(wù),大家會(huì)立刻想到Mysql的事務(wù),所謂的事務(wù)就是對(duì)數(shù)據(jù)進(jìn)行一系列的操作,要么都執(zhí)行成功,要么都執(zhí)行失敗,下面就介紹一下Redis如何實(shí)現(xiàn)事務(wù),感興趣的可以了解一下
    2022-08-08
  • window下創(chuàng)建redis出現(xiàn)問(wèn)題小結(jié)

    window下創(chuàng)建redis出現(xiàn)問(wèn)題小結(jié)

    這篇文章主要介紹了window下創(chuàng)建redis出現(xiàn)問(wèn)題總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 詳解Redis SCAN命令實(shí)現(xiàn)有限保證的原理

    詳解Redis SCAN命令實(shí)現(xiàn)有限保證的原理

    這篇文章主要介紹了Redis SCAN命令實(shí)現(xiàn)有限保證的原理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-07-07

最新評(píng)論

出国| 蒙山县| 虹口区| 泰兴市| 万山特区| 云霄县| 曲麻莱县| 许昌市| 伊宁市| 商水县| 陆丰市| 大足县| 宜州市| 博客| 商水县| 论坛| 岐山县| 新建县| 泰州市| 柞水县| 沅陵县| 彭山县| 恩施市| 大化| 昌平区| 岳池县| 肥乡县| 大竹县| 沽源县| 宣威市| 华宁县| 浦城县| 文昌市| 三江| 松滋市| 吴旗县| 安平县| 故城县| 沁源县| 博乐市| 吴旗县|