服務端執行命令請求的過程
- 【專欄簡介】
- 【技術大綱】
- 【專欄目標】
- 【目標人群】
- 1. Redis愛好者與社區成員
- 2. 后端開發和系統架構師
- 3. 計算機專業的本科生及研究生
- 初始化服務器
- 1. 初始化服務器狀態結構
- 初始化`RedisServer`變量
- 2. 加載相關系統配置和用戶配置參數
- 定制化配置參數
- 案例分析
- 更新服務端口號
- 更新數據庫個數
- 配置覆蓋總結
- 3. 創建和初始化對應的對象結構實例
- initServer初始化服務器
- 創建和修改內存數據結構
- initServer分配內存對象
- 總結介紹
- 載入RDB文件或者AOF文件
【專欄簡介】
隨著數據需求的迅猛增長,持久化和數據查詢技術的重要性日益凸顯。關系型數據庫已不再是唯一選擇,數據的處理方式正變得日益多樣化。在眾多新興的解決方案與工具中,Redis憑借其獨特的優勢脫穎而出。
【技術大綱】
為何Redis備受矚目?原因在于其學習曲線平緩,短時間內便能對Redis有初步了解。同時,Redis在處理特定問題時展現出卓越的通用性,專注于其擅長的領域。深入了解Redis后,您將能夠明確哪些任務適合由Redis承擔,哪些則不適宜。這一經驗對開發人員來說是一筆寶貴的財富。
在這個專欄中,我們將專注于Redis的6.2版本進行深入分析和介紹。Redis 6.2不僅是我個人特別偏愛的一個版本,而且在實際應用中也被廣泛認為是穩定性和性能表現都相當出色的版本。
【專欄目標】
本專欄深入淺出地傳授Redis的基礎知識,旨在助力讀者掌握其核心概念與技能。深入剖析了Redis的大多數功能以及全部多機功能的實現原理,詳細展示了這些功能的核心數據結構和關鍵算法思想。讀者將能夠快速且有效地理解Redis的內部構造和運作機制,這些知識將助力讀者更好地運用Redis,提升其使用效率。
將聚焦于Redis的五大數據結構,深入剖析各種數據建模方法,并分享關鍵的管理細節與調試技巧。
【目標人群】
Redis技術進階之路專欄:目標人群與受眾對象,對于希望深入了解Redis實現原理底層細節的人群。
1. Redis愛好者與社區成員
Redis技術有濃厚興趣,經常參與社區討論,希望深入研究Redis內部機制、性能優化和擴展性的讀者。
2. 后端開發和系統架構師
在日常工作中經常使用Redis作為數據存儲和緩存工具,他們在項目中需要利用Redis進行數據存儲、緩存、消息隊列等操作時,此專欄將為他們提供有力的技術支撐。
3. 計算機專業的本科生及研究生
對于學習計算機科學、軟件工程、數據分析等相關專業的在校學生,以及對Redis技術感興趣的教育工作者,此專欄可以作為他們的學習資料和教學參考。
無論是初學者還是資深專家,無論是從業者還是學生,只要對Redis技術感興趣并希望深入了解其原理和實踐,都是此專欄的目標人群和受眾對象。
讓我們攜手踏上學習Redis的旅程,探索其無盡的可能性!
初始化服務器
Redis服務器自啟動至具備處理客戶端命令請求的能力,需經歷一系列嚴謹的初始化與配置環節。
其中涵蓋了初始化服務器運行狀態、加載用戶設定的配置參數、構建必要的數據結構體系以及建立網絡通信連接等關鍵步驟。接下來,將對Redis服務器完整的初始化流程展開細致闡述。
1. 初始化服務器狀態結構
初始化服務器的第一步就是創建一個結構體structredisServer
類型的實例變量作為服務器的狀態,并為結構中的各個屬性設置默認值。
初始化RedisServer
變量
初始化RedisServer
變量的工作由redis.c/initServerConfig
函數完成,以下是這個函數最開頭的一部分代碼:
void initserverConfig(void){//設置服務器的運行id getRandomHexChars(server.runid,REDIS_RUN_ID_SIZE)//為運行id加上結尾字符 server.runid[REDIS_RUN_ID_SIZE] = '\0';//設置默認配置文件路徑 server.configfile = NULL;//設置默認服務器頻串 server.hz = REDIS_DEFAULT_HZ;//設置服務器的運行架構 server.arch_bits = (sizeof (long) == 8 )64 32;//設置默認服務器端口號 server.port = REDIS_SERVERPORT;
}
以下是initServerConfig
函數完成的主要工作:
注意,
initServerConfig
函數沒有創建服務器狀態的其他數據結構,數據庫、慢查詢日志、Lua環境、共享對象這些數據結構在之后的步驟才會被創建出來。
當initServerConfig
函數執行完畢之后,服務器就可以進人初始化的第二個階段一載人配置選項。
2. 加載相關系統配置和用戶配置參數
在啟動服務器時,用戶可以通過給定配置參數或者指定配置文件來修改服務器的默認配置。舉個例子,如果我們在終端中輸人
定制化配置參數
$ \redis-server --port 10086
那么我們就通過給定配置參數的方式,修改了服務器的運行端口號。另外,如果我們在終端中輸人:
$ \redis-server redis.conf
并且redis.conf文件中包含以下內容:
#將服務器的數據庫數量設置為32個
databases 32
#關閉RDB文件的壓縮功能
rdbcompression no
那么我們就通過指定配置文件的方式修改了服務器的數據庫數量,以及RDB
持久化模塊的壓縮功能。
服務器在用initServerConfig
函數初始化完server變量之后,就會開始載人用戶給定的配置參數和配置文件,并根據用戶設定的配置,對server變量相關屬性的值進行修改。
案例分析
例如,在初始化server變量時,程序會為決定服務器端口號的port屬性設置默認值:
void initServerconfig(void){//默認值為6379 server.port=REDIS_SERVERPORT;
}
更新服務端口號
如果用戶在啟動服務器時為配置選項port指定了新值10086($ redis-server --port 10086
),那么server. port
屬性的值就會被更新為10086
,這將使得服務器的端口號從默認的6379變為用戶指定的10086。
更新數據庫個數
如果用戶在啟動服務器時為選項databases
設置了值32
,那么server. dbnum
屬性的值就會被更新為32,這將使得服務器的數據庫數量從默認的16個變為用戶指定的32個。
配置覆蓋總結
服務器在載入用戶指定的配置選項,并對server狀態進行更新之后,服務器就可以進人初始化的第三個階段一初始化服務器數據結構。
3. 創建和初始化對應的對象結構實例
在之前執行initServerConfig
函數初始化server狀態時,程序只創建了命令表一個數據結構,不過除了命令表之外,服務器狀態還包含其他數據結構,比如:
server.clients
(鏈表):記錄了與服務器相連的客戶端的狀態結構,每個節點包含redisclient結構實例server.db
(數組):包含了服務器的所有數據庫。server.pubsub channels
(字典):保存頻道訂閱信息,以及保存模式訂閱信息的server,pubsub_patterns
鏈表。server.lua
:執行Lua腳本的Lua環境server.slowlog
:慢查詢日志的屬性
initServer初始化服務器
初始化服務器進行到這一步,服務器將調用initServer
函數,為以上提到的數據結構分配內存,并在有需要時,為這些數據結構設置或者關聯初始化值。
注意,服務器到現在才初始化數據結構的原因在于,服務器必須先載入用戶指定的配置選項,然后才能正確地對數據結構進行初始化。
創建和修改內存數據結構
如果在執行initServerConfig
函數時就對數據結構進行初始化,那么一旦用戶通過配置選項修改了和數據結構有關的服務器狀態屬性,服務器就要重新調整和修改已創建的數據結構。
為了避免出現這種麻煩的情況,服務器選擇了將server狀態的初始化分為兩步進行:
initServerConfig
函數主要負責初始化屬性initserver
函數主要負責初始化數據結構
initServer分配內存對象
- 創建進程信號處理器
- 創建共享復用對象
- Redis服務器常用的值,像表示 “OK” 回復、“ERR” 回復的字符串對象,以及對應整數1到10000的字符串對象等。服務器復用這些共享對象,避免重復創建相同對象。
- 創建事件監聽器
- 監聽套接字關聯連接應答事件處理器,待服務器正式運行時接收客戶端連接。
- 創建時間事件
- 同時為
serverCron
函數創建時間事件,待服務器運行時執行該函數。
- 同時為
- 載入AOF文件數據
- 若AOF持久化功能已開啟,打開現有的AOF文件;若文件不存在,則創建并打開新的 AOF 文件,為 AOF 寫入操作做準備。
- 建立I/O處理器模塊:
- 初始化服務器的后臺I/O模塊,為后續的 I/O 操作做好準備。
總結介紹
serverCron
函數默認每隔100毫秒執行一次,它的工作主要包括更新服務器狀態信息,處理服務器接收的SIGTERM
信號,管理客戶端資源和數據庫狀態,檢查并執行持久化操作等等。
命令請求從發送到完成主要包括以下步驟:
服務從啟動到能夠處理客戶端的求需要執行以下步驟:
載入RDB文件或者AOF文件
服務器依據文件記錄還原數據庫狀態,具體方式取決于AOF持久化功能是否啟用:若啟用,使用AOF文件還原;若未啟用,則使用RDB文件。完成數據庫狀態還原后,服務器會在日志中記錄文件載入及狀態還原耗時。