用elastic stack來分析下你的redis slowlog

redis是目前最流行的 NoSQL 內(nèi)存數(shù)據(jù)庫擦耀,然而如果在使用過程中出現(xiàn)濫用骚秦、亂用的情況碍舍,很容易發(fā)生性能問題,此時(shí)我們就要去關(guān)注慢查詢?nèi)罩厩海疚膰L試給大家介紹一種通過 elastic stack 來快速分析 redis 慢查詢?nèi)罩镜姆椒ㄠ戮粒M芙o大家提供幫助。

redis slowlog簡介

redis是目前最流行的緩存系統(tǒng)跃脊,因其豐富的數(shù)據(jù)結(jié)構(gòu)和良好的性能表現(xiàn)宇挫,被各大公司廣泛使用。盡管redis性能極佳酪术,但若不注意使用方法器瘪,極容易出現(xiàn)慢查詢,慢查詢多了或者一個(gè)20s的慢查詢會導(dǎo)致操作隊(duì)列(redis是單進(jìn)程)堵塞绘雁,最終引起雪崩甚至整個(gè)服務(wù)不可用橡疼。對于慢查詢語句,redis提供了相關(guān)的配置和命令庐舟。
配置有兩個(gè):slowlog-log-slower-thanslowlog-max-len欣除。slowlog-log-slower-than是指當(dāng)命令執(zhí)行時(shí)間(不包括排隊(duì)時(shí)間)超過該時(shí)間時(shí)會被記錄下來,單位為微秒挪略,比如通過下面的命令历帚,就可以記錄執(zhí)行時(shí)長超過20ms的命令了。

config set slowlog-log-slower-than 20000

slowlog-max-len是指redis可以記錄的慢查詢命令的總數(shù)杠娱,比如通過下面的命令挽牢,就可以記錄最近100條慢查詢命令了。

config set slowlog-max-len 100

操作慢查詢的命令有兩個(gè):slowlog get [len]slowlog reset摊求。slowlog get [len]命令獲取指定長度的慢查詢列表禽拔。

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"

上面返回了兩個(gè)慢查詢命令,其中每行的含義如下:

  1. 第一行是一個(gè)慢查詢id。該id是自增的奏赘,只有在 redis server 重啟時(shí)該id才會重置寥闪。
  2. 第二行是慢查詢命令執(zhí)行的時(shí)間戳
  3. 第三行是慢查詢命令執(zhí)行耗時(shí),單位為微秒
  4. 第四行是慢查詢命令的具體內(nèi)容磨淌。

slowlog reset命令是清空慢日志隊(duì)列疲憋。

elastic stack

elastic stack是elastic公司的一系列軟件產(chǎn)品,包括elasticsearch梁只、kibana缚柳、logstash、beats等搪锣,感興趣的可以去官網(wǎng)看各個(gè)產(chǎn)品的詳細(xì)介紹秋忙,此次不再做詳細(xì)的講解。本次分析過程中构舟,我們會用到elasticsearch灰追、kibanabeats三款產(chǎn)品。elasticsearch用來存儲解析后的redis slowlog狗超,kibana用于圖形化分析弹澎,beats用于收集redis slowlog。
這里著重講一下beats努咐,它是一系列輕量級的數(shù)據(jù)收集產(chǎn)品統(tǒng)稱苦蒿,目前官方提供了filebeatpacketbeat渗稍、heartbeat佩迟、metricbeat等,可以用來收集日志文件竿屹、網(wǎng)絡(luò)包报强、心跳包、各類指標(biāo)數(shù)據(jù)等拱燃。像我們這次要收集的redis slowlog秉溉,官方還沒有提供相關(guān)工具,需要我們自己實(shí)現(xiàn)扼雏,但借助beats的一系列腳手架工具坚嗜,我們可以方便快速的創(chuàng)建自己的rsbeat---redis slowlog beat夯膀。

rsbeat原理簡介

接下來我們先講解一下rsbeat的實(shí)現(xiàn)原理诗充,一圖勝千言,我們先來看下它的工作流诱建。

rsbeat工作流

我們由下往上分析:

  1. 最下面是我們要分析的redis server列表
  2. 再往上便是rsbeat蝴蜓,它會與這些redis server建立連接并定期去拉取 slowlog
  3. 在啟動時(shí),rsbeat會發(fā)送下面的命令到每一臺redis server茎匠,來完成slowlog的配置格仲,這里設(shè)置記錄最近執(zhí)行時(shí)長超過20ms的500條命令。
