一、背景

作为最底层的技术人员,目前由于有客户在运维中遇到混合架构,公有云上使用了产品级别Redis数据库,同时由于业务在云服务器和kubnets的容器内也有redis数据库,因此对于这种混合模式数据库的监控,进行简单的分析总结,在此记录笔记,在此抛砖引玉,也曾希望对各位有一点点益处。 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,在原子化操作的基础上,有具有数据持久化的功能,同时也支持主从同步和集群搭建,支持发布订阅机制,大大提高了数据操作的扩展性和数据冗余安全性。在目前SAAS无论是共有云还是私有云,自建集群,还是docker容器,监控方式多样化,针对不同的场景各种方式互补来更好的提供监控。

二、监控方式

2.1 云平台监控

目前对于SAAS产品级别数据库产品,即开即用底层均依托于各云厂商的多副本或集群方式,来保障数据的安全性和服务的稳定性,但在目前的几次云故障中,我们也要心怀对数据的敬畏之心,各方面多方式做好数据的备份,没有绝对的安全,无论在多少个9的SLA面前,数据一旦发生不可挽回性丢失或损坏那将是百分之百的损失,数据无价。 因此需要做好数据备份:

  • 共有云产品备份策略,
  • 备份恢复验证数据可用性
  • 跨可用区,异地灾备
  • 多副本,主从备份
  • 本地或对象存储归档备份等

监控方式使用各公有云提供的数据库监控,但是对于提供监控指标有可能很少,且很多云厂商监控频率为5分,实时性不高,对此我们可以使用自定义监控来将数据上报给云平台来扩展自定义监控项,同时联系云服务提供商是否可以缩短监控频率等。 可了解云平台自定义监控:阿里云自定义监控 此处只举了一个例子,各不同云厂商如果具有自定义监控功能,那都可以类似的来进行操作。

在此监控展示两张代表性国内公有云厂商redis监控图

  • 腾讯云

  • 阿里云

2.2 第三方监控工具

第三方成熟监控工具也很多,提供服务的如:

2.2.1 安畅网络的SmartEye

在此仅简略介绍应用监控

  • 服务监控类型丰富,常用应用及数据库监控都有
  • 身处运维人员角度,提供完善齐全服务监控指标
  • 安装方式非常方便,一条命令即可安装部署
  • 监控模式多样化,可直接安装agent代理,或纯内网proxy模式监控
  • 服务系统资源占用极小
  • 监控频率细粒度,1分钟监控数据上报
  • 可自定义脚本横向扩展指标或监控其他应用业务等
  • 告警策略分级,告警方式可选性多 详细信息可以官网介绍了解详情SmartEye

2.2.2 监控宝

监控宝的应用监控也较详细 可以参考之前的文章了解监控宝服务性能监控

2.3 开源监控工具

2.3.1 RedisLive

RedisLive是由python编写的并且开源的图形化监控工具,非常轻量级,核心服务部分只包含一个web服务和一个基于redis自带的info命令以及monitor命令的监控服务,界面上只有一个基于BootStrap的web界面,非常简洁明了。除此之外,它还支持多实例监控,切换方便,而且配置起来也非常容易。监控信息支持redis存储和持久化存储(sqlite)两种方式。 操作方式可以参考:RedisLive监控Redis服务

2.3.2 Zabbix监控

zabbix作为运维人员总所周知的开源监控系统,其功能强大,监控方式多样深受技术人员喜爱,有很多公司对其进行二次开发来定制化本公司监控系统。

本次为客户提供的也是SAAP云平台结合Zabbix私有监控来共同构建完整监控体系,优势互补且监控冗余。

  • 对于客户SAAS产品Redis使用自带云产品监控配合自定义监控项可以很好满足;
  • 对于客户自建Redis和容器内跑的数据库利用zabbix监控;
  • 云主机的redis可以利用在云主机上安装agent采集数据,被动发送给server监控 但是对于容器内,在内部安装agent,对于目前已经整在运行的业务进行大规模在此部署显得不是非常的方便,此时使用在zabbix server自定义脚本来实现监控。

A. 通过redis-cli命令的info参数可以获取redis的详细信息,利用自定义脚本来截取想要的参数进行监控,以下为记录的获取的参数,还可以通过redis参考指标获取。

# Server        #服务端信息
redis_version:3.2.10        #Redis版本
redis_git_sha1:00000000     #Git SHA1
redis_git_dirty:0       #Git dirty flag
redis_build_id:c8b45a0ec7dc67c6
redis_mode:standalone       #redis运行的模式
os:Linux 3.10.0-514.26.2.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.5
process_id:1755
run_id:0ee1ada5aa030118000d991c39564e41d504a3a5     #服务器的随机标识符(用于 Sentinel 和集群
tcp_port:6379       #监听端口
uptime_in_seconds:5095759       #运行时长(秒)
uptime_in_days:58       #运行时长
hz:10
lru_clock:7308631       #以分钟为单位进行自增的时钟,用于 LRU 管理
executable:/usr/bin/redis-server
config_file:/etc/redis.conf

# Clients       #客户端信息
connected_clients:4     #已连接客户端的数量
client_longest_output_list:0        # 当前连接的客户端当中,最长的输出列表
client_biggest_input_buf:0      #当前连接的客户端当中,最大输入缓存
blocked_clients:0      #list阻塞调用被阻塞的连接个数如果监控数据大于0,告警 

