成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

跟著大彬讀源碼 - Redis 2 - 服務(wù)器如何響應(yīng)客戶端請(qǐng)求?(上)

Anonymous1 / 1509人閱讀

摘要:現(xiàn)在客戶端和服務(wù)器都準(zhǔn)備好了,那么客戶端和服務(wù)器如何建立連接服務(wù)器又是如何響應(yīng)客戶端的請(qǐng)求呢連接服務(wù)器客戶端和服務(wù)器進(jìn)行通訊,首先應(yīng)該就是建立連接。以上是客戶端發(fā)送命令給服務(wù)器的過程,在下一節(jié)中,我們?cè)賮碚J(rèn)識(shí)服務(wù)器是如何響應(yīng)客戶端請(qǐng)的。

上次我們通過問題“啟動(dòng)服務(wù)器,程序都干了什么?”,跟著源碼,深入了解了 Redis 服務(wù)器的啟動(dòng)過程。

既然啟動(dòng)了 Redis 服務(wù)器,那我們就要連上 Redis 服務(wù)干些事情。這里我們可以通過 redis-cli 測(cè)試。

現(xiàn)在客戶端和服務(wù)器都準(zhǔn)備好了,那么Redis 客戶端和服務(wù)器如何建立連接?服務(wù)器又是如何響應(yīng)客戶端的請(qǐng)求呢?

1 連接服務(wù)器

客戶端和服務(wù)器進(jìn)行通訊,首先應(yīng)該就是建立連接。接下來,我們來看下 redis-cli 與服務(wù)器的連接過程。

還記得我們上次使用 gdb 調(diào)試程序的步驟嗎?讓我們對(duì) redis-cli 再來一次,看看源碼的執(zhí)行步驟。在開始之前,記得在編輯器打開 redis-cli.c,定位到 main 函數(shù)的位置,畢竟 gdb 看代碼沒有編輯器看著舒服。

debug 步驟如下:

# bash
cd /opt/redis-3.2.13
// 啟動(dòng) Redis 服務(wù)。Ctrl+c 可推出服務(wù)器啟動(dòng)頁,同時(shí)保持服務(wù)器運(yùn)行
./src/redis-server --port 8379 &
// 調(diào)試 redis-clli
gdb ./src/redis-cli
# gdb 
(gdb) b main
(gdb) r -p 8379
(gdb) layout src
(gdb) focus cmd

執(zhí)行完上述步驟,我們會(huì)進(jìn)入如下界面:

這時(shí)候我們就可以回到編輯器頁,看看對(duì) main 函數(shù)中哪一行比較感興趣,就停下來研究研究。到了 2618 行,我們會(huì)看到有執(zhí)行 parseOptions 這個(gè)函數(shù),看名字,好像是初始化一些可選項(xiàng)。那就進(jìn)去看看唄。

1.1 初始化客戶端配置

函數(shù)執(zhí)行步驟:main -> parseOptions -> main。

我們會(huì)看到,在執(zhí)行 redis-cli 時(shí)攜帶的參數(shù)都是在這個(gè)函數(shù)中解析,比如我們啟動(dòng)的時(shí)候帶著的 -p 參數(shù),會(huì)在 996 行被解析到,同時(shí)賦值給客戶端的 hostport 配置項(xiàng)。如下圖:

1.2 客戶端啟動(dòng)模式

函數(shù)執(zhí)行步驟:main。

回到 main 函數(shù),會(huì)看到后面的代碼會(huì)出現(xiàn)很多 cliConnect 函數(shù)。要注意的是,這里并不表示 redis-cli 會(huì)執(zhí)行多次 cliConnect 函數(shù)。實(shí)際上,每一個(gè) if 語句塊,都代表著客戶端的一種連接模式,3.2.13 版本支持以下模式:

Latency mode:延遲模式。redis-cli --latency -p 8379 用來測(cè)試客戶端與服務(wù)器連接的延遲。還有 --history--dist 可選項(xiàng),用來展示不同的形式。

Slave mode:模擬從節(jié)點(diǎn)模式。

Get RDB mode:生成并發(fā)送 RDB 持久化文件,保存在本地。

Pipe mode:管道模式。將命令封裝成指定數(shù)據(jù)格式,批量發(fā)送給 redis 服務(wù)器執(zhí)行。

Find big keys:統(tǒng)計(jì) bigkey 的分布。

Stat mode:統(tǒng)計(jì)模式。實(shí)時(shí)展示服務(wù)器的統(tǒng)計(jì)信息。

Scan mode:掃描指定模式的鍵,相當(dāng)于 scan 模式。

LRU test mode:實(shí)時(shí)測(cè)試 LRU 算法的命中情況。

1.3 連接服務(wù)器

函數(shù)執(zhí)行步驟:main -> cliConnect -> redisConnect -> redisContextInit -> redisContextConnectTcp -> _redisContextConnectTcp -> cliConnect。

我們上面沒有使用特殊模式啟動(dòng),因此,我們會(huì)看到在 2687 行真正的去調(diào)用 cliConnect 函數(shù)。跟蹤進(jìn)去,讓我們看看究竟是如何和服務(wù)器進(jìn)行連接的。

