Redis 有哪些好用的运维工具?

299 阅读10分钟

前言

我们在应用 Redis 时,经常会面临的运维工作,包括 Redis 的运行状态监控,数据迁移,主从集群、切片集群的部署和运维。

运行状态监控

我们先来看下监控 Redis 实时运行状态的工具,这些工具都用到了 Redis 提供的一个监控命令:INFO。

最基本的 INFO 命令

Redis 本身提供的 INFO 命令会返回丰富的实例运行监控信息,这个命令是 Redis 监控工具的基础。

INFO [section [section ...]]

image.png INFO 命令在使用时,可以带一个参数 section,这个参数的取值有好几种,相应的,INFO 命令也会返回不同类型的监控信息。我把 INFO 命令的返回信息分成 5 大类,其中,有的类别当中又包含了不同的监控内容。

经常关注的 section 类别命令参数详解放在文章最后~,也可以查看官网的介绍。

面向 Prometheus 的 Redis-exporter 监控

Prometheus 是一套开源的系统监控报警框架。它的核心功能是从被监控系统中拉取监控数据,结合 Grafana 工具,进行可视化展示。而且,监控数据可以保存到时序数据库中,以便运维人员进行历史查询。同时,Prometheus 会检测系统的监控指标是否超过了预设的阈值,一旦超过阈值,Prometheus 就会触发报警。

Prometheus 正好提供了插件功能来实现对一个系统的监控,我们把插件称为 exporter,每一个 exporter 实际是一个采集监控数据的组件。exporter 采集的数据格式符合 Prometheus 的要求,Prometheus 获取这些数据后,就可以进行展示和保存了。

Redis-exporter 就是用来监控 Redis 的,它将 INFO 命令监控到的运行状态和各种统计信息提供给 Prometheus,从而进行可视化展示和报警设置。除了获取 Redis 实例的运行状态,Redis-exporter 还可以监控键值对的大小和集合类型数据的元素个数,这个可以在运行 Redis-exporter 时,使用 check-keys 的命令行选项来实现。

此外,我们可以开发一个 Lua 脚本,定制化采集所需监控的数据。然后,我们使用 scripts 命令行选项,让 Redis-exporter 运行这个特定的脚本,从而可以满足业务层的多样化监控需求。

最后,我还想再给你分享两个小工具:redis-statRedis Live。跟 Redis-exporter 相比,这两个都是轻量级的监控工具。它们分别是用 Ruby 和 Python 开发的,也是将 INFO 命令提供的实例运行状态信息可视化展示。

数据迁移工具 Redis-shake

Redis-shake 的基本运行原理,是先启动 Redis-shake 进程,这个进程模拟了一个 Redis 实例。然后,Redis-shake 进程和数据迁出的源实例进行数据的全量同步。

image.png

Redis-shake 的一大优势,就是支持多种类型的迁移。

首先,它既支持单个实例间的数据迁移,也支持集群到集群间的数据迁移。

其次,有的 Redis 切片集群(例如 Codis)会使用 proxy 接收请求操作,Redis-shake 也同样支持和 proxy 进行数据迁移。

另外除了支持开源的 Redis 版本以外,Redis-shake 还支持云下的 Redis 实例和云上的 Redis 实例进行迁移,可以帮助我们实现 Redis 服务上云的目标。

在数据迁移后,我们通常需要对比源实例和目的实例中的数据是否一致。如果有不一致的数据,我们需要把它们找出来,从目的实例中剔除,或者是再次迁移这些不一致的数据。

数据比对工具 Redis-full-check

Redis-full-check 的工作原理很简单,就是对源实例和目的实例中的数据进行全量比对,从而完成数据校验。不过,为了降低数据校验的比对开销,Redis-full-check 采用了多轮比较的方法。

在第一轮校验时,Redis-full-check 会找出在源实例上的所有 key,然后从源实例和目的实例中把相应的值也都查找出来,进行比对。第一次比对后,redis-full-check 会把目的实例中和源实例不一致的数据,记录到 sqlite 数据库中。

从第二轮校验开始,Redis-full-check 只比较上一轮结束后记录在数据库中的不一致的数据。