# Memory        # 内存信息
used_memory:1366580712      #Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human:1.27G     #以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss:1593454592      ## Redis 分配的内存总量(包括内存碎片),以字节(byte)为单位
used_memory_rss_human:1.48G     ##以人类可读的格式返回 Redis 分配的内存总量(包括内存碎片)
used_memory_peak:2856423024     #Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human:2.66G        #以人类可读的格式返回 Redis 的内存消耗峰值
total_system_memory:16658460672     #系统内存总量(以字节为单位)
total_system_memory_human:15.51G        #人类客可读格式redis的系统内存总量
used_memory_lua:37888       #Lua 引擎所使用的内存大小(以字节为单位)
used_memory_lua_human:37.00K        #以人类可读方式返回Lua 引擎所使用的内存大小
maxmemory:0     
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.17         #redis内存碎片率(used_memory_rss/used_memory),小于1,表示redis已使用swap分区,则告警
mem_allocator:jemalloc-3.6.0        #在编译时指定的,Redis所使用的内存分配器。可以是libc、jemalloc或者tcmalloc

# Persistence       #RDB 和 AOF 的相关信息
loading:0       #一个标志值,记录了服务器是否正在载入持久化文件
rdb_changes_since_last_save:5270        ##距离最近一次成功创建持久化文件之后,经过了多少秒
rdb_bgsave_in_progress:0        #一个标志值,记录了服务器是否正在创建 RDB 文件
rdb_last_save_time:1534035237       ##最近一次成功创建 RDB 文件的 UNIX 时间戳
rdb_last_bgsave_status:ok       ##一个标志值,记录了最近一次创建 RDB 文件的结果是成功还是失败
rdb_last_bgsave_time_sec:15     #记录了最近一次创建 RDB 文件耗费的秒数
rdb_current_bgsave_time_sec:-1      #如果服务器正在创建 RDB 文件,那么这个值记录的就是当前的创建操作已经耗费的秒数
aof_enabled:0       #redis是否开启了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文件是否成功

# Stats
total_connections_received:14133        #服务器已接受的连接请求数量
total_commands_processed:7477479089     #服务器已执行的命令数量
instantaneous_ops_per_sec:271       #服务器每秒钟执行的命令数量 
total_net_input_bytes:599074234857      #redis网络入口流量字节数
total_net_output_bytes:2484573994623        #redis网络出口流量字节数
instantaneous_input_kbps:53.60      #redis网络入口kbps
instantaneous_output_kbps:107.04        #redis网络出口kbps
rejected_connections:0      #因为最大客户端数量限制而被拒绝的连接请求数量
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:61703692       #因为过期而被自动删除的数据库键数量
evicted_keys:0      因为最大内存容量限制而被驱逐(evict)的键数量
keyspace_hits:5121978022        # 请求键被命中次数
keyspace_misses:68376478        # 请求键未被命中次数
pubsub_channels:0       #当前使用中的频道数量
pubsub_patterns:0       #当前使用中的模式数量   
latest_fork_usec:40503      最近一次fork阻塞的微秒数,最近一次Fork操作阻塞redis进程的耗时数,单位微秒。
migrate_cached_sockets:0

# Replication       # 复制信息
role:master     #角色
connected_slaves:0      #连接的slave数量
master_repl_offset:0        # master复制偏移量
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:169884.36      #Redis服务器耗费的系统CPU
used_cpu_user:85656.09      #Redis服务器耗费的用户CPU
used_cpu_sys_children:43671.30      #子进程耗费的系统CPU
used_cpu_user_children:316353.91         #子进程耗费的用户CPU

# Cluster
cluster_enabled:0       #是否启用集群

# Keyspace
db0:keys=2353841,expires=2204380,avg_ttl=929326076  #据库的键数量、数据库设置有过期时间的key的数量(这个值减少是正常的)

B. 对获取的指标挑选想要监控的进行脚本截取

#!/bin/bash
# -------------------------------------------------------------------------------
 
REDIS_CLI_COMMAND="redis-cli"
REDIS_HOST="172.x.x.x"
REDIS_PORT="6379"
 
ARGS=1
 
if [ $# -ne "$ARGS" ];then
    echo "Please input one arguement:"
fi
 
case $1 in
    connected_clients)
        result=`$REDIS_CLI_COMMAND -h $REDIS_HOST -p $REDIS_PORT -a 'password' info | grep -w "connected_clients" | awk -F':' '{print $2}'`
            echo $result
            ;;
    used_memory_rss)
        result=`$REDIS_CLI_COMMAND -h $REDIS_HOST -p $REDIS_PORT -a 'password' info | grep -w "used_memory_rss" | awk -F':' '{print $2}' | awk -F'G' '{print $1}'`
            echo $result
			 ....   #此处可以根据以上写自己感兴趣的监控项
esac

注意,如果多个主机监控,可以将host作为第二个参数进行传入,也可分多个脚本,区分不同端口或密码, C. 最后添加进zabbix server 主机的agent配置段

UnsafeUserParameters=1           #配置用户可自定义脚本

UserParameter=Redis.Info_0.2[*],/etc/zabbix/script/redis/chk_redis.0.2.sh $1         #此处多实例,可以根据后两位ip地址进行数据区分

三、总结

  • 目前对于平台话的,尽量用平台化统一监控管理,如何内部有自定义那就更好了,可以配合脚本多维度细粒度实现定制化监控,非常方便;
  • 对于例如客户这种混合模式,平台无法满足可以利用平台基础监控+私有化部署监控互补来满足绝大多数需求。
  • 对于想要既方便且功能强大的,由易于管理维护,smarteye可以考虑,监控类型及指标全而完整,细粒度、高频率、支持自定义、可私有化部署,成为下一代监控的首选。