日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis 慢查询日志

發布時間:2024/2/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis 慢查询日志 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

結論:

  • Redis 的慢查詢日志功能用于記錄執行時間超過指定時長的命令。
  • Redis 服務器將所有的慢查詢日志保存在服務器狀態的?slowlog?鏈表中, 每個鏈表節點都包含一個?slowlogEntry?結構, 每個?slowlogEntry?結構代表一條慢查詢日志。
  • 打印和刪除慢查詢日志可以通過遍歷?slowlog?鏈表來完成。
  • slowlog?鏈表的長度就是服務器所保存慢查詢日志的數量。
  • 新的慢查詢日志會被添加到?slowlog?鏈表的表頭, 如果日志的數量超過?slowlog-max-len?選項的值, 那么多出來的日志會被刪除。

原文轉載自:

http://redisbook.com/index.html

慢查詢日志

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

服務器配置有兩個和慢查詢日志相關的選項:

  • slowlog-log-slower-than?選項指定執行時間超過多少微秒(1?秒等于?1,000,000?微秒)的命令請求會被記錄到日志上。

    舉個例子, 如果這個選項的值為?100?, 那么執行時間超過?100?微秒的命令就會被記錄到慢查詢日志; 如果這個選項的值為?500?, 那么執行時間超過?500?微秒的命令就會被記錄到慢查詢日志; 諸如此類。

  • slowlog-max-len?選項指定服務器最多保存多少條慢查詢日志。

    服務器使用先進先出的方式保存多條慢查詢日志: 當服務器儲存的慢查詢日志數量等于?slowlog-max-len?選項的值時, 服務器在添加一條新的慢查詢日志之前, 會先將最舊的一條慢查詢日志刪除。

    舉個例子, 如果服務器?slowlog-max-len?的值為?100?, 并且假設服務器已經儲存了?100?條慢查詢日志, 那么如果服務器打算添加一條新日志的話, 它就必須先刪除目前保存的最舊的那條日志, 然后再添加新日志。

讓我們來看一個慢查詢日志功能的例子, 首先用?CONFIG_SET?命令將?slowlog-log-slower-than?選項的值設為?0?微秒, 這樣 Redis 服務器執行的任何命令都會被記錄到慢查詢日志中, 接著將?slowlog-max-len?選項的值設為?5?, 讓服務器最多只保存?5?條慢查詢日志:

redis> CONFIG SET slowlog-log-slower-than 0 OKredis> CONFIG SET slowlog-max-len 5 OK

接著, 我們用客戶端發送幾條命令請求:

redis> SET msg "hello world" OKredis> SET number 10086 OKredis> SET database "Redis" OK

然后使用?SLOWLOG GET?命令查看服務器所保存的慢查詢日志:

redis> SLOWLOG GET 1) 1) (integer) 4 # 日志的唯一標識符(uid)2) (integer) 1378781447 # 命令執行時的 UNIX 時間戳3) (integer) 13 # 命令執行的時長,以微秒計算4) 1) "SET" # 命令以及命令參數2) "database"3) "Redis" 2) 1) (integer) 32) (integer) 13787814393) (integer) 104) 1) "SET"2) "number"3) "10086" 3) 1) (integer) 22) (integer) 13787814363) (integer) 184) 1) "SET"2) "msg"3) "hello world" 4) 1) (integer) 12) (integer) 13787814253) (integer) 114) 1) "CONFIG"2) "SET"3) "slowlog-max-len"4) "5" 5) 1) (integer) 02) (integer) 13787814153) (integer) 534) 1) "CONFIG"2) "SET"3) "slowlog-log-slower-than"4) "0"

如果這時再執行一條?SLOWLOG GET?命令, 那么我們將看到, 上一次執行的?SLOWLOG GET?命令已經被記錄到了慢查詢日志中, 而最舊的、編號為?0?的慢查詢日志已經被刪除, 服務器的慢查詢日志數量仍然為?5?條:

redis> SLOWLOG GET 1) 1) (integer) 52) (integer) 13787815213) (integer) 614) 1) "SLOWLOG"2) "GET" 2) 1) (integer) 42) (integer) 13787814473) (integer) 134) 1) "SET"2) "database"3) "Redis" 3) 1) (integer) 32) (integer) 13787814393) (integer) 104) 1) "SET"2) "number"3) "10086" 4) 1) (integer) 22) (integer) 13787814363) (integer) 184) 1) "SET"2) "msg"3) "hello world" 5) 1) (integer) 12) (integer) 13787814253) (integer) 114) 1) "CONFIG"2) "SET"3) "slowlog-max-len"4) "5"

