Redis状态查看性能分析总结

Publish: July 4, 2020 Category: 运维 No Comments

作为一个广泛使用的缓存、消息队列、简单算法支撑基础组件,redis每一次大版本更新都会给我们带来惊喜。在写本文章的时候redis已经发布了6.0.5稳定版。后续会陆续分享一些使用redis实现各种算法的场景,本文主要讲述redis运维性能分析方面的实战总结。

一 查看redis运行状态

从如下几个方面来查看,info 命令有三种使用方式分别如下:

info 部分redis统计信息


info all 全部redis统计信息


info section 某一块的统计信息,其中section可以忽略大小写,例如: redis-cli info memory

通常情况下都是对某个块感兴趣,然后会对该块执行info 操作。

下面基本给出了Redis info 命令的状态说明。

Server包含redis服务本身的一些信息,如:版本号、运行模式、操作系统版本、TCP端口。

命令: redis-cli info server 服务端相关

redis_version:5.0.4 #redis版本
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:964fe9af98041665
redis_mode:standalone #运行模式,单机或集群
os:Linux 3.10.0-693.21.1.el7.x86_64 x86_64 #系统版本
arch_bits:64 #架构,32位或64位
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5 #编译redis时所使用的gcc版本
process_id:2939 #redis服务器的进程id
run_id:11b5694d024d8c728c1448ec4163fb0c22b86375 #redis服务器的随机标识符(用于sentinel和集群)
tcp_port:6379 #redis服务监听端口
uptime_in_seconds:18316 #redis服务启动时长,单位为秒
uptime_in_days:0 #redis服务启动时长,单位为天
hz:10 #redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率
configured_hz:10
lru_clock:4564768
executable:/usr/local/redis/redis-server #执行文件位置
config_file:/usr/local/redis/./redis.conf #配置文件位置

clients 客户端相关,包含连接数、阻塞命令连接数、输入输出缓冲区相关

redis-cli info Clients

connected_clients:2 #已连接的客户端数(不包括通过slave连接的客户端)
client_recent_max_input_buffer:2 #当前所有输出缓冲区中队列对象个数最大值
client_recent_max_output_buffer:0 #当前所有输出缓冲区中占用的最大容量
blocked_clients:0 #正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量

memory 包含redis内存使用、系统内存使用、碎片率、内存分配器

命令:redis-cli info Memory

used_memory:8985032 #由redis分配器分配的内存总量,以字节为单位
used_memory_human:8.57M #易读方式
used_memory_rss:15175680 #从操作系统的角度,返回redis已分配的内存总量(俗称常驻集大小)
used_memory_rss_human:14.47M #易读方式
used_memory_peak:14859000 #redis的内存消耗峰值(以字节为单位)
used_memory_peak_human:14.17M #易读方式
used_memory_peak_perc:60.47% #峰值内存超出分配内存(used_memory)的百分比
used_memory_overhead:5407864 #服务器为管理其内部数据结构而分配的所有开销的字节总和
used_memory_startup:862032 #Redis在启动时消耗的初始内存量(以字节为单位)
used_memory_dataset:3577168
used_memory_dataset_perc:44.04%
allocator_allocated:8951208
allocator_active:15137792
allocator_resident:15137792
total_system_memory:512077824 #系统内存总量
total_system_memory_human:488.36M
used_memory_lua:37888 #Lua引擎使用的字节量
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0 #配置设置的最大可使用内存值
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.69
allocator_frag_bytes:6186584
allocator_rss_ratio:1.00
allocator_rss_bytes:0
rss_overhead_ratio:1.00
rss_overhead_bytes:37888
mem_fragmentation_ratio:1.70 #used_memory_rss和used_memory之间的比率
mem_fragmentation_bytes:6224472 #used_memory_rss和used_memory之间的差值,单位字节
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:66616
mem_aof_buffer:0
mem_allocator:libc #内存分配器,在编译时选择
active_defrag_running:0 #指示活动碎片整理是否处于活动状态的标志
lazyfree_pending_objects:0

persistence RDB和AOF两种持久化的统计信息

命令:redis-cli info Persistence

