1. 程式人生 > 其它 >《Redis設計與實現》讀書筆記(三十六) ——Redis 慢查詢日誌實現

《Redis設計與實現》讀書筆記(三十六) ——Redis 慢查詢日誌實現

《Redis設計與實現》讀書筆記(三十六) ——Redis 慢查詢日誌實現

(原創內容,轉載請註明來源,謝謝)

一、基本功能

redis的慢查詢日誌,用於記錄執行時間超過給定時長的命令請求,使用者可以通過這個功能產生的日誌來監視和優化查詢速度。

redis伺服器中,有兩個配置選項與此相關。

1)slowlog-log-slower-than,該選項確定超過多少微秒的命令請求,會被記錄到日誌。

2)slowlog-max-len,該選項指定伺服器最多儲存多少條慢查詢日誌。超出這個條數的,則會先刪除最舊的一條日誌,再新增一條日誌。

可以用config setslowlog-log-slower-than 100來設定超過100毫秒的命令,或config set slowlog-max-len 100來設定慢查詢日誌最多紀錄100條等。

可以通過sloglogget,來獲取當前的慢查詢日誌。

二、慢查詢記錄的儲存

伺服器狀態中,有幾個和慢查詢相關的屬性,儲存在redisServer結構體中。

struct redisServer{
//....其他內容
long long slowlog_entry_id;//下一條慢查詢日誌的id
list *slowlog;//所有慢查詢日誌的連結串列
long long slowlog-log-slower-than;//伺服器配置的slowlog-log-slower-than值
unsigned long slowlog-max-len;//伺服器配置的slowlog-max-len值
};

slowlog_entry_id初始化的值是0,每建立一條新的慢查詢日誌,這個屬性的值就會變成最新的日誌id的值,之後每建立一個慢查詢日誌,程式會對這個屬性的值增1,作為新的慢查詢日誌的id。

slowlog連結串列,儲存了伺服器中所有的慢查詢日誌,連結串列中的每一個節點,就是一個slowlogEntry結構,每個結構代表一個慢查詢日誌。

typedef struct slowlogEntry{
long long id;//唯一識別符號
time_t time;//命令執行時間,是unix時間戳
long long duration;//命令執行消耗時間,毫秒為單位
robj **argv;//命令與命令引數
int argc;//命令數量
}slowlogEntry;

例如下圖的慢查詢日誌:

其slowlogEntry結構如下圖所示:

整體屬性如下圖所示:

id越大的排在連結串列的表頭,因此slowlog連結串列是使用插入到表頭的方式來新增新日誌。

三、慢查詢日誌的閱覽和刪除

如果沒有指定返回的log的數量,預設返回整個慢查詢日誌。如果有指定,則會返回指定數量。但是如果指定的數量超出總數量,還是會返回整個慢查詢日誌。

四、新增新日誌

每次執行前和執行後,redis伺服器都會用微秒的方式,記錄unix時間戳,差距就是執行伺服器命令的耗時。

這個耗時會傳給slowlogPushEntryIfNeeded函式,用於判斷是否需要將查詢命令記錄到慢查詢日誌,以及目前的日誌長度是否超出設定的範圍,再將slowlog_entry_id值加1。

五、總結

1、慢查詢功能用於記錄執行時間超過設定時間的命令,可以通過配置檔案配置需要記錄的命令執行時間,單位是毫秒;配置慢查詢日誌的總記錄數,超出這個數會刪除最舊的日誌後,新增一條新記錄。

2、列印和刪除慢查詢日誌可以通過遍歷slowlog連結串列完成,該連結串列的長度就是儲存慢查詢日誌的數量。新的日誌會新增到表頭,這樣以便於如果連結串列長度超出總的長度,刪除最舊的日誌。

——written by linhxx 2017.10.02