Redis學習筆記(十) 客戶端

来源:https://www.cnblogs.com/xtt321/archive/2020/05/18/12913529.html
-Advertisement-
Play Games

Redis伺服器是典型的一對多伺服器程式:一個伺服器可以與多個客戶端建立網路連接,每個客戶端可以向伺服器發送命令請求,而伺服器則接收並處理客戶端發送的命令請求,並向客戶端返回命令回覆。 通過使用由I/O多路復用技術實現的文件事件處理器,Redis伺服器使用單線程單進程的方式處理命令請求,並於多個客戶 ...


Redis伺服器是典型的一對多伺服器程式:一個伺服器可以與多個客戶端建立網路連接,每個客戶端可以向伺服器發送命令請求,而伺服器則接收並處理客戶端發送的命令請求,並向客戶端返回命令回覆。

通過使用由I/O多路復用技術實現的文件事件處理器,Redis伺服器使用單線程單進程的方式處理命令請求,並於多個客戶端進行網路通信。

每個與伺服器進行連接的客戶端,服務端都為這些客戶端建立相應的redisClient結構(客戶端狀態),保存客戶端當前的狀態信息,以及執行相關功能時需要用到的數據結構。

Redis伺服器狀態結構的clients屬性是一個鏈表,這個鏈表保存了所有與伺服器連接的客戶端的狀態結構,對客戶端執行批量操作,或者查找某個指定的客戶端,都可以通過遍歷clients鏈完成。

struct redisServer{
//一個鏈表,保存了所有客戶端狀態
list *clients;
}

1、客戶端狀態的fd屬性記錄了客戶端正在使用的套接字描述符

typedef struct redisClient{
int fd;
} redisClient;

根據客戶端的類型不同fd的屬性值可以是-1,或者是大於-1的整數:偽客戶端fd屬性為-1;普通客戶端的fd屬性值為大於-1的整數。

2、預設情況下一個連接到伺服器的客戶端是沒有名稱的, 可以使用Client setname 命令為客戶端設置一個名稱。

3、客戶端的標誌屬性flags記錄了客戶端角色(role),以及客戶端狀態

typedef struct redisClient{
int flag;
} redisClient;

在主從伺服器進行複製操作時,主伺服器會成為從伺服器的客戶端,而從伺服器也會成為主伺服器的客戶端。

 

REDIS_MASTER 客戶端是一個主伺服器

REDIS_BLOCKED 客戶端正在被列表命令阻塞

REDIS_MULTI | REDIS_DIRTY_CAS 客戶端正在執行事務,但事務的安全性已經被破壞

REDIS_SLAVE | REDOS_PRE_PSYNC 客戶端是一個從伺服器,並且版本低於REDIS2.8

REDIS_LUA_CLIENT | REDIS_FORCE_AOF | REDIS_FORCE_REPL 這是專門執行Lua腳本包含的redis命令的偽客戶端 ,它強制伺服器將當前執行的命令寫入到AOF文件,並複製給從伺服器。

4、客戶端狀態的輸入緩衝區用戶保存客戶端發送的命令請求:

typedef struct redisClient {
sds querybuf;
} redisClient;

5、在伺服器將客戶端發送的命令請求保存在客戶端狀態的querybuf屬性後,伺服器將對命令請求的內容進行分析,並將得出的命令參數以及命令參數的個數分別保存到客戶端狀態的argv屬性和argc屬性

typedef struct redisClient{
robj **argv;
int argc;
} redisClient;

argv屬性是一個數組,數組的每個項都是一個字元串隊形,其中avgv[0]是要執行的命令,其之後的其他項都是傳給命令的參數。

6、當伺服器從協議內容中分析並得出argv屬性和argc屬性的值之後,伺服器將根據項argv[0]的值,在命令表中查找命令所對應的實現函數。

命令表是一個字典表,字典的鍵是一個SDS結構,保存了命令的名字,字典值是命令的名字,字典值是命令所對應的redisCommand結構,這個結構保存了命令的實現函數、命令的標誌、命令應該給定的參數個數、命令的總執行次數和總耗時長等統計信息。

當程式在命令表中成功找到argv[0]所對應的redisCommand結構時,它會將客戶端狀態的cmd指針指向這個結構:

typedef struct redisClient{
struct redisCommand *cmd;
} redisClient;

之後,伺服器就可以使用cmd屬性所指向的redisCommand結構,以及argv、argc屬性中保存的命令參數信息,調用命令實現函數,執行客戶端指定的命令。

7、執行命令所得的命令回覆會被保存在客戶端狀態的輸出緩衝區裡面,每個客戶端有兩個輸出緩衝區可以用,一個緩衝區的大小是固定的,一個大小是可變的。

固定大小的緩衝區用於保存那些長度比較小的回覆,可變大小的緩衝區用於保存耐餓長度比較大的回覆。

客戶端的固定大小緩衝區由buf和bufpos兩個屬性組成

typedef struct redisClient{
char buf[REDIS_REPLY_CHUNK_BYTES];//REDIS_REPLY_CHUNK_BYTES 預設16 *1024  也就是說固定緩衝區預設 16k
int bufpos;//記錄已使用的位元組數量
} redisClient;

8、身份認證

客戶端狀態的authenticated屬性用於記錄客戶端是否通過了身份驗證:

typedef struct redisClient{
int authenticated;
} redisClient;

authenticated屬性僅在伺服器啟用了身份驗證功能的時候使用,如果伺服器沒有啟用的話,即使為0也不會拒絕客戶端的命令請求。

9、時間