config set slowlog-log-slower-than 20000
config set slowlog-max-len 500
slowlog reset
  1. 然后rsbeat會定時(shí)去拉取每臺redis server的慢查詢命令
slowlog get 500
slowlog reset

注意之類slowlog reset是因?yàn)榇舜我呀?jīng)將所有的慢日志都取出了诵冒,下次獲取時(shí)取最新生成的凯肋,防止重復(fù)計(jì)算。

  1. rsbeat將解析的慢日志發(fā)布到elasticsearch中進(jìn)行存儲
  2. 通過kibana進(jìn)行slowlog的圖形化分析

rsbeat的整個(gè)工作流到這里已經(jīng)介紹完畢了汽馋,是不是很簡單呢侮东?下面我們來簡單看一下rsbeat的核心代碼實(shí)現(xiàn)。

rsbeat核心代碼講解

rsbeat已經(jīng)在github上開源了豹芯,感興趣的同學(xué)可以自己去下下來使用悄雅。下面我們分析的代碼位于beater/rsbeat.go,這也是rsbeat的核心文件铁蹈。

func poolInit(server string, slowerThan int) *redis.Pool {
    return &redis.Pool{
        MaxIdle:     3,
        MaxActive:   3,
        IdleTimeout: 240 * time.Second,
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp", server, redis.DialConnectTimeout(3*time.Second), redis.DialReadTimeout(3*time.Second))
            if err != nil {
                logp.Err("redis: error occurs when connect %v", err.Error())
                return nil, err
            }
            c.Send("MULTI")
            c.Send("CONFIG", "SET", "slowlog-log-slower-than", slowerThan)
            c.Send("CONFIG", "SET", "slowlog-max-len", 500)
            c.Send("SLOWLOG", "RESET")
            r, err := c.Do("EXEC")

            if err != nil {
                logp.Err("redis: error occurs when send config set %v", err.Error())
                return nil, err
            }

            logp.Info("redis: config set %v", r)
            return c, err
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            _, err := c.Do("PING")
            logp.Info("redis: PING")
            return err
        },
    }
}

poolInit方法是rsbeat初始化時(shí)進(jìn)行的操作宽闲,這里也就是發(fā)送slowlog配置的地方,代碼很簡單握牧,就不展開解釋了容诬。

func (bt *Rsbeat) redisc(beatname string, init bool, c redis.Conn, ipPort string) {
    defer c.Close()
    logp.Info("conn:%v", c)

    c.Send("SLOWLOG", "GET")
    c.Send("SLOWLOG", "RESET")
    logp.Info("redis: slowlog get. slowlog reset")

    c.Flush()
    reply, err := redis.Values(c.Receive()) // reply from GET
    c.Receive()                             // reply from RESET

    logp.Info("reply len: %d", len(reply))

    for _, i := range reply {
        rp, _ := redis.Values(i, err)
        var itemLog itemLog
        var args []string
        redis.Scan(rp, &itemLog.slowId, &itemLog.timestamp, &itemLog.duration, &args)
        argsLen := len(args)
        if argsLen >= 1 {
            itemLog.cmd = args[0]
        }
        if argsLen >= 2 {
            itemLog.key = args[1]
        }
        if argsLen >= 3 {
            itemLog.args = args[2:]
        }
        logp.Info("timestamp is: %d", itemLog.timestamp)
        t := time.Unix(itemLog.timestamp, 0).UTC()

        event := common.MapStr{
            "type":           beatname,
            "@timestamp":     common.Time(time.Now()),
            "@log_timestamp": common.Time(t),
            "slow_id":        itemLog.slowId,
            "cmd":            itemLog.cmd,
            "key":            itemLog.key,
            "args":           itemLog.args,
            "duration":       itemLog.duration,
            "ip_port":        ipPort,
        }

        bt.client.PublishEvent(event)
    }
}

redisc方法實(shí)現(xiàn)了定時(shí)從redis server拉取最新的slowlog列表,并將它們轉(zhuǎn)化為elasticsearch中可以存儲的數(shù)據(jù)后我碟,發(fā)布到elasticsearch中放案。這里重點(diǎn)說下每一個(gè)字段的含義:

  1. @timestamp是指當(dāng)前時(shí)間戳。
  2. @log_timestamp是指慢日志命令執(zhí)行的時(shí)間戳矫俺。
  3. slow_id是該慢日志的id吱殉。
  4. cmd是指執(zhí)行的 redis 命令,比如sadd厘托、scard等等友雳。
  5. key是指redis key的名稱
  6. args是指 redis 命令的其他參數(shù),通過 cmd铅匹、key押赊、args我們可以完整還原執(zhí)行的redis命令。
  7. duration是指redis命令執(zhí)行的具體時(shí)長包斑,單位是微秒流礁。
  8. ip_port是指發(fā)生命令的 redis server 地址。

