热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用elasticstack来分析下你的redisslowlog

redis是目前最流行的NoSQL内存数据库,然而如果在使用过程中出现滥用、乱用的情况,很容易发生性能问题,此时我们就要去关注慢查询日志&

redis是目前最流行的 NoSQL 内存数据库,然而如果在使用过程中出现滥用、乱用的情况,很容易发生性能问题,此时我们就要去关注慢查询日志,本文尝试给大家介绍一种通过 elastic stack 来快速分析 redis 慢查询日志的方法,希望能给大家提供帮助。


redis slowlog简介

redis是目前最流行的缓存系统,因其丰富的数据结构和良好的性能表现,被各大公司广泛使用。尽管redis性能极佳,但若不注意使用方法,极容易出现慢查询,慢查询多了或者一个20s的慢查询会导致操作队列(redis是单进程)堵塞,最终引起雪崩甚至整个服务不可用。对于慢查询语句,redis提供了相关的配置和命令。
配置有两个:slowlog-log-slower-thanslowlog-max-lenslowlog-log-slower-than是指当命令执行时间(不包括排队时间)超过该时间时会被记录下来,单位为微秒,比如通过下面的命令,就可以记录执行时长超过20ms的命令了。


 

config set slowlog-log-slower-than 20000

slowlog-max-len是指redis可以记录的慢查询命令的总数,比如通过下面的命令,就可以记录最近100条慢查询命令了。

config set slowlog-max-len 100

操作慢查询的命令有两个:slowlog get [len] 和 slowlog resetslowlog get [len]命令获取指定长度的慢查询列表。

redis 127.0.0.1:6379> slowlog get 2
1) 1) (integer) 142) (integer) 13094482213) (integer) 154) 1) "ping"
2) 1) (integer) 132) (integer) 13094481283) (integer) 304) 1) "slowlog"2) "get"3) "100"

上面返回了两个慢查询命令,其中每行的含义如下:


  1. 第一行是一个慢查询id。该id是自增的,只有在 redis server 重启时该id才会重置。
  2. 第二行是慢查询命令执行的时间戳
  3. 第三行是慢查询命令执行耗时,单位为微秒
  4. 第四行是慢查询命令的具体内容。

slowlog reset命令是清空慢日志队列。


elastic stack

elastic stack是elastic公司的一系列软件产品,包括elasticsearch、kibana、logstash、beats等,感兴趣的可以去官网看各个产品的详细介绍,此次不再做详细的讲解。本次分析过程中,我们会用到elasticsearchkibanabeats三款产品。elasticsearch用来存储解析后的redis slowlog,kibana用于图形化分析,beats用于收集redis slowlog。
这里着重讲一下beats,它是一系列轻量级的数据收集产品统称,目前官方提供了filebeatpacketbeatheartbeatmetricbeat等,可以用来收集日志文件、网络包、心跳包、各类指标数据等。像我们这次要收集的redis slowlog,官方还没有提供相关工具,需要我们自己实现,但借助beats的一系列脚手架工具,我们可以方便快速的创建自己的rsbeat---redis slowlog beat


rsbeat原理简介

接下来我们先讲解一下rsbeat的实现原理,一图胜千言,我们先来看下它的工作流。

我们由下往上分析:


  1. 最下面是我们要分析的redis server列表
  2. 再往上便是rsbeat,它会与这些redis server建立连接并定期去拉取 slowlog
  3. 在启动时,rsbeat会发送下面的命令到每一台redis server,来完成slowlog的配置,这里设置记录最近执行时长超过20ms的500条命令。

config set slowlog-log-slower-than 20000
config set slowlog-max-len 500
slowlog reset

然后rsbeat会定时去拉取每台redis server的慢查询命令

slowlog get 500
slowlog reset

注意之类slowlog reset是因为此次已经将所有的慢日志都取出了,下次获取时取最新生成的,防止重复计算。


  1. rsbeat将解析的慢日志发布到elasticsearch中进行存储
  2. 通过kibana进行slowlog的图形化分析

rsbeat的整个工作流到这里已经介绍完毕了,是不是很简单呢?下面我们来简单看一下rsbeat的核心代码实现。


rsbeat核心代码讲解