为了避免对实例的正常请求处理造成影响,Redis-full-check 在每一轮比对结束后,会暂停一段时间。随着 Redis-shake 增量同步的进行,源实例和目的实例中的不一致数据也会逐步减少,所以,我们校验比对的轮数不用很多。

我们可以自己设置比对的轮数。具体的方法是,在运行 redis-full-check 命令时,把参数 comparetimes 的值设置为我们想要比对的轮数。

Redis-full-check 提供了三种比对模式,我们可以通过 comparemode 参数进行设置。comparemode 参数有三种取值,含义如下:

  • KeyOutline:只对比 key 值是否相等;
  • ValueOutline:只对比 value 值的长度是否相等;
  • FullValue:对比 key 值、value 长度、value 值是否相等。

集群管理工具 CacheCloud

面向 Redis 运维管理的云平台,它实现了主从集群、哨兵集群和 Redis Cluster 的自动部署和管理,用户可以直接在平台的管理界面上进行操作。针对常见的集群运维需求,CacheCloud 提供了 5 个运维操作。

  • 下线实例:关闭实例以及实例相关的监控任务。
  • 上线实例:重新启动已下线的实例,并进行监控。
  • 添加从节点:在主从集群中给主节点添加一个从节点。
  • 故障切换:手动完成 Redis Cluster 主从节点的故障转移。
  • 配置管理:用户提交配置修改的工单后,管理员进行审核,并完成配置修改。

CacheCloud 不仅会收集 INFO 命令提供的实例实时运行状态信息,进行可视化展示,而且还会把实例运行状态信息保存下来,例如内存使用情况、客户端连接数、键值对数据量。这样一来,当 Redis 运行发生问题时,运维人员可以查询保存的历史记录,并结合当时的运行状态信息进行分析。

INFO 命令详解

stats(General statistics)

  • total_connections_received:接收成功的链接总数
  • total_commands_processed:命令成立完成的总数
  • instantaneous_ops_per_sec:每秒处理的命令数量
  • total_net_input_bytes:输入流总量,byte级别
  • total_net_output_bytes:输出流总量,byte级别
  • instantaneous_input_kbps:每秒输入kb数量
  • instantaneous_output_kbps:每秒输出kb数量
  • rejected_connections:拒绝链接数量
  • sync_full:与副本完全同步的次数
  • sync_partial_ok:部分同步请求接受数量
  • sync_partial_err:部分同步请求拒绝数量,或者说处理失败数量
  • expired_keys:过期的key数量
  • expired_stale_perc:过期key与总Key数量的占比
  • evicted_keys:内存超出时,被逐出的Key数量
  • keyspace_hits:自redis启动开始,成功命中的key数量
  • keyspace_misses:自redis启动开始,未成功名称的key数量
  • pubsub_channels:当前使用中的channel数量
  • pubsub_patterns:当前使用的模式的数量
  • latest_fork_usec:fork耗时,微秒,fork详情
  • migrate_cached_sockets:socket缓冲
  • slave_expires_tracked_keys:副本到期跟踪的key数量(仅适用于可写副本)

commandstat(Redis command statistics)

  • calls:调用次数
  • usec:总耗时(微秒)
  • usec_per_call:平均耗时(微秒)

cpu(CPU consumption statistics)

  • used_cpu_sys:redis主进程占用核心态的CPU总耗时(主线程和后台线程)
  • used_cpu_user:redis主进程占用用户态的CPU总耗时(主线程和后台线程)
  • used_cpu_sys_children:redis后台进程占用核心态的CPU总耗时
  • used_cpu_user_children:redis后台进程占用用户态的CPU总耗时

