Redis學習筆記(十一) 伺服器

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

Redis伺服器負責與多個客戶端建立網路通信,處理客戶端發送的命令請求,在資料庫中保存客戶端執行命令所產生的數據,並通過資源管理來維持伺服器自身的運轉。 命令請求過程(以set命令為例) 1、客戶端向伺服器發送命令請求 SET KEY VALUE。 Redis伺服器的命令請求來自於Redis客戶端, ...


Redis伺服器負責與多個客戶端建立網路通信,處理客戶端發送的命令請求,在資料庫中保存客戶端執行命令所產生的數據,並通過資源管理來維持伺服器自身的運轉。

 

命令請求過程(以set命令為例)

 

1、客戶端向伺服器發送命令請求 SET KEY VALUE。

 

Redis伺服器的命令請求來自於Redis客戶端,當用戶從客戶端鍵入一個命令請求時,客戶端會將這個命令命令請求請求轉換成協議格式,然後通過連接到伺服器的套接字,將協議格式的命令請求發送給伺服器。

 

 

 2、伺服器接收並處理客戶端發送來的命令請求 SET KEY VALUE,在資料庫中進行設置操作,並產生命令回覆OK。

讀取套接字中的協議格式命令請求,並將其保存在客戶端狀態的輸入緩衝區中。

對輸入緩衝區中的命令請求進行解析,提取出命令請求中包含的命令參數,以及命令參數的格式,分別將參數和參數個數保存到客戶端狀態的argv和argc屬性中

調用命令執行器,執行客戶端指定的命令。

命令執行器:

1、查找命令。2、執行預備操作。(檢查命令、命令參數、客戶端身份驗證、檢查伺服器記憶體占用情況、事務、伺服器狀態、是否監聽等)3、調用命令實現函數,產生命令回覆函數,保存在客戶端狀態的輸出緩存區4、執行後續工作:(慢查詢檢查記錄日誌;根據命令耗時更新redisCommand結構的milliseconds屬性、calls計數器加1;如果開啟了AOF,如果是寫命令則寫入到AOF緩衝區;如果有其他從伺服器正在複製當前的伺服器,那麼伺服器會將剛剛執行的命令傳播給所有從伺服器。)

3、伺服器將命令回覆OK發送為客戶端。

 

當客戶端套接字變為可寫狀態時,伺服器會執行命令回覆處理器,將保存在客戶端緩衝區的命令回覆發送給客戶端。

 

4、客戶端接收伺服器返回的命令回覆OK,並將這個回覆列印給用戶觀看。客戶端收到協議格式的命令回覆後,將其轉換為人類可讀的格式,並列印。

 

 

 

 

serverCron函數

 

 

Redis伺服器中的serverCron函數每100毫秒執行一次,這個函數負責管理伺服器的資源,並保持伺服器自身的良好運轉。

 

1、更新伺服器緩存時間,為減少系統調用獲取當前時間的次數,伺服器狀態中的unixtime和mstime屬性被用作當前時間的緩存:

struct redisServer{
    //保存了秒級精度的當前unix時間戳
    time_t unixtime;
    //保存了毫秒級精度的系統當前unix時間戳
    long long mstime;
    //預設每10秒更新一次事件緩存,用於計算鍵的空轉時間。
    unsigned lruclock:22
}

伺服器只會在列印日誌、更新伺服器LRU始終、決定是否執行持久化任務、計算伺服器上線時間這類對事件精度不高的功能上用;對於為鍵設置過期事件、添加慢日誌這種需要高精度事件的功能來說,伺服器還是會再次執行系統調用,從而獲得更準確的系統當前事件。

 

每個Redis對象都有一個lru屬性,這個lru屬性保存了對象最後一次被命令訪問的時間:

typedef struct redisObject{
    unsigned lru:22'
} robj;

serverCron函數中的trackOperationsPerSecond函數會以每100毫秒一次的頻率執行,這個函數的功能以抽樣計算的方式,估算並記錄伺服器在最近一秒鐘處理的命令請求數量,這個值通過INFO status命令的instantaneous_ops_per_sec域查看。

2、更新伺服器記憶體峰值記錄:伺服器狀態中的stat_peak_memory屬性記錄伺服器的記憶體峰值大小:

struct redisServer{
    //已使用記憶體峰值
    size_t stat_peak_memory;
}

3、處理sigterm信號

static void sigtermHandler(int sig){
    //列印日誌
    redisLogFromHandler(REDIS_WARNING,"received sigterm,scheduling shutdown...");
    //打開關閉標識
    server.shutdown_asap=1;
}
struct redisServer{
    //serverCron函數運行時,程式灰度伺服器狀態的shutdown_asap屬性進行檢查,並根據屬性值決定是否關閉伺服器。
    //關閉伺服器的標識
    //值為1時,關閉伺服器
    //值為0時,不做動作
    int shutdown_asap;
}

4、管理客戶端資源

serverCron函數每次執行都會調用clientCron函數,clientsCron函數會對一定數量的客戶端進行檢查:如果客戶端與伺服器之間的連接已經超時,那麼程式釋放這個客戶端;如果客戶端在上一次執行命令請求後,輸入緩衝區的大小超過了一定的長度,那麼程式會釋放客戶端當前的輸入緩衝區,重新創建一個迷人大小的輸入緩衝區,防止客戶端的輸入緩衝區耗費過多的資源。

5、管理資料庫資源 :刪除過期鍵,如有需要,對字典進行收縮操作。

6、執行被延遲的BGREWRITEAOF

如果BGSAVE執行期間,客戶端發來BGREWRITEAOF命令,則需要延遲到BGSAVE命令執行完成後。

7、檢查持久化操作運行狀態