loading:0 #服务器是否正在载入持久化rdb文件
rdb_changes_since_last_save:0 #自上次rdb持久化以来发生改变的数值
rdb_bgsave_in_progress:0 #服务器是否正在创建rdb文件
rdb_last_save_time:1564845192 #最后一次成功rdb持久化的时间戳
rdb_last_bgsave_status:ok #最后一次rdb持久化是否成功
rdb_last_bgsave_time_sec:0 #最后一次成功生成rdb文件耗时秒数
rdb_current_bgsave_time_sec:-1 #当前bgsave已耗费的时间(如果有)
rdb_last_cow_size:438272 #上次rbd保存操作期间写时复制分配的字节大小
aof_enabled:0 #aof功能是否开启
aof_rewrite_in_progress:0 #标识aof的rewrite操作是否在进行中
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1 #最后一次aof rewrite耗费的时长
aof_current_rewrite_time_sec:-1 #当前rewrite已耗费的时间(如果有)
aof_last_bgrewrite_status:ok #最后一次bgrewrite是否成功
aof_last_write_status:ok #上次aof写入状态
aof_last_cow_size:0 #上次AOF重写操作期间写时复制分配的大小(以字节为单位)

如果激活了AOF,则会添加以下附加字段:
aof_current_size:4201740 #aof当前尺寸
aof_base_size:4201687 #服务器启动时或者aof重写最近一次执行之后aof文件的大小
aof_pending_rewrite:0 #是否有aof重写操作在等待rdb文件创建完毕之后执行?
aof_buffer_length:0 #aof buffer的大小
aof_rewrite_buffer_length:0 #aof rewrite buffer的大小
aof_pending_bio_fsync:0 #后台I/O队列里面,等待执行的fsync调用数量
aof_delayed_fsync:0 #被延迟的fsync调用数量

如果正在进行加载操作,则会添加以下附加字段:
loading_start_time #加载操作开始的基于纪元的时间戳
loading_total_bytes #文件总大小
loading_loaded_bytes #已加载的字节数
loading_loaded_perc #加载进度表示为百分比
loading_eta_seconds #ETA在几秒钟内完成负载

stats 基础统计信息: 连接、命令、网络、过期、同步

命令:redis-cli info Stats

total_connections_received:7212 #服务接受的总连接数
total_commands_processed:2341631 #服务器处理的总命令数
instantaneous_ops_per_sec:0 #每秒处理的命令数
total_net_input_bytes:125344667 #从网络读取的总字节数
total_net_output_bytes:1712517025 #写入网络的总字节数
instantaneous_input_kbps:0.00 #网络读取速率KB/sec
instantaneous_output_kbps:0.00 #网络写入速率KB/sec
rejected_connections:0 #因达到最大连接数而拒绝的连接
sync_full:1 #给从节点完全同步的数量
sync_partial_ok:0 #接受的同步请求数量
sync_partial_err:0 #拒绝的同步请求数量
expired_keys:0 #键到期的总数
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0 #因达到maxmemory限制而被驱逐的键的数量
keyspace_hits:641037 #Number of successful lookup of keys in the main dictionary
keyspace_misses:9002 #Number of failed lookup of keys in the main dictionary
pubsub_channels:1
pubsub_patterns:0
latest_fork_usec:326 #最新fork操作的持续时间(以微秒为单位)
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

replication 主从复制

命令:redis-cli info Replication

role:master #master or slave
connected_slaves:0 #已建立连接的从节点数
master_replid:fe1bb6f5cfef91b36603d8e57081cc02890705c8 #复制ID
master_replid2:0000000000000000000000000000000000000000 #第二个复制ID,用于failover的PSYNC
master_repl_offset:86270959 #服务当前的复制偏移量
second_repl_offset:-1 #The offset up to which replication IDs are accepted
repl_backlog_active:0
repl_backlog_size:1048576 #复制积压缓冲区的总大小(B)
repl_backlog_first_byte_offset:85222384 #复制积压缓冲区的主偏移量
repl_backlog_histlen:1048576 #复制积压缓冲区中数据的大小

cpu cpu计算模块

命令:redis-cli info CPU

used_cpu_sys:24.941282 #Redis服务消耗的系统cpu
used_cpu_user:18.820039 #Redis服务消耗的用户cpu
used_cpu_sys_children:0.050757 #后台进程占用的系统cpu
used_cpu_user_children:0.259980 #后台进程占用的用户cpu

