Redis监控汇总一

一、概述

对于任何运行在生产环境的软件,监控都是必不可少的一个环节。

我们在分析各种工具之前,先来看下redis都有哪些指标需要关注和监控。

Redis监控的用途有两种,一种是类似于zabbix,监控指标并用来报警,另外一种就是出现问题时,快速定位问题使用的。

各个数据库db的key数量、redis存储的key总数量 
redis内存使用状况 
redis使用CPU状况 
redis当前的QPS 
redis中数据请求的命中率 
key的过期和逐出情况 
当前redis的客户端情况 
Redis网络出入带宽 
redis客户端发起的命令排行(TOP 10 命令) 
主从、RDB和AOF持久化及其他

redis自带了redis-cli工具,基本上可以覆盖以上一些指标,但是有很多指标需要经过进一步处理才可以显示。我们后面会逐个分析。

二、redis-cli命令

redis-cli是redis自带的客户端工具,可以执行丰富的redis命令,当然也提供了很多的监控数据。

2.1 info命令

info命令是redis最基本的监控数据

[root@localhost ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> info
# Server
redis_version:3.2.9 # Redis 服务器版本
redis_git_sha1:3e69191b # Git SHA1
redis_git_dirty:0 # Git dirty flag
redis_build_id:d5dcf1b56df95e23 # Build id
redis_mode:standalone # 单机or集群
os:Linux 3.10.0-514.2.2.el7.x86_64 x86_64 # Redis 服务器的宿主操作系统
arch_bits:64 # 架构(32 或 64 位)  
multiplexing_api:epoll # Redis 所使用的事件处理机制 
gcc_version:4.8.5 # 编译 Redis 时所使用的 GCC 版本 
process_id:24342 # 服务器进程的 PID
run_id:1fb25b435e4bb907db135ef86d8be26f6494a5bf # Redis 服务器的随机标识符
tcp_port:6379 # TCP/IP 监听端口 
uptime_in_seconds:8713721 # 运行秒数
uptime_in_days:100 # 运行天数
hz:10
lru_clock:248381 # 以分钟为单位进行自增的时钟,用于 LRU 管理
executable:/data0/gowork/src/github.com/CodisLabs/codis/admin/../bin/codis-server # 执行命令
config_file:/data0/gowork/src/github.com/CodisLabs/codis/admin/../config/redis.conf # 配置文件

# Clients
connected_clients:18 # 已连接客户端的数量
client_longest_output_list:0 # 当前连接的客户端当中,最长的输出列表
client_biggest_input_buf:0 # 当前连接的客户端当中,最大输入缓存
blocked_clients:0 # 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量

# Memory
used_memory:2927088 # 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human:2.79M # 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss:8982528 # 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_rss_human:8.57M
used_memory_peak:3561832 # Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human:3.40M # 以人类可读的格式返回 Redis 的内存消耗峰值
total_system_memory:1040805888
total_system_memory_human:992.59M
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:3.07 # used_memory_rss 和 used_memory 之间的比率
mem_allocator:jemalloc-4.0.3 # 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。

# 在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。 
# 当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
# 内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。 当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
# 当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
# 如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory的值可能和操作系统显示的 Redis 内存占用并不一致。
# 查看 used_memory_peak 的值可以验证这种情况是否发生。  

# Persistence
loading:0 # 是否正在 load of a dump file 的标记 
rdb_changes_since_last_save:0 # 自从上次save后rdb change的数量 
rdb_bgsave_in_progress:0 # 是否正常进行bgsave 
rdb_last_save_time:1501484100 # 上次save的unix时间戳
rdb_last_bgsave_status:ok # rdb上次bgsave的状态
rdb_last_bgsave_time_sec:-1 # 上次bgsave的持续时间(s)
rdb_current_bgsave_time_sec:-1 # 正在bgsave的持续时间(s)
aof_enabled:1 # 一个标志值,记录了 AOF 是否处于打开状态
aof_rewrite_in_progress:0 # 一个标志值,记录了服务器是否正在创建 AOF 文件。 
aof_rewrite_scheduled:0 # 一个标志值,记录了在 RDB 文件创建完毕之后,是否需要执行预约的 AOF 重写操作。
aof_last_rewrite_time_sec:-1 # 最近一次创建 AOF 文件耗费的时长
aof_current_rewrite_time_sec:-1 # 如果服务器正在创建 AOF 文件,那么这个域记录的就是当前的创建操作已经耗费的秒数
aof_last_bgrewrite_status:ok # 一个标志值,记录了最近一次创建 AOF 文件的结果是成功还是失败
aof_last_write_status:ok
aof_current_size:176265  # AOF 文件目前的大小  
aof_base_size:176265  # 服务器启动时或者 AOF 重写最近一次执行之后,AOF 文件的大小  
aof_pending_rewrite:0  # 是否有 AOF 重写操作在等待 RDB 文件创建完毕之后执行 
aof_buffer_length:0  # AOF 缓冲区的大小  
aof_rewrite_buffer_length:0  # AOF 重写缓冲区的大小  
aof_pending_bio_fsync:0  # 后台 I/O 队列里面,等待执行的 fsync 调用数量  
aof_delayed_fsync:0 # 被延迟的 fsync 调用数量  
loading_start_time:1441769386   # loading启动时间戳  
loading_total_bytes:1787767808   # loading需要加载数据量  
loading_loaded_bytes:1587418182  # 已经加载的数据量  
loading_loaded_perc:88.79 # 加载百分比  
loading_eta_seconds:7 # 剩余时间  

# Stats
total_connections_received:52 # 服务器已接受的连接请求数量
total_commands_processed:45288712 #  服务器已执行的命令数量
instantaneous_ops_per_sec:2 # 服务器每秒钟执行的命令数量
total_net_input_bytes:860321352
total_net_output_bytes:20245117032
instantaneous_input_kbps:0.07
instantaneous_output_kbps:2.81
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0 # 因为过期而被自动删除的数据库键数量
evicted_keys:0 # 因为最大内存容量限制而被驱逐(evict)的键数量
keyspace_hits:0 # 查找数据库键成功的次数
keyspace_misses:0 # 查找数据库键失败的次数
pubsub_channels:0 # 目前被订阅的频道数量
pubsub_patterns:0 # 目前被订阅的模式数量
latest_fork_usec:0 # 最近一次 fork() 操作耗费的毫秒数
migrate_cached_sockets:0

# Replication  
role:master         #主从相关内容
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU        ##@@CPU状态,这个值需要进行计算后才能得出CPU利用率。
used_cpu_sys:5327.45
used_cpu_user:3378.65
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=13678267,expires=10984098,avg_ttl=550750775
##@@这里显示了各个数据库key的存放数目,也可以通过select db后,dbsize计算当前db中key的数量。

info命令只是总体显示了一些监控数据,redis-cli还有其他监控项目,比如

2.2 查看和杀掉客户端连接

##@@列出客户端
127.0.0.1:6379> CLIENT LIST
id=881455 addr=172.28.0.87:36377 fd=12 name= age=4882 idle=5 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=del
id=881976 addr=172.28.0.95:42077 fd=35 name= age=2334 idle=9 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=setnx
id=881899 addr=172.28.0.95:40057 fd=38 name= age=2729 idle=6 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
##@@杀掉客户端(不实用,自己一会儿就连上了)
127.0.0.1:6379> CLIENT KILL 172.28.0.95:40057

2.3 stat命令

此命令可以显示key数量、内存、客户端数量、QPS情况,类似于iostat、vmstat之类每秒钟刷新一次,如下

[root@Ali-BJ-OL-99 fio]# redis-cli -h 127.0.0.1 -p 6379 --stat
------- data ------ --------------------- load -------------------- - child -
keys      mem      clients blocked requests            connections
12495867  11.93G  57      0      2774586381 (+0)    878430
12495972  11.93G  57      0      2774587430 (+1049)  878430
12496038  11.93G  57      0      2774588265 (+835)  878430
12496149  11.93G  57      0      2774589330 (+1065)  878430
12496225  11.93G  57      0      2774590345 (+1015)  878430
12496326  11.93G  57      0      2774591469 (+1124)  878430
12496428  11.93G  57      0      2774592548 (+1079)  878430

如果你的redis设置了密码,需要加上参数”-a yourpassword”。

2.4 查看redis延迟

–latency, –latency-history 参数可以参看redis当前的响应延迟情况。

[root@Ali-BJ-OL-99 ~]# redis-cli -h 127.0.0.1 -p 6379 --latency
min: 7, max: 1230, avg: 66.22 (89 samples)

2.5 使用monitor开启实时监控

monitor命令会监控当前redis接受的命令和数据内容,这个命令会比较消耗资源,根据官网的测试,QPS会下降到原先的50%,需要谨慎使用。

[root@Ali-BJ-OL-99 ~]# redis-cli monitor
OK
1520496864.844638 [0 172.28.0.95:40594] "SETNX" "CSCustomer_5ad69f0b068f278e01c2ef5f701ec5a5" "1"
1520496864.845212 [0 172.28.0.27:10706] "GET" "lock_:4211022454185883_20003"
1520496864.846564 [0 172.28.0.27:10706] "DEL" "lock_:4211022454185883_20003"

我们可以将 redis-cli monitor数据写入到文件,然后就可以手动分析命令执行的次数。

[root@Ali-BJ-OL-99 ~]# cat m.log |awk '{print $4}' |sort |uniq -c |sort -nr
  3523 "SETNX"
  1488 "GET"
  1253 "SADD"
  1142 "PING"

2.6 使用bigkeys查找占用空间较大的key

–bigkeys这条命令会使用SCAN从redis里面查找占用空间最大的key,这会遍历redis数据库。 
但是他只把最大的找出来了,不怎么实用,至少来个TOP10吧。

[root@Ali-BJ-OL-99 ~]# redis-cli --bigkeys
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Biggest string found so far 'priv_key_78410' with 1 bytes
[00.09%] Biggest string found so far 'bigkey' with 573 bytes
[50.22%] Biggest string found so far 'bigkey2' with 606 bytes
-------- summary -------
Sampled 81697 keys in the keyspace!
Total key length in bytes is 1133020 (avg len 13.87)
Biggest string found 'bigkey2' has 606 bytes
81697 strings with 83563 bytes (100.00% of keys, avg size 1.02)
0 lists with 0 items (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

2.7showlog 功能

Redis 有一个实用的 slowlog 功能,正如你可以猜到的,可以让你检查运行缓慢的查询。

Slowlog 将会记录运行时间超过 Y 微秒的最后 X 条查询. X 和 Y 可以在 redis.conf 或者在运行时通过 CONFIG 命令:

CONFIG SET slowlog-log-slower-than 5000
CONFIG SET slowlog-max-len 25

slowlog-log-slower-than 是用来设置微秒数的, 因此上面的设置将记录执行时间超过 5 秒的查询. 要获取记录的日志,你可以使用 SLOWLOG GET X 命令, 这里 X 是你想要获取的记录条数:

SLOWLOG GET 10