標籤:
慢查詢日誌記錄最新的N條執行時間超過M毫秒的命令。慢查詢日誌儲存在記憶體中,而不是檔案中,這保證了慢查詢日誌的效率。
慢查詢日誌的條目定義/* This structure defines an entry inside the slow log list *//* * 慢查詢日誌 */typedef struct slowlogEntry { // 命令與命令參數 robj **argv; // 命令與命令參數的數量 int argc; // 唯一識別碼 long long id; /* Unique entry identifier. */ // 執行命令消耗的時間,以微秒為單位 // 注釋裡說的 nanoseconds 是錯誤的 long long duration; /* Time spent by the query, in nanoseconds. */ // 命令執行時的時間,格式為 UNIX 時間戳記 time_t time; /* Unix time at which the query was executed. */} slowlogEntry;
伺服器和慢查詢有關的定義 /* slowlog */ // 儲存了所有慢查詢日誌的鏈表 list *slowlog; /* SLOWLOG list of commands */ // 下一條慢查詢日誌的 ID long long slowlog_entry_id; /* SLOWLOG current entry ID */ // 伺服器配置 slowlog-log-slower-than 選項的值 long long slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */ // 伺服器配置 slowlog-max-len 選項的值 unsigned long slowlog_max_len; /* SLOWLOG max number of items logged */伺服器的慢查詢儲存在一個list中,list中的每一項都是一條慢查詢日誌,較新的日誌總是儲存在隊首。慢查詢日誌中儲存命令的執行參數和執行時間,如果超出系統限制,參數和日誌可能被截斷。
慢查詢支援的用戶端操作GET:擷取某條或者全部慢查詢日誌RESET:清空慢查詢日誌LEN:慢查詢日誌的數量
慢查詢日誌的應用redis每執行一條命令,就會記錄命令的開始時間和結束時間,由此計算命令的執行時間。並發命令以及命令的執行時間傳遞給slowlogPushEntryIfNeeded,由slowlogPushEntryIfNeeded決定是否產生慢查詢日誌。/* Call() is the core of Redis execution of a command */// 調用命令的實現函數,執行命令void call(redisClient *c, int flags){ //擷取命令的執行時間 /* Log the command into the Slow log if needed, and populate the * per-command statistics that we show in INFO commandstats. */ // 如果有需要,將命令放到 SLOWLOG 裡面 if (flags & REDIS_CALL_SLOWLOG && c->cmd->proc != execCommand) slowlogPushEntryIfNeeded(c->argv,c->argc,duration);}
slowlogPushEntryIfNeeded的實現判斷系統標誌位,並把慢查詢日誌加入到伺服器的慢查詢鏈表中/* Push a new entry into the slow log. * * 如果參數 duration 超過伺服器設定的上限時間, * 那麼將一個新條目以 FIFO 順序推入到慢查詢日誌中。 * * This function will make sure to trim the slow log accordingly to the * configured max length. * * 根據伺服器設定的最大日誌長度,可能會對日誌進行截斷(trim) */void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) { // 慢查詢功能未開啟,直接返回 if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */ // 如果執行時間超過伺服器設定的上限,那麼將命令添加到慢查詢日誌 if (duration >= server.slowlog_log_slower_than) // 新日誌添加到鏈表表頭 listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration)); /* Remove old entries if needed. */ // 如果日誌數量過多,那麼進行刪除 while (listLength(server.slowlog) > server.slowlog_max_len) listDelNode(server.slowlog,listLast(server.slowlog));}
redis的慢查詢日誌