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
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...