Redis服務器負責與多個客戶端建立網絡連接,處理客戶端發送三個的命令請求,在數據庫中爆粗你客戶單執行命令所產生的數據,并通過資源管理來維持服務器自身的運轉。
命令請求的執行過程 當服務器與客戶端的連接套接字因為客戶端的寫入而變得可讀時,服務器將調用命令請求處理器來執行以下操作:
-1、讀取套接字中協議格式的命令請求,并將其保存到客戶端狀態的輸入緩沖區中;
-2、對輸入緩沖區中的命令請求進行分析,提取出命令請求中包含的命令參數,以及命令參數的個數,然后分別將參數和參數個數保存到客戶單狀態的argv屬性和argc屬性里面;
-3、調用命令執行器,執行客戶單指定的命令。
命令執行器做的第一件事就是根據客戶單狀態的argv[0]參數,在命令表中查找參數所指定的命令,并將命令保存到客戶端狀態的cmd屬性中。
命令執行器的預備操作:
-1、檢查客戶端狀態的cmd指針是否指向NULL,如果是的話,說明用戶輸入的命令名字找不到實現,返回錯誤;
-2、根據cmd屬性指向的arity屬性,檢查命令參數是否正確,不正確返回錯誤;
-3、檢查客戶的江岸是否已經通過了身份驗證,未通過身份驗證的客戶單只能執行auth命令,如果未通過客戶端執行其他命令,返回錯誤;
-4,如果服務器打開了maxmemory功能,那么在執行命令之前,先檢查副武器的內存占用情況,并在有需要的時候回收內存,從而使得接下來的命令可以順利執行,如果回收失敗,那么返回錯誤;
-5、如果服務器上一次執行bgsave出錯,并且打開了stop-writes-on-bgsave-error功能,而且即將執行一個寫命令,返回錯誤;
-6、如果客戶端正在訂閱頻道,或者正在訂閱模式,那么服務器智慧執行客戶端發來的訂閱相關命令;
-7、如果服務器正在進行數據載入,那么客戶端發送的命令必須帶有l標識才會執行,否則拒絕執行;
-8、如果服務器因為執行lua腳本而超時并進入阻塞狀態,那么服務器智慧執行客戶端發來的shutdown nosave命令和script kill命令,其他拒絕;
-9、如果客戶端正在進行事務,那么服務器智慧執行客戶端發來的事務相關命令,其他命令進隊列;
-10、如果服務器打開了監視器功能,那么服務器會將要執行的命令和參數等信息發送給監視器。
調用命令實現函數
前面的操作已經將處理器注冊到了cmd中,執行后將回復保存到客戶端的輸出緩沖區中。
執行后續工作
-1、如果服務器開啟了慢查詢日志功能,那么man插敘你日志模塊會檢查是否需要為剛剛執行完的命令請求添加一條新的慢查詢日志。
-2、根據執行命令所耗費的時長,更新redisCommand的毫秒屬性,并將命令的引用計數+1;
-3、如果服務器開啟了AOF持久化功能,那么會將剛剛執行的命令請求寫入到AOF緩沖區中;
-4、如果有其他從服務器正在復制當前這個服務器,那么服務器會將剛剛執行的命令傳遞給所有從服務器。
將命令回復發送給客戶端
當客戶單的套接字變為可寫狀態時,服務器就會執行命令回復處理器,將保存在客戶端輸出緩沖區中的命令回復發送給客戶端,發送完畢后,回復處理器會清空客戶單狀態的輸出緩沖區,為處理下一個命令請求做好準備。
serverCron函數
redis服務器中的serverCron函數默認每隔100ms執行一次,這個函數負責管理服務器資源,并保持服務器自身的良好運轉。
功能:
-1、更新服務器時間緩存:會以100ms的頻率更新unixtime和mstime;
-2、更新lru時鐘:服務器狀態中的lruclouk屬性保存了副武器的lru時鐘,默認每10秒更新一次的時鐘緩存,用于計算鍵的空轉時長,通過與對象的lru對比;
-3、更新服務器每秒執行命令次數:100ms的頻率執行;
-4、更新服務器內存峰值記錄:stat_peak_memory記錄了服務器內存峰值的大小,每次執行serverCron都會查看當前的內存數量進行對比,判斷是否覆蓋。
-5、處理SIGTERM信號:在啟動時,redis會為服務器進程的sigterm信號關聯處理器,處理器會在服務器接到信號時,打開shutdown_asap標識,每次運行serverCron,程序都會檢測這個標識,判斷知否關閉服務器。
-6、管理客戶端資源:每次調用會檢查超時客戶端并釋放,如果客戶單在上一次執行命令后,輸入緩沖區的大小超過了一定的長度,那么程序會釋放客戶單當前的輸入緩沖區,并重新創建一個默認大小的輸入緩沖區,防止消耗過多內存。
-7、管理數據庫資源:每次執行會調用databasesCron,它會檢查一部分數據庫,刪除過期鍵,在必要時對字典進行收縮操作;
-8、執行被延遲的BGREWRITEAOF:在執行bgsave期間,客戶端發來bgrewriteaof命令,那么這個命令會延遲到bgsave命令執行完畢之后;
-9、檢查持久化操作的運行狀態:只要rdb_child_pid和aof_child_pid其中一個不為-1,就會執行一次wait3,檢查子進程是否有信號發來服務器進程。其他情況會判斷是否有bgrewriteaof被延遲了,或者自動保存條件被觸發,或者aof重寫條件被觸發;
-10、將aof緩沖區的內容寫入aof文件;
-11、關閉異步客戶端;
-12、增加cronloops計數器,每次執行都會+1;
初始化服務器
-1、初始化服務器狀態結構:設置服務器運行id,設置默認配置文件路徑,設置默認服務器頻率,設置服務器運行架構,設置默認端口號,設置默認rdb條件和aof條件,初始化lru時鐘,創建愛你命令表;
-2、載入配置選項:命令行的參數,配置文件的設置;
-3、初始化服務器數據結構:創建客戶端狀態的鏈表,創建數據庫數組,創建訂閱字典,創建訂閱模式的鏈表,更改慢查詢日志的slowlog屬性,更改lua屬性; 為服務器設置進程信號處理器,創建愛你共享對象,打開服務器監聽端口,為serverCron創建時間事件,如果aof打開,那么打開現有aof文件,否則創建,初始化服務器的后臺I/O模塊bio。
還原數據庫狀態
如果開啟了aof,使用aof文件還原數據庫狀態,否則使用rdb文件。
執行事件循環
server.c
評論
查看更多