memory(Memory consumption related information)

  • used_memory:已使用内存,byte级别
  • used_memory_human:已使用内存,可读方式展示
  • used_memory_rss:Redis占用的物理内存,byte级别
  • used_memory_rss_human:Redis占用的物理内存,可读方式展示
  • used_memory_peak:Redis的内存使用峰值,byte级别
  • used_memory_peak_human:Redis的内存使用峰值,可读方式展示
  • used_memory_peak_perc:used_memory / used_memory_peak百分比
  • used_memory_overhead:Redis管理数据结构使用的内存,byte级别
  • used_memory_startup:Redis启动时消耗的内存
  • used_memory_dataset:used_memory - used_memory_overhead数据集大小,byte级别
  • used_memory_dataset_perc:used_memory_dataset / used_memory数据集站总消耗内存占比
  • allocator_allocated:分配器分配的内存,作用未知,byte级别
  • allocator_active:分配器活跃内存,作用未知,byte级别
  • allocator_resident:分配器常驻内存,作用未知,byte级别
  • total_system_memory:所在服务器系统总内存,byte级别
  • total_system_memory_human:所在服务器系统总内存,可读方式显示
  • used_memory_lua:lua使用的内存,byte级别
  • used_memory_lua_human:lua使用的内存,可读方式展示
  • used_memory_scripts:lua缓存使用的内存,byte级别
  • used_memory_scripts_human:lua缓存使用的内存,可读方式展示
  • maxmemory:最大使用内存限制,超过时,会使用LRU或LFU策略删除key,该值尽量设置的小于系统内存
  • maxmemory_human:最大使用内存限制,可读方式展示
  • maxmemory_policy:内存超出时,删除key的策略,有lru,lfu可选
  • mem_fragmentation_ratio:used_memory_rss / used_memory内存碎片率,过高对性能的影响
  • mem_fragmentation_bytes:内存碎片大小,byte级别
  • mem_allocator:内存分配器

replication(Master/replica replication information)

  • role:实例的角色,是master or slave
  • connected_slaves:连接的slave实例个数
  • slave0:副本连接信息(lag从库多少秒未向主库发送REPLCONF命令)ip=10.16.36.19,port=8123,state=online,offset=193369160007,lag=0
  • master_failover_state:是否正常进行故障切换的状态
  • master_replid:当前Redis服务的复制实例ID
  • master_repl_offset:主从同步 主库偏移量
  • repl_backlog_active:复制积压缓冲区是否开启
  • repl_backlog_size:复制积压缓冲区大小
  • repl_backlog_first_byte_offset:复制积压缓冲区里偏移量的大小 repl_backlog_histlen:此值等于 master_repl_offset - * repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小

persistence(RDB and AOF related information)

  • loading:是否有加载转储文件的标识,0=无,1=有,内存耗尽可能会有
  • rdb_changes_since_last_save:自最后一次持久保存后,rdb进行的改动数量
  • rdb_bgsave_in_progress:标志rdb是否在保存,0=无,1=有
  • rdb_last_save_time:最后一次保存时间戳
  • rdb_last_bgsave_status:最后一次异步持久化操作的状态
  • rdb_last_bgsave_time_sec:最后一次异步持久化持续时长,秒级
  • rdb_current_bgsave_time_sec:当前异步持久化时长,-1表示当前没有异步持久化
  • rdb_last_cow_size:最后一次持久化时内存copy的大小,byte级别
  • aof_enabled:是否开启aof的持久化方式,0=不开启,1=开启
  • aof_rewrite_in_progress:标志aof是否有在重写,0=无,1=有
  • aof_rewrite_scheduled:标识是否将要在rdb save操作结束后执行
  • aof_last_rewrite_time_sec:aof最后一次重写耗时,秒级
  • aof_current_rewrite_time_sec:aof当前重写耗时,-1代表当前没有执行重写
  • aof_last_bgrewrite_status:aof最后一次异步重写状态
  • aof_last_write_status:aof最后一次重写状态
  • aof_last_cow_size:aof最后一次重写消耗内存, byte级别
  • aof_current_size:aof当前文件大小,byte级别
  • aof_base_size:aof最新一次启动或重写的文件大小,byte级别
  • aof_pending_rewrite:同上面的aof_rewrite_scheduled
  • aof_buffer_length:aof buffer的大小
  • aof_rewrite_buffer_length:aof 重写buffer大小
  • aof_pending_bio_fsync:后台IO队列中等待fsync任务的个数
  • aof_delayed_fsync:延迟的fsync计数器

总结

平时我们遇到的 Redis 变慢问题,有时觉得很难定位原因,其实是因为我们没有做好完善的监控。 Redis INFO 信息看似简单,但是这些信息记录着 Redis 运行时的各种状态数据,如果我们把这些数据采集到并监控到位,80% 的异常情况能在第一时间发现。

参考

摘自 极客时间 - 蒋德钧老师的《Redis 核心技术与实战》 <- 极其推荐大家阅读~

《Redis 核心技术与实战》学习笔记 Day5