cliConnect 函數(shù)中,我們看到,根據(jù) hostsocket 的配置項(xiàng),會(huì)使用不同的連接模式。從名字上,我們大概可以猜出,一個(gè)是 TCP Socket 連接,另一個(gè)是本機(jī) Unix Socket 連接。

如果想要使用 Unix Socket 連接,只需按格式配置 hostscoket 即可:./src/redis-cli -s /tmp/redis.sock。

我們這里使用 TCP Scoket 連接,使用 redisConnect 函數(shù)建立連接。

不斷追蹤,我們會(huì)看到上面所示的函數(shù)執(zhí)行步驟,在 _redisContextConnectTcp 函數(shù)中會(huì)看到 getaddrinfoconnect 函數(shù)的調(diào)用,這里就是建立 TCP 連接的地方。

1.4 校驗(yàn)權(quán)限及選擇數(shù)據(jù)庫

函數(shù)執(zhí)行步驟:cliConnect -> anetKeepAlive -> cliAuth -> cliSelect -> main。

回到 cliConnect 函數(shù),如果正常連接上服務(wù)器后,還會(huì)將我們上面創(chuàng)建的 TCP 連接設(shè)置為長(zhǎng)連接,然后校驗(yàn)權(quán)限,選擇連接數(shù)據(jù)庫。

...
/* Set aggressive KEEP_ALIVE socket option in the Redis context socket
 * in order to prevent timeouts caused by the execution of long
 * commands. At the same time this improves the detection of real
 * errors. */
anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);
/* Do AUTH and select the right DB. */
if (cliAuth() != REDIS_OK)
    return REDIS_ERR;
if (cliSelect() != REDIS_OK)
    return REDIS_ERR;
...

至此,我們已經(jīng)跑完客戶端與服務(wù)器建立連接的全過程。感興趣的小伙伴可以嘗試連接不存在的 IP 或 端口,觀察程序拋出異常的時(shí)機(jī),熟悉整個(gè)連接過程。

客戶端與 服務(wù)器建立連接后,就可以使用相關(guān)命令操作數(shù)據(jù)庫中的 key 了。下面我們以 SET KEY VALUE 命令為例,來看看命令的執(zhí)行過程。

2 發(fā)送命令請(qǐng)求

當(dāng)用戶在客戶端鍵入一個(gè)命令請(qǐng)求時(shí),客戶端會(huì)將這個(gè)命令請(qǐng)求按協(xié)議格式轉(zhuǎn)換,然后通過連接到服務(wù)器的套接字,將轉(zhuǎn)換后的命令請(qǐng)求發(fā)送給服務(wù)器,如圖 3 所示:

因此,對(duì)于我們上面的命令請(qǐng)求,客戶端會(huì)轉(zhuǎn)成:

"*3
$3
SET
$3
KEY
$5
VALUE
"

然后發(fā)給服務(wù)器。

以上是客戶端發(fā)送命令給服務(wù)器的過程,在下一節(jié)中,我們?cè)賮碚J(rèn)識(shí)服務(wù)器是如何響應(yīng)客戶端請(qǐng)的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/62118.html

相關(guān)文章

  • 跟著彬讀源碼 - Redis 3 - 務(wù)器如何響應(yīng)戶端請(qǐng)求?(下)

    摘要:讀取命令請(qǐng)求當(dāng)客戶端與服務(wù)器之間的套接字因客戶端的寫入變得可讀時(shí),服務(wù)器將調(diào)用命令請(qǐng)求處理器執(zhí)行以下操作讀取套接字中的命令請(qǐng)求,并將其保存到客戶端狀態(tài)的輸入緩沖區(qū)。 繼續(xù)我們上一節(jié)的討論。服務(wù)器啟動(dòng)了,客戶端也發(fā)送命令了。接下來,就要到服務(wù)器表演的時(shí)刻了。 1 服務(wù)器處理 服務(wù)器讀取到命令請(qǐng)求后,會(huì)進(jìn)行一系列的處理。 1.1 讀取命令請(qǐng)求 當(dāng)客戶端與服務(wù)器之間的套接字因客戶端的寫入變得...

    roadtogeek 評(píng)論0 收藏0
  • 跟著彬讀源碼 - Redis 1 - 啟動(dòng)服務(wù),程序都干了什么?

    摘要:此時(shí)服務(wù)器處于休眠狀態(tài),并使用進(jìn)行事件輪詢,等待監(jiān)聽事件的發(fā)生。繼續(xù)執(zhí)行被調(diào)試程序,直至下一個(gè)斷點(diǎn)或程序結(jié)束縮寫。服務(wù)啟動(dòng)包括初始化基礎(chǔ)配置數(shù)據(jù)結(jié)構(gòu)對(duì)外提供服務(wù)的準(zhǔn)備工作還原數(shù)據(jù)庫執(zhí)行事件循環(huán)等。 一直很羨慕那些能讀 Redis 源碼的童鞋,也一直想自己解讀一遍,但迫于 C 大魔王的壓力,解讀日期遙遙無期。 相信很多小伙伴應(yīng)該也都對(duì)或曾對(duì)源碼感興趣,但一來覺得自己不會(huì) C 語言,二來也...

    sewerganger 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<