有了這些字段罗丰,我們就可以用kibana來愉快的進(jìn)行可視化數(shù)據(jù)分析了神帅。

Kibana圖形化分析slowlog

Kibana提供了非常方便的數(shù)據(jù)分析操作,這里不展開解釋了萌抵,感興趣的可以自行去學(xué)習(xí)找御,這里直接上圖元镀,看下最終的分析結(jié)果。

列表詳情頁
時(shí)間段自由指定
查看慢日志按照時(shí)間的分布情況

上圖可以看到最近有一個(gè)很明顯的數(shù)量減少霎桅,原因是我們解決了相關(guān)的慢查詢栖疑。

按慢查詢數(shù)目來查看cmd分布和key分布
按慢查詢時(shí)長來查看cmd分布和key分布
表格呈現(xiàn)慢查詢的具體命令

看完上面的截圖,有沒有心動滔驶,想親自操刀試一下遇革?Kibana操作起來非常簡單,尤其對于程序員來講揭糕,使用起來得心應(yīng)手澳淑。趕緊下載rsbeat下來自己試一下吧!

總結(jié)

隨著 elastic stack 的發(fā)展插佛,其使用門檻越來越低杠巡,我認(rèn)為目前所有的有志于做數(shù)據(jù)分析的工程師都應(yīng)該了解和掌握它的用法。有了它的幫助雇寇,你可以以極快的速度搭建起自己的一套免費(fèi)強(qiáng)大的數(shù)據(jù)分析軟件氢拥,它的優(yōu)點(diǎn)包括但不限于下面提到的:

  1. 數(shù)據(jù)源任意且自定制。只要你能將數(shù)據(jù)讀取出來并存儲到elasticsearch中即可分析锨侯。
  2. 支持海量數(shù)據(jù)分析嫩海。得益于elastic多年的迅猛發(fā)展,其產(chǎn)品已經(jīng)非常成熟囚痴,上TB的數(shù)據(jù)都可以輕松應(yīng)對存儲與分析叁怪。有了它,你就可以舍棄數(shù)據(jù)一多就卡頓的excel了深滚。
  3. 強(qiáng)大的開源社區(qū)支持奕谭。elastic產(chǎn)品的迅猛發(fā)展離不開開源社區(qū)的支持,你只要在社區(qū)中提出自己的問題或者需求痴荐,總會有人即時(shí)給你答復(fù)和建議血柳。如果你有一定的開發(fā)能力,那么完全可以按照自己的想法來折騰生兆。

別再看了难捌,趕緊去自己動手實(shí)踐下吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸦难,一起剝皮案震驚了整個(gè)濱河市根吁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌合蔽,老刑警劉巖击敌,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辈末,居然都是意外死亡愚争,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門挤聘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轰枝,“玉大人,你說我怎么就攤上這事组去“霸桑” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵从隆,是天一觀的道長诚撵。 經(jīng)常有香客問我,道長键闺,這世上最難降的妖魔是什么寿烟? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮辛燥,結(jié)果婚禮上筛武,老公的妹妹穿的比我還像新娘。我一直安慰自己挎塌,他們只是感情好徘六,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著榴都,像睡著了一般待锈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘴高,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天竿音,我揣著相機(jī)與錄音,去河邊找鬼拴驮。 笑死谍失,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的莹汤。 我是一名探鬼主播快鱼,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纲岭!你這毒婦竟也來了抹竹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤止潮,失蹤者是張志新(化名)和其女友劉穎窃判,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喇闸,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袄琳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年询件,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唆樊。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宛琅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逗旁,到底是詐尸還是另有隱情嘿辟,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布片效,位于F島的核電站红伦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淀衣。R本人自食惡果不足惜昙读,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膨桥。 院中可真熱鬧箕戳,春花似錦、人聲如沸国撵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽介牙。三九已至壮虫,卻和暖如春抛杨,著一層夾襖步出監(jiān)牢的瞬間妄均,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工滨攻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留线得,地道東北人饶唤。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像贯钩,于是被迫代替她去往敵國和親募狂。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容