- redisClient 中有輸入輸出緩衝區
- 輸入緩衝區:命令處理器將用戶輸入的命令寫入客戶端輸入緩衝區,該緩衝區可動態擴展,但最大不能超過 1G,不然服務器將關閉客戶端;
- 輸出緩衝區:命令執行器將命令執行生成的回覆寫入輸出緩衝區,並關聯回覆響應處理器,待客戶端產生可寫事件時,回覆響應處理器將輸出緩衝區的內容發送給客戶端,並清空輸出緩衝區;
- 輸入緩衝區的內容被解析後,生成命令、參數等信息,存入redisClient中的argv數組,並記錄數組長度,以待後續命令檢查及執行;
- serverCron(時間事件,默認每隔100ms執行一次):
- 更新服務器時間:unixtime/mstime(s/ms),默認100ms;
- 更新lru_time:默認10s;
- 更新服務器每秒執行命令數(大概值,取1ms次數乘以1000爲一次樣本,默認取16次樣本平均值);
- 處理sigterm信號(不帶參數的kill):redisServer.asap狀態,serverCron每次執行,都將檢測該標識,爲1時,將關閉服務器,且關閉前將進行持久化操做;
- 管理客戶端資源:每次serverCron都執行,釋放過時客戶端及清理客戶端輸入緩衝區;
- 管理數據庫資源:每次都調用databaseCron,隨機處理一部分數據的過時鍵,並在須要時,對字典(鍵空間)進行收宿操做;
- bgrewriteaof:redisServer.aof_rewrite_scheduled,BGSAVE期間,若收到bgrewriteaof命令,將修改此標識,延時到serverCron執行期間執行此命令;
- 檢查子進程持久化操做的運行狀態,以判斷是否須要執行後續操做(替換rdb文件或者重寫的aof文件等等),若無持久化狀態,則檢查是否知足持久化條件,進行持久化,或者aof重寫;
- 將aof緩衝區中的內容寫入aof文件(開啓aof且緩衝區有數據),並按配置判斷是否須要調用同步指令;
- 關閉異步客戶端(輸出緩衝區大小超過限制);
- 增長cronLoops計數值,該計數記錄了serverCron執行次數(目前該計數惟一做用:在複製模塊中實現,serverCron函數每執行N次,就執行一次指定代碼);
- 服務器初始化
- 建立redisServer實例變量server;
- 調用initServerConfig,設置server默認值,並建立命令表;
- 載入配置項,並使用配置的值替換server中的默認值;
- 調用initServer函數,爲建立相關數據結構分配內存,並按需設置或關聯初始化值等,並進行一些設置:
- 數據結構:
- server.cliens 鏈表
- server.db 數組
- server.pubsub_channels 字典,用於保存頻道訂閱信息;
- server.pubsub_patterns 鏈表,保存模式訂閱信息;
- server.lua 用於執行lua腳本的lua環境;
- server.slowlog 用於保存慢查詢日誌;
- 設置:
- 爲服務器設置進程信號處理器;
- 建立共享對象(如服務器經常使用的"OK"等字符串常量,其中有表示整數1-10000的字符串對象);
- 打開服務器的監聽端口,併爲監聽套接字關聯【鏈接應答處理器】;
- 爲serverCro函數件建立時間事件;
- 若AOF持久化功能打開,打開現有的AOF文件,若不存在,建立一個新的,爲AOF寫入作準備;
- 初始化服務器上後臺IO(BIO)模塊,
- initServer執行完後,打印redis圖標及支行模式、服務器版本、端口號、PID等信息;
- 還原數據庫狀態:載入RDB或AOF文件(若啓用AOF,就用AOF,不然用RDB),還原數據;
- 執行事件循環;
- 日誌:xxx The server is now ready to accept connections on port 6379;
- 簡單描述初始化過程:
- 初始化服務器狀態;
- 載入服務器配置;
- 初始化服務器數據結構;
- 還原數據庫狀態;
- 執行事件循環;
- 事件輪詢:
- 獲取到達時間最近的時間事件,假設是t事件;
- 獲取t事件到達時間,若已到達(負數),置爲0,作爲獲取文件事件的等待時間,設該時間爲n;
- 以n爲等待時間獲取文件事件(有事件當即返回,無事件等待,直到有事件或超時);
- 若獲取到文件事件,執行;
- 檢查並執行全部已到達的時間事件(單機只有serverCron?)
- 重複這個過程;
- redis應用:
- main:初始化,而後調用aeMain;
- aeMain:死循環,調用aeProcessEvents
- aeProcessEvents:處理文件事件及時間事件(過程見上述:事件輪詢);
一些結構:redis
redisServer數據庫
redisClient數組
redisDb服務器
redisObject數據結構
redisCommand異步
執行命令時,若是客戶端正在訂閱頻道或模式,那麼服務器將只接受發佈訂閱相關的命令,其它命令會被拒絕; 所以,哨兵既要訂閱消息,又要發出命令,須要創建兩個 鏈接 到服務器;函數