redis探针主要是监控redis相关情况,比如内存,连接数等。

原理

1、set log format,支持txt和json两种格式的日志

2、set log level,支持正常的日志级别

3、show version 支持option打印版本

4、解析addr和passwd和alias,这几个参数支持参数配置,也可以重环境变量中获取

Environment         Variables
Name                Description
REDIS_ADDR          Address of Redis node(s)
REDIS_PASSWORD      Password to use when authenticating to Redis
REDIS_ALIAS         Alias name of Redis node(s)
REDIS_FILE          Path to file containing Redis node(s)

5、创建一个Exporter结构体,初始化,将上面的信息传进去,并创建对应的指标,checkkey支持对多数据库的查询

// Exporter implements the prometheus.Exporter interface, and exports Redis metrics.
type Exporter struct {
    redis        RedisHost
    namespace    string
    keys         []dbKeyPair
    keyValues    *prometheus.GaugeVec
    keySizes     *prometheus.GaugeVec
    duration     prometheus.Gauge
    scrapeErrors prometheus.Gauge
    totalScrapes prometheus.Counter
    metrics      map[string]*prometheus.GaugeVec
    metricsMtx   sync.RWMutex
    sync.RWMutex
}


// RedisHost represents a set of Redis Hosts to health check.
type RedisHost struct {
    Addrs     []string
    Passwords []string
    Aliases   []string
}

6、然后调用client_golang的库函数进行数据采集,scrape连接数据库,调用命令,然后解析返回参数。完成监控。

由此可见,redis_exporter只是简单的对redis的单节点进行了监控,并没有对redis的cluster和sentinel进行监控。

sentinel监控

这边需要监控sentinel,这边做一个设计

  • 运行天数

    redis_start_time_seconds{addr="10.37.152.206:26379",alias=""} 1.551058403e+09
    

    这个指标直接解析info信息中的sentinel信息,每次通过执行info命令获取,获取uptime_in_days字段值,设计标签为通用的addr,alias字段。

  • 注册shard数据

    redis_sentinel_masters{addr="10.37.152.206:26379",alias=""} 4
    

    这个指标直接解析info信息中的sentinel信息,每次通过执行info命令获取,获取sentinel_masters字段值,设计标签为通用的addr,alias字段。

  • 正常shard的个数

    redis_sentinel_masters_ok{addr="10.37.152.206:26379",alias=""} 0
    

    这个指标直接解析info信息中的sentinel信息,每次通过执行info命令获取,获取status=ok的个数,设计标签为通用的addr,alias字段。

  • 异常shard的个数

    redis_sentinel_masters_down{addr="10.37.152.206:26379",alias=""} 4
    

    这个指标直接解析info信息中的sentinel信息,每次通过执行info命令获取,获取status=odown的个数,设计标签为通用的addr,alias字段。

  • sentinel的连接数

    redis_sentinel_connects{addr="10.37.152.206:26379",alias=""} 0
    

    这个指标是通过执行netstat命令来统计对应进程的连接数,设计标签为通用的addr,alias字段。

  • 检活

    redis_sentinel_status{addr="10.37.152.206:26379",alias=""} 1
    

    这个指标是通过执行redis PING命令来检测返回的是否是PONG,如果是则为1,否则为0,代表着sentinel的死活状态,设计标签为通用的addr,alias字段。

  • 26379端口检测

    redis_sentinel_port_isalive{addr="10.37.152.206:26379",alias=""} 0
    

    这个指标是通过执行netstat命令来统计对应端口为LiSTEN的数量,1代表端口正在监听,0代表没有监听端口,设计标签为通用的addr,alias字段。

目前探针融合在redis的探针中,可以自动识别sentinel还是redis,然后放回对应的指标,支持多地址混合配置,可以返回所有需要的指标。

连接池

redis探针目前是短连接,在很多场景下,需要改短连接为长连接,可以只使用一个连接来解决这个问题,这个其实适用于长连接使用的场景,然后考虑长连接可能出来大量连接存在的场景,所以最好直接使用连接池,对连接的数量进行限制,这样就可以完美的解决问题。

探针启动直接初始化一个连接池,大小为2,正常使用一个长连接来采集高频率的数据,出现异常,可能会使用到第二个长连接。

验证在高频率的采集下连接数并没有出现增长。

问题

redis自身支持长连接需要设置参数,tcp_keepalive=1,默认是关闭的,所以都是以timeout时间为准,到时间后redis端会关闭连接,所以探针侧就会close_wait,当然这个连接是可以复用的,当重新请求的时候,又会建立连接在连接池上,按着我们每10s才是一次的频率,redis设置的180s的超时时间,基本上不会出现不断短连接的情形。