commandstats 命令统计: 命名名、总次数、总耗时、平均耗时

命令:127.0.0.1:6379> info cluster

cmdstat_get:calls=2326949,usec=3880386,usec_per_call=1.67
cmdstat_srem:calls=71876,usec=155728,usec_per_call=2.17
cmdstat_spop:calls=1596043,usec=8371315,usec_per_call=5.25
cmdstat_hgetall:calls=1296013,usec=4947252,usec_per_call=3.82
cmdstat_hmset:calls=5094842,usec=46347011,usec_per_call=9.10
cmdstat_lindex:calls=61876787,usec=30817880,usec_per_call=0.50
cmdstat_incr:calls=20379974,usec=78351791,usec_per_call=3.84
cmdstat_scard:calls=3144267,usec=7024982,usec_per_call=2.23
cmdstat_smembers:calls=2020700,usec=14479220,usec_per_call=7.17
cmdstat_del:calls=105429,usec=274328,usec_per_call=2.60
cmdstat_type:calls=5043,usec=22802,usec_per_call=4.52
cmdstat_info:calls=145,usec=9895,usec_per_call=68.24
cmdstat_hlen:calls=12,usec=24,usec_per_call=2.00
cmdstat_hscan:calls=2482,usec=23321,usec_per_call=9.40
cmdstat_zrange:calls=1,usec=16,usec_per_call=16.00
cmdstat_lrem:calls=26523,usec=87943,usec_per_call=3.32
cmdstat_flushdb:calls=2,usec=126,usec_per_call=63.00
cmdstat_zadd:calls=1,usec=19,usec_per_call=19.00
cmdstat_keys:calls=5,usec=80,usec_per_call=16.00
cmdstat_llen:calls=1693424,usec=3609399,usec_per_call=2.13
cmdstat_expire:calls=601857,usec=1670618,usec_per_call=2.78
cmdstat_scan:calls=3154,usec=489417,usec_per_call=155.17
cmdstat_lrange:calls=309,usec=1614,usec_per_call=5.22
cmdstat_client:calls=74,usec=186,usec_per_call=2.51
cmdstat_hget:calls=453031,usec=2680791,usec_per_call=5.92
cmdstat_sdiffstore:calls=14183,usec=126377,usec_per_call=8.91
cmdstat_set:calls=373344,usec=1138488,usec_per_call=3.05
cmdstat_config:calls=268,usec=5164,usec_per_call=19.27
cmdstat_sismember:calls=12303,usec=26399,usec_per_call=2.15
cmdstat_ttl:calls=628724,usec=1183274,usec_per_call=1.88
cmdstat_command:calls=3,usec=2557,usec_per_call=852.33
cmdstat_sscan:calls=1680,usec=14153,usec_per_call=8.42
cmdstat_select:calls=2036746,usec=2902309,usec_per_call=1.42
cmdstat_ping:calls=17630512,usec=15285714,usec_per_call=0.87
cmdstat_hincrby:calls=21785,usec=108326,usec_per_call=4.97
cmdstat_sadd:calls=1715290,usec=6206881,usec_per_call=3.62
cmdstat_exists:calls=7667,usec=7765,usec_per_call=1.01
cmdstat_lpush:calls=468,usec=3317,usec_per_call=7.09

cluster 集群

127.0.0.1:6379> info cluster

cluster_enabled:0

keyspace 每个数据库键统计

127.0.0.1:6379> info keyspace

db0:keys=262,expires=78,avg_ttl=108848761
db1:keys=3,expires=0,avg_ttl=0
db3:keys=692,expires=0,avg_ttl=0

二 延迟时间问题:

info 命令无法获取延迟时间,可以用如下命令测试:

redis-cli --latency -h 127.0.0.1 -p 6379

由于当前服务器不同的运行情况,延迟时间可能有所误差,通常1G网卡的延迟时间是200μs,Redis的响应延迟时间以毫秒为单位
我的执行结果如下:

min: 0, max: 8, avg: 0.11 (18936 samples)

找到高延迟的慢命令:

1. 使用slowlog查出引发延迟的慢命令

Redis中的slowlog命令可以让我们快速定位到那些超出指定执行时间的慢命令,默认情况下命令若是执行时间超过10ms就会被记录到日志。slowlog只会记录其命令执行的时间,不包含io往返操作,也不记录单由网络延迟引起的响应慢。通常1gb带宽的网络延迟,预期在200μs左右,倘若一个命令仅执行时间就超过10ms,那比网络延迟慢了近50倍。 想要查看所有执行时间比较慢的命令,可以通过使用Redis-cli工具,输入slowlog get命令查看,返回结果的第三个字段以微妙位单位显示命令的执行时间。假如只需要查看最后10个慢命令,输入slowlog get 10即可。

127.0.0.1:6379> SLOWLOG get 10
1) 1) (integer) 0
2) (integer) 1593758724
3) (integer) 21193
4) 1) "LINDEX"

  2) "myservice/queue/user/21"
  3) "-125179"

5) "127.0.0.1:46276"
6) ""

其中字段分别意思是:
1)、日志的唯一标识符
2)、被记录命令的执行时间点,以 UNIX 时间戳格式表示
3)、查询执行时间,以微秒为单位
4)、执行的命令,以数组的形式排列。完整命令是config get *

2.监控客户端的连接:

因为Redis是单线程模型(只能使用单核),来处理所有客户端的请求, 但由于客户端连接数的增长,处理请求的线程资源开始降低分配给单个客户端连接的处理时间,这时每个客户端需要花费更多的时间去等待Redis共享服务的响应。这种情况下监控客户端连接数是非常重要的,因为客户端创建连接数的数量可能超出预期的数量,也可能是客户端端没有有效的释放连接。在Redis-cli工具中输入info clients可以查看到当前实例的所有客户端连接信息。如下图,第一个字段(connected_clients)显示当前实例客户端连接的总数:
Redis默认允许客户端连接的最大数量是10000。若是看到连接数超过5000以上,那可能会影响Redis的性能。倘若一些或大部分客户端发送大量的命令过来,这个数字会低的多。

三 找到CPU占用过高问题:

使用Monitor可以查看redis正在执行的命令,这个执行之后如果业务比较忙可以使用管道过滤。

/usr/local/redis/bin/redis-cli monitor

执行上面的命令会看到当前redis只在执行的所有指令,想下面这样。


root@iZ2ze0q83m2ana0ndbaynbZ:~# /usr/local/redis/bin/redis-cli monitor
OK
1593825132.132419 [0 127.0.0.1:38862] "SELECT" "0"
1593825132.132659 [0 127.0.0.1:38862] "SADD" "myservice/queue/myservice/21" "180"
1593825132.138736 [0 127.0.0.1:59936] "SMEMBERS" "myservice/queue/reservation"
1593825133.659125 [0 127.0.0.1:38868] "SELECT" "0"
1593825133.659432 [0 127.0.0.1:38868] "TTL" "myservice/source/app/e46994310f465838"
1593825133.851233 [0 127.0.0.1:59938] "PING"
1593825133.851729 [0 127.0.0.1:59938] "GET" "myservice/source/myservice_heartbeat/e46994310f422032"
1593825135.907108 [0 127.0.0.1:59938] "PING"
1593825135.907250 [0 127.0.0.1:59938] "GET" "myservice/source/myservice_heartbeat/e46994310f422032"
1593825137.956901 [0 127.0.0.1:59938] "PING"
1593825137.957059 [0 127.0.0.1:59938] "GET" "myservice/source/myservice_heartbeat/e46994310f422032"
1593825139.231991 [0 127.0.0.1:59936] "PING"
1593825139.232142 [0 127.0.0.1:59936] "SMEMBERS" "myservice/queue/map"
1593825139.232237 [0 127.0.0.1:59936] "SMEMBERS" "myservice/queue/map"

其中字段意思分别是

时间戳.微秒 [db 客户端ip.客户端port] "任务指令"

四 设计总结

项目开发中禁止使用模糊匹配,防止出现全部key扫描的业务设计场景。
尽量不要在redis中做持久化,交由其他服务完成。

Tags: redis管理, redis

Related Posts:

Leave a Comment