typedef struct redisClient{
time_t ctime;//創建客戶端的時間 連接伺服器時長(秒)
time_t lastinteraction;//最後一次與伺服器互動時間,計算客戶端空轉時間
//記錄緩衝區第一次到達軟性限制的時間
time_t obuf_soft_limit_reached_time;
} redisClient;

如果客戶端是通過網路連接於伺服器進行連接的普通客戶端,那麼客戶端使用connect函數連接到伺服器時,伺服器就會調用連接事件處理器,為客戶端創建相應的客戶端狀態,並將這個新的客戶端狀態添加到伺服器狀態結構clients鏈表的末尾。

普通客戶端可以因為多種原因而被關閉:

客戶端進程退出或者被殺死,那麼客戶端與服務端的網路連接被關閉。

如果客戶端向服務端發送了帶有不符合協議的命令請求,那麼這個客戶端也會被關閉。

如果客戶端成為了CLIENT KILL命令的目標,那麼它也會被關閉。

如果服務端設置了timeout配置項,那麼客戶端的空轉事件超過timeout現象設置的值時,客戶端被關閉。

如果客戶端發送的命令請求的大小超過了輸入緩衝區的限制大小(預設1G),那麼客戶端會被伺服器關閉。

如果要發送給客戶端的命令回覆的大小超過了輸出緩衝區的限制大小,那麼這個客戶端會被伺服器關閉。

 

伺服器使用兩種模式來限制客戶端輸出緩衝區的大小:

1、硬性限制,如果輸出緩衝區的大小超過了硬性限制所設置的大小,那麼伺服器立即關閉客戶端。

2、軟性限制,如果輸出緩衝區的大小超過了軟性限制設置的大小,但沒有超過硬性設置的大小,obuf_soft_limit_reached_time屬性記錄下客戶端達到軟性限制的起始事件,之後伺服器會繼續監視客戶端,如果輸出緩衝區的大小一直超出軟性限制,並且持續時間超過伺服器設置的時長,那麼伺服器將關閉客戶端。

服務端會在初始化時創建負責執行Lua腳本中包含redis命令的偽客戶端,並將這個偽客戶端關聯在伺服器狀態結構的lua_client屬性中:

struct redisServer{
redisClient *lua_client;
}

lua_client 偽客戶端在伺服器運行的整個聲明周期中會一直存在,只有伺服器關閉時,這個客戶端才會關閉。

伺服器在載入AOF文件時,會創建用於執行AOF文件的Redis命令的偽客戶端,併在載入完成之後,關閉偽客戶端。

 


 

每天學一點,總會有收穫。

 

說明:尊重作者知識產權,文中內容參考《Redis設計與實現》,僅在此做學習與大家分享。


 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在圓形佈局中說過極坐標。 極坐標是長度和邊與極軸之間的角度的坐標表示。 換句話說,只要知道角度和長度(與中心點的距離),我們就能求出這一點的坐標,相對的我們知道這個一點的XY坐標也能求出角度和長度。 極坐標的工具性真的很強,在繪圖,動畫上 有很大的幫助,計算過程要簡單不少。 下麵我給出一個簡單的小慄 ...
  • 現在賬號密碼太多了。一不小心就忘了某些密碼,比如Centos的root密碼,我就記錄下怎麼解決的 1. 首先,打開centos7,在選擇進入系統的界面按“e”鍵進入編輯頁面 ​ 2. 然後按向下鍵,找到以“Linux16”開頭的行,在該行的最後面追加 “init=/bin/sh” ​ 接下來按“ct ...
  • [toc] rpm是什麼? rpm的全稱為 The RPM Package Manager ,是RHEL系操作系統的軟體包管理器,這些軟體包的尾碼為.rpm。 RPM命令用於在Linux系統上安裝,卸載,升級,查詢,列出和檢查RPM軟體包。 安裝 i,安裝軟體包 v,顯示命令執行過程 h,輸出進度條 ...
  • 目標鍵位:Caps Lock映射為Control L,Control L映射為Escape,Escape映射為Caps Lock 方法:修改/usr/share/X11/xkb/keycodes/evdev,使 <CAPS> = 9 <LCTL> = 66 <ESC> = 37 執行 sudo dp ...
  • Vi (Visual Interface)是 Linux下基於Shell 的文本編輯器,Vim (Visual Interface iMproved)是 Vi的增強版本,擴展了很多功能,比如對程式源文件的語法高亮。不管是 Vi 還是 Vim,我們習慣上都管它叫 Vi,但實際上用的更多的是 Vim。 ...
  • 不管是哪一門電腦語言,迴圈都是不可繞開的一個話題,Shell 當然也不是例外。下麵總結一些 Shell 腳本里常用的迴圈相關的知識點,新手朋友可以參考。 for 迴圈 Shell 腳本里最簡單的迴圈當屬 迴圈,有編程基礎的朋友應該都有使用過 for 迴圈。最簡單的 for 迴圈如下所示,你只需將變 ...
  • Linux計劃任務中對應的時間含義及指令 指令 : --linux定時任務 crontab -e # 創建自己的一個任務調度,此時會進入到vi編輯界面,來編寫我們要調度的任務 crontab -l # 列出定時的任務 時間對應關係 : 55 7 * * * csh -c "/home/dpower/ ...
  • 安裝系統 一、下載介質 https://www.archlinux.org/download/ 二、啟動 ISO 到Live 環境 此步驟由很多種方式: 製作ISO為U盤啟動工具,可以使用 Ultra ISO 或 大白菜 有Linux/Unix系統的,可以硬碟寫入Grub,製作啟動項 三、安裝前的準 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...