【最佳实践】Elastic stack 实时分析下你的Redis slowlog

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

作者介绍

魏彬,普翔科技 CTO,开源软件爱好者,中国第一位 Elastic 认证工程师,《Elastic日报》和 《ElasticTalk》社区项目发起人,被 elastic 中国公司授予 2019 年度合作伙伴架构师特别贡献奖。对 Elasticsearch、Kibana、Beats、Logstash、Grafana 等开源软件有丰富的实践经验,为零售、金融、保险、证券、科技等众多行业的客户提供过咨询和培训服务,帮助客户在实际业务中找准开源软件的定位,实现从 0 到 1 的落地、从 1 到 N 的拓展,产生实际的业务价值。

Redis slowlog简介

Redis 是目前最流行的缓存系统,因其丰富的数据结构和良好的性能表现,被各大公司广泛使用。尽管 redis 性能极佳,但若不注意使用方法,极容易出现慢查询,慢查询多了或者一个 20s 的慢查询会导致操作队列( redis 是单进程)堵塞,最终引起雪崩甚至整个服务不可用。对于慢查询语句,redis 提供了相关的配置和命令。

配置有两个:slowlog-log-slower-than 和 slowlog-max-len。slowlog-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 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"

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

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

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

Elastic Stack

Elastic Stack 是 Elastic 公司 的一系列开源软件产品,包括 Elasticsearch、Kibana、Logstash、Beats 等,当然你也可以选择阿里云 Elasticsearch,不仅100%兼容开源,同时拥有完整云上Elastic Stack生态,并提供免费 X-Pack(价值6000美金);在本次分析过程中,我们会用到 elasticsearch、kibana 和 beats 三款产品。elasticsearch用来存储解析后的 redis slowlog,kibana 用于图形化分析,beats 用于收集 redis slowlog。

这里着重讲一下 beats,它是一系列轻量级的数据收集产品统称,目前官方提供了 filebeat、packetbeat、heartbeat、metricbeat 等,可以用来收集日志文件、网络包、心跳包、各类指标数据等。像我们这次要收集的redis slowlog,官方还没有提供相关工具,需要我们自己实现,但借助beats的一系列脚手架工具,我们可以方便快速的创建自己的 rsbeat---redis slowlog beat。

rsbeat原理简介

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

image.png


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

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

slowlog get 500
slowlog reset

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

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

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

sbeat核心代码讲解

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 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 方法实现了定时从 redis server 拉取最新的 slowlog 列表,并将它们转化为 elasticsearch 中可以存储的数据后,发布到 elasticsearch 中。这里重点说下每一个字段的含义:

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

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

Kibana 图形化分析 slowlog

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

image.png


列表详情页

image.png


时间段自由指定

image.png


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

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

image.png


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

image.png


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

image.png


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

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

总结

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

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

别再看了,赶紧去自己动手实践下吧!

声明:本文由原文《用 elastic stack 来分析下你的 redis slowlog》作者“魏彬”授权转载,对未经许可擅自使用者,保留追究其法律责任的权利。


image.png

阿里云Elastic Stack】100%兼容开源ES,独有9大能力,提供免费X-pack服务(单节点价值$6000)

相关活动


更多折扣活动,请访问阿里云 Elasticsearch 官网

阿里云 Elasticsearch 商业通用版,1核2G ,SSD 20G首月免费
阿里云 Logstash 2核4G首月免费


image.png

image.png

相关文章
|
4月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
|
4月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
641 6
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
335 1
|
JSON NoSQL Java
从Redis到Tair:开源工具的最佳实践
《从Redis到Tair:开源工具的最佳实践》介绍了Redis闭源后Valkey社区的成立及其兼容性测试、性能测试、数据迁移与校验、客户端接入最佳实践,以及Tair的开源模块。内容涵盖Redis闭源背景、阿里云在Valkey社区中的贡献、Tair与Redis的兼容性测试工具(如resp-compatibility)、性能测试工具(如RESP-Benchmark)、数据迁移工具(如Redis Shake)及数据校验工具。此外,还详细介绍了TairHash和TairDoc两个开源模块的应用场景,帮助用户更好地理解和使用这些工具。
733 4
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
284 5
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
2915 3
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。
1114 4
|
缓存 NoSQL 网络协议
【Azure Redis 缓存】Azure Redis Cluster 在增加分片数时失败分析
【Azure Redis 缓存】Azure Redis Cluster 在增加分片数时失败分析
149 0
|
9月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?

热门文章

最新文章