伺服器狀態使用rdb_child_pid\aof_child_pid屬性記錄執行BGSAVe命令和BGREWRITEAOF命令的子進程ID,用於檢查命令是否正在執行

struct redisServer{
    //記錄執行BGSAVE命令的紫禁城,如果沒有執行則為-1
    pid_t rdb_child_pid;
    //記錄執行BGREWRITEAOF命令的子進程ID,沒執行則為-1
    pid_t aof_child_pid;
}

 

 

8、將AOF緩衝區中的內容寫入AOF文件

9、關閉非同步客戶端(檢查輸出緩衝區大小)

10、增加cronloops計數器的值(沒執行serverCron函數N次就執行一次指定的代碼)

 

初始化伺服器

 

1、初始化伺服器狀態結構,創建一個struct redisServer類型的實例變數server作為伺服器的狀態。

initServerConfig函數完成的主要工作:

設置伺服器運行ID

設置伺服器的預設運行頻率

設置伺服器的預設配置文件路徑

設置伺服器的運行架構

設置伺服器的預設埠號

設置伺服器預設RDB持久化條件和APF持久化條件

初始化伺服器LRU時鐘

創建命令表

2、載入配置項修改預設的配置。

3、初始化伺服器數據結構

在執行initServerConfig函數初始化server狀態時,程式只創建命令表一個數據結構,伺服器在次數初始化其他數據結構:

server.clients鏈表,記錄所有與伺服器相連接的客戶端狀態

erver.db數組,包含伺服器的所有資料庫。

保存頻道訂閱信息的server.pubsub_channels字典以及保存模式訂閱信息的server_publsub_patterns鏈表。

執行Lua腳本的Lua環境 server.lua;

用於保存慢查詢日誌的server.slwlog鏈表

除了初始化數據結構之外,initServer還進行了一些非常重要的設置操作:

為伺服器設置進程信號處理器。

創建共用對象。

打開伺服器的監聽端,並未監聽套接字關聯連接應答事件處理時,等待伺服器正式運行時接收客戶端連接。

為serverCron函數創建時間事件,等待伺服器正式運行時,執行serverCron函數。

如果AOF持久化功能打開,那麼打開現有的AOF文件,如果文件不存在則創建新的AOF文件

初始化伺服器的後臺I/O模塊,為將來的I/O操作做準備。

 

執行完以上內容那麼你就看到了熟悉的畫面:

 

 

4、還原資料庫裝填

在完成對伺服器狀態server變數的初始化後,伺服器需要載入RDB文件或者AOF文件,並根據文件記錄的內容還原資料庫狀態

5、執行事件迴圈

到此伺服器的初始化工作圓滿完成,伺服器現在開始可以接收客戶端的連接請求,並處理客戶端發來的命令請求。

 


 

寫到這裡,非常有衝動寫一下.net 程式初始化以及運行過程服務端做了那些事情,著手準備!


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

 

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

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 最近看到vmlinux大神介紹了一款網路查看工具,感覺很好用,下麵進行簡要摘錄: iptraf-ng 可以方便查看當前伺服器網路狀況:CentOS 7.0,採用了衍生版本iptraf-ng 。 iptraf-ng -h usage: iptraf-ng [options] or: iptraf-ng ...
  • 1. 目的 簡化SSH登陸過程, 實現從機器A登陸機器B只需要運行 即可, 即不需要輸入用戶名和密碼。 2. 配置host 配置host的作用是ssh登陸機器時用hostname代替IP, 在機器很多的集群環境中hostname比IP容易記的多, 編輯 文件, 配置需要登陸的機器IP和hostnam ...
  • linux下c編程特點 typeof 取變數類型 GNU c對比ANSI c做了很多擴展,例如動態數組 第7章 Linux設備驅動中的併發控制 造成竟態的原因 多核 進程和中斷形成的多路徑(linux2.6以後,禁止了中斷嵌套) 編譯亂序 執行亂序 解決竟態的辦法 中斷屏蔽:只能屏蔽本核的 原子操作 ...
  • 1、重啟tomcat 使用命令:ps: 查詢tomcat進程號 kill:殺死tomcat進程 步驟: 1)ps -ef | grep tomcat 查詢tomcat進程號, 2)kill -9 進程號 強制殺死該進程2 3)ps -ef | grep tomcat 再次查詢進程是否已經被殺死 4) ...
  • 問題:supervisorctl restart 服務名 失敗 案例: [root@node203 ~]# supervisorctl statusetcd-server-97-203 RUNNING pid 7706, uptime 14:29:46kube-apiserver-97-203 FA ...
  • 資料庫 1.1 資料庫基礎 1.1.1 選擇 1.1.1.1 Having 子句的作用是(C )。 A.查詢結果的分組條件 B.組的篩選條件 C.限定返回的行的判斷條件 D.對結果集進行排序 1.1.1.2 最常用的一種基本數據模型是關係數據模型,它的表示採用(D) A.樹 B.網路 C.圖 D.二 ...
  • 在Oracle和SQL Server資料庫中,可以設置一些複雜的賬號密碼策略,例如在失敗登錄超過N次即可鎖定賬號,那麼在MySQL中能否也有這樣的功能呢?答案是MySQL也有類似這樣的功能,只不過在MySQL中是在其登錄失敗超過閥值後,延遲響應時間,而不是鎖定賬號,在MySQL 5.7.17 以後提... ...
  •  JDBC基本使用方法 JDBC固定步驟: 載入驅動 連接資料庫,代表資料庫 向資料庫發送SQL的對象Statement: CRUD 編寫SQL (根據業務, 不同的SQL) 執行SQL 遍歷結果集 關閉連接 補充: statement.executeQuery(); //執行查詢操作 state ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...