rsbeat已经在github上开源了,感兴趣的同学可以自己去下下来使用。下面我们分析的代码位于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初始化时进行的操作,这里也就是发送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 GETc.Receive() // reply from RESETlogp.Info("reply len: %d", len(reply))for _, i := range reply {rp, _ := redis.Values(i, err)var itemLog itemLogvar args []stringredis.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方法实现了定时从redis server拉取最新的slowlog列表,并将它们转化为elasticsearch中可以存储的数据后,发布到elasticsearch中。这里重点说下每一个字段的含义:


  1. @timestamp是指当前时间戳。
  2. @log_timestamp是指慢日志命令执行的时间戳。
  3. slow_id是该慢日志的id。
  4. cmd是指执行的 redis 命令,比如saddscard等等。
  5. key是指redis key的名称
  6. args是指 redis 命令的其他参数,通过 cmdkeyargs我们可以完整还原执行的redis命令。
  7. duration是指redis命令执行的具体时长,单位是微秒。
  8. ip_port是指发生命令的 redis server 地址。

有了这些字段,我们就可以用kibana来愉快的进行可视化数据分析了。


Kibana图形化分析slowlog

Kibana提供了非常方便的数据分析操作,这里不展开解释了,感兴趣的可以自行去学习,这里直接上图,看下最终的分析结果。


查看慢日志按照时间的分布情况
查看慢日志按照时间的分布情况

 

 

上图可以看到最近有一个很明显的数量减少,原因是我们解决了相关的慢查询。


按慢查询数目来查看cmd分布和key分布
按慢查询数目来查看cmd分布和key分布

                                                        


按慢查询时长来查看cmd分布和key分布
按慢查询时长来查看cmd分布和key分布

 


表格呈现慢查询的具体命令
表格呈现慢查询的具体命令

 

 

看完上面的截图,有没有心动,想亲自操刀试一下?Kibana操作起来非常简单,尤其对于程序员来讲,使用起来得心应手。赶紧下载rsbeat下来自己试一下吧!


总结

随着 elastic stack 的发展,其使用门槛越来越低,我认为目前所有的有志于做数据分析的工程师都应该了解和掌握它的用法。有了它的帮助,你可以以极快的速度搭建起自己的一套免费强大的数据分析软件,它的优点包括但不限于下面提到的:


  1. 数据源任意且自定制。只要你能将数据读取出来并存储到elasticsearch中即可分析。
  2. 支持海量数据分析。得益于elastic多年的迅猛发展,其产品已经非常成熟,上TB的数据都可以轻松应对存储与分析。有了它,你就可以舍弃数据一多就卡顿的excel了。
  3. 强大的开源社区支持。elastic产品的迅猛发展离不开开源社区的支持,你只要在社区中提出自己的问题或者需求,总会有人即时给你答复和建议。如果你有一定的开发能力,那么完全可以按照自己的想法来折腾。



作者:rockybean
链接:https://www.jianshu.com/p/f0878aaacf77
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


推荐阅读
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
  • 本文详细介绍了一种通过MySQL弱口令漏洞在Windows操作系统上获取SYSTEM权限的方法。该方法涉及使用自定义UDF DLL文件来执行任意命令,从而实现对远程服务器的完全控制。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • Python实现斐波那契数列的方法与优化
    本文详细介绍了如何在Python中编写斐波那契数列,并探讨了不同的实现方法及其性能优化。通过递归、迭代和公式法,读者可以了解每种方法的优缺点,并选择最适合自己的实现方式。 ... [详细]
  • 题目描述:给定一个N*M的网格,初始时网格中有k个芯片,每个芯片的位置已知。玩家可以在每一步操作中将所有芯片沿同一方向移动一格。如果芯片到达边界,则保持不动。目标是通过一系列操作,使每个芯片依次访问指定的目标位置。 ... [详细]
  • ZooKeeper集群脑裂问题及其解决方案
    本文深入探讨了ZooKeeper集群中可能出现的脑裂问题,分析其成因,并提供了多种有效的解决方案,确保集群在高可用性环境下的稳定运行。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • 基于Node.js、Express、MongoDB和Socket.io的实时聊天应用开发
    本文详细介绍了使用Node.js、Express、MongoDB和Socket.io构建的实时聊天应用程序。涵盖项目结构、技术栈选择及关键依赖项的配置。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本文详细介绍了在使用 SmartUpload 组件进行文件上传时,如何正确配置和查找文件保存路径。通过具体的代码示例和步骤说明,帮助开发者快速解决上传路径配置的问题。 ... [详细]
author-avatar
霸气的玫琳_801
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有