SLOWLOG GET N 命令可以查看redis保存的指定條數的慢查詢日志

參數N可以指定條數

127.0.0.1:6379> slowlog get 3 1) 1) (integer) 7452) (integer) 15635253743) (integer) 624) 1) "slowlog"2) "get"5) "127.0.0.1:59328"6) "" 2) 1) (integer) 7442) (integer) 15635096293) (integer) 184) 1) "keys"2) "back:realtime:2019-07-19_*"5) "127.0.0.1:50458"6) "" 3) 1) (integer) 7432) (integer) 15635096293) (integer) 24) 1) "ping"5) "127.0.0.1:50458"6) ""

獲取慢查詢日志列表當前長度

??? slowlog len

127.0.0.1:6379> slowlog len (integer) 5

慢查詢記錄的保存

服務器狀態中包含了幾個和慢查詢日志功能有關的屬性:

struct redisServer {// ...// 下一條慢查詢日志的 IDlong long slowlog_entry_id;// 保存了所有慢查詢日志的鏈表list *slowlog;// 服務器配置 slowlog-log-slower-than 選項的值long long slowlog_log_slower_than;// 服務器配置 slowlog-max-len 選項的值unsigned long slowlog_max_len;// ...};

slowlog_entry_id?屬性的初始值為?0?, 每當創建一條新的慢查詢日志時, 這個屬性的值就會用作新日志的?id?值, 之后程序會對這個屬性的值增一。

比如說, 在創建第一條慢查詢日志時,?slowlog_entry_id?的值?0?會成為第一條慢查詢日志的 ID , 而之后服務器會對這個屬性的值增一; 當服務器再創建新的慢查詢日志的時候,?slowlog_entry_id?的值?1?就會成為第二條慢查詢日志的 ID , 然后服務器再次對這個屬性的值增一, 以此類推。

slowlog?鏈表保存了服務器中的所有慢查詢日志, 鏈表中的每個節點都保存了一個?slowlogEntry?結構, 每個?slowlogEntry?結構代表一條慢查詢日志:

typedef struct slowlogEntry {// 唯一標識符long long id;// 命令執行時的時間,格式為 UNIX 時間戳time_t time;// 執行命令消耗的時間,以微秒為單位long long duration;// 命令與命令參數robj **argv;// 命令與命令參數的數量int argc;} slowlogEntry;

舉個例子, 對于以下慢查詢日志來說:

1) (integer) 3 2) (integer) 1378781439 3) (integer) 10 4) 1) "SET"2) "number"3) "10086"

圖 23-1 展示的就是該日志所對應的?slowlogEntry?結構。

圖 23-2 展示了服務器狀態中, 和慢查詢功能有關的屬性:

  • slowlog_entry_id?的值為?6?, 表示服務器下條慢查詢日志的?id?值將為?6?。
  • slowlog?鏈表包含了?id?為?5?至?1?的慢查詢日志, 最新的?5?號日志排在鏈表的表頭, 而最舊的?1?號日志排在鏈表的表尾, 這表明?slowlog?鏈表是使用插入到表頭的方式來添加新日志的。
  • slowlog_log_slower_than?記錄了服務器配置?slowlog-log-slower-than?選項的值?0?, 表示任何執行時間超過?0?微秒的命令都會被慢查詢日志記錄。
  • slowlog-max-len?屬性記錄了服務器配置?slowlog-max-len?選項的值?5?, 表示服務器最多儲存五條慢查詢日志。

注意

因為版面空間不足的緣故, 所以圖 23-2 展示的各個?slowlogEntry?結構都省略了?argv?數組。

慢查詢日志的閱覽和刪除

弄清楚了服務器狀態的?slowlog?鏈表的作用之后, 我們可以用以下偽代碼來定義查看日志的?SLOWLOG GET?命令:

def SLOWLOG_GET(number=None):# 用戶沒有給定 number 參數# 那么打印服務器包含的全部慢查詢日志if number is None:number = SLOWLOG_LEN()# 遍歷服務器中的慢查詢日志for log in redisServer.slowlog:if number <= 0:# 打印的日志數量已經足夠,跳出循環breakelse:# 繼續打印,將計數器的值減一number -= 1# 打印日志printLog(log)

