1. 程式人生 > >將redis slowlog存入MySQL

將redis slowlog存入MySQL

【需求】
redis slowlog是排查效能問題關鍵監控指標。它是記錄redis queries執行時間超時特定閥值的系統。這類慢查詢命令被儲存到redis伺服器的一個定長佇列,最多儲存slowlog-max-len(預設128)個慢查詢命令。當慢查詢命令達到128個時,新產生的慢查詢被加入前,會從佇列中刪除最舊的慢查詢命令。雖然可以修改slowlog儲存條數,但是redis屬於記憶體資料庫,儲存的slowlog越多佔用記憶體越大,而記憶體又非常昂貴,因此需要定期將redis的slowlog轉儲到MySQL裡。

【分析】

redis slowlog格式如下所示

redis 127.0.0.1:6379> slowlog get 2
1) 1) (integer) 14
   2) (integer) 1309448221
   3) (integer) 15
   4) 1) "ping"
2) 1) (integer) 13
   2) (integer) 1309448128
   3) (integer) 30
   4) 1) "slowlog"
      2) "get"
      3) "100"

第1) 2) 3)欄位行數都是固定的,就一行,但是第4)個欄位行數是不固定的,可能包括1行,也可能包括n行,那麼如何去獲取每條慢日誌的開始行號和結束行號呢?或者說如何擷取每一條slowlog呢?

一種思路:
<1>將所有慢日誌取出來輸出到臨時檔案
<2>通過slowlog len獲取慢日誌條數
<3>通過slowlog get 1獲取第1條慢日誌的行數,假如第1條慢日誌一共有6行,那麼第1條慢日誌就是檔案中的(1-6)行
<4>獲取第2條慢日誌時,起始行就是7,結束行就是(slowlog get 2|wc -l),那麼第2條慢日誌就是檔案中的[7-(slowlog get 2|wc -l)]行
<5>其它慢日誌以此類推計算即可,最後存入MySQL

【shell實現】

下面是用shell實現的擷取slowlog的核心程式碼

slowlog_len=`redis-cli -h $ip -p $port slowlog len`

if [ $slowlog_len -eq 0 ];then
    exit
else
    redis-cli -h $ip -p $port slowlog get $slowlog_len > $TMP1
    start_line=1
    for ((i=1;i<="$slowlog_len";i++))
    do
        end_line=`redis-cli -h $ip -p $port slowlog get $i|wc -l`
        for j in {1..4}
        do
            if [ $j -eq 4 ];then
                info_4=`sed -n "${start_line},${end_line}p" $TMP1`
            else
                eval info_$j=`sed -n "${start_line}p" $TMP1`
                start_line=`expr $start_line + 1`
            fi
        done
        start_line=`expr $end_line + 1`
        exec_time=`date -d "@$info" +"%Y-%m-%d %H:%M:%S"`
        mysql -u $user -p$pass -h $db_host -P $db_port $db -N -e "insert into $db_slow(hostip,port,log_num,log_time,exec_time,command_info) lines(\"$ip\",$port,$info_1,\"$exec_time\",$info_3,\"$info_4\");"
        i=`expr $i + 1`
    done
fi
redis-cli -h $ip -p $port slowlog reset

【侷限】

此方案存在一定的侷限性,因為每次通過slowlog get i|wc -l獲取時都要耗費時間,雖然這個時間很短,假如在這個時間段內有新的slowlog進入,很可能造成獲取的slowlog行號錯亂,因為不確定每條slowlog的行數。當然也可以通過儲存slowlog到檔案的方式儲存慢日誌。如果各位網友有更好的解決方案煩請告知下,多謝。