查看日志數量的?SLOWLOG LEN?命令可以用以下偽代碼來定義:

def SLOWLOG_LEN():# slowlog 鏈表的長度就是慢查詢日志的條目數量return len(redisServer.slowlog)

另外, 用于清除所有慢查詢日志的?SLOWLOG RESET?命令可以用以下偽代碼來定義:

def SLOWLOG_RESET():# 遍歷服務器中的所有慢查詢日志for log in redisServer.slowlog:# 刪除日志deleteLog(log)

添加新日志

在每次執行命令的之前和之后, 程序都會記錄微秒格式的當前 UNIX 時間戳, 這兩個時間戳之間的差就是服務器執行命令所耗費的時長, 服務器會將這個時長作為參數之一傳給?slowlogPushEntryIfNeeded?函數, 而?slowlogPushEntryIfNeeded?函數則負責檢查是否需要為這次執行的命令創建慢查詢日志, 以下偽代碼展示了這一過程:

# 記錄執行命令前的時間 before = unixtime_now_in_us()# 執行命令 execute_command(argv, argc, client)# 記錄執行命令后的時間 after = unixtime_now_in_us()# 檢查是否需要創建新的慢查詢日志 slowlogPushEntryIfNeeded(argv, argc, before-after)

slowlogPushEntryIfNeeded?函數的作用有兩個:

  • 檢查命令的執行時長是否超過?slowlog-log-slower-than?選項所設置的時間, 如果是的話, 就為命令創建一個新的日志, 并將新日志添加到?slowlog?鏈表的表頭。
  • 檢查慢查詢日志的長度是否超過?slowlog-max-len?選項所設置的長度, 如果是的話, 那么將多出來的日志從?slowlog?鏈表中刪除掉。
  • 以下是?slowlogPushEntryIfNeeded?函數的實現代碼:

    void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) {// 慢查詢功能未開啟,直接返回if (server.slowlog_log_slower_than < 0) return;// 如果執行時間超過服務器設置的上限,那么將命令添加到慢查詢日志if (duration >= server.slowlog_log_slower_than)// 新日志添加到鏈表表頭listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration));// 如果日志數量過多,那么進行刪除while (listLength(server.slowlog) > server.slowlog_max_len)listDelNode(server.slowlog,listLast(server.slowlog)); }

    函數中的大部分代碼我們已經介紹過了, 唯一需要說明的是?slowlogCreateEntry?函數: 該函數根據傳入的參數, 創建一個新的慢查詢日志, 并將?redisServer.slowlog_entry_id?的值增一。

    舉個例子, 假設服務器當前保存的慢查詢日志如圖 23-2 所示, 如果我們執行以下命令:

    redis> EXPIRE msg 10086 (integer) 1

    服務器在執行完這個?EXPIRE?命令之后, 就會調用?slowlogPushEntryIfNeeded?函數, 函數將為?EXPIRE?命令創建一條?id?為?6?的慢查詢日志, 并將這條新日志添加到?slowlog?鏈表的表頭, 如圖 23-3 所示。

    注意, 除了?slowlog?鏈表發生了變化之外,?slowlog_entry_id?的值也從?6?變為?7?了。

    之后,?slowlogPushEntryIfNeeded?函數發現, 服務器設定的最大慢查詢日志數目為?5?條, 而服務器目前保存的慢查詢日志數目為?6?條, 于是服務器將?id?為?1?的慢查詢日志刪除, 讓服務器的慢查詢日志數量回到設定好的?5?條。

    刪除操作執行之后的服務器狀態如圖 23-4 所示。

    重點回顧

    • Redis 的慢查詢日志功能用于記錄執行時間超過指定時長的命令。
    • Redis 服務器將所有的慢查詢日志保存在服務器狀態的?slowlog?鏈表中, 每個鏈表節點都包含一個?slowlogEntry?結構, 每個?slowlogEntry?結構代表一條慢查詢日志。
    • 打印和刪除慢查詢日志可以通過遍歷?slowlog?鏈表來完成。
    • slowlog?鏈表的長度就是服務器所保存慢查詢日志的數量。
    • 新的慢查詢日志會被添加到?slowlog?鏈表的表頭, 如果日志的數量超過?slowlog-max-len?選項的值, 那么多出來的日志會被刪除。

    總結

    以上是生活随笔為你收集整理的redis 慢查询日志的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。