一, 背景
作为最底层的技术人员, 目前由于有客户在运维中遇到混合架构, 公有云上使用了产品级别 Redis 数据库, 同时由于业务在云服务器和 kubnets 的容器内也有 Redis 数据库, 因此对于这种混合模式数据库的监控, 进行简单的分析总结, 在此记录笔记, 在此抛砖引玉, 也曾希望对各位有一点点益处. Redis 是一个 key-value 存储系统. 和 Memcached 类似, 它支持存储的 value 类型相对更多, 在原子化操作的基础上, 有具有数据持久化的功能, 同时也支持主从同步和集群搭建, 支持发布订阅机制, 大大提高了数据操作的扩展性和数据冗余安全性. 在目前 SAAS 无论是共有云还是私有云, 自建集群, 还是 docker 容器, 监控方式多样化, 针对不同的场景各种方式互补来更好的提供监控.
二, 监控方式
2.1 云平台监控
目前对于 SAAS 产品级别数据库产品, 即开即用底层均依托于各云厂商的多副本或集群方式, 来保障数据的安全性和服务的稳定性, 但在目前的几次云故障中, 我们也要心怀对数据的敬畏之心, 各方面多方式做好数据的备份, 没有绝对的安全, 无论在多少个 9 的 SLA 面前, 数据一旦发生不可挽回性丢失或损坏那将是百分之百的损失, 数据无价. 因此需要做好数据备份:
共有云产品备份策略,
备份恢复验证数据可用性
跨可用区, 异地灾备
多副本, 主从备份
本地或对象存储归档备份等
监控方式使用各公有云提供的数据库监控, 但是对于提供监控指标有可能很少, 且很多云厂商监控频率为 5 分, 实时性不高, 对此我们可以使用自定义监控来将数据上报给云平台来扩展自定义监控项, 同时联系云服务提供商是否可以缩短监控频率等. 可了解云平台自定义监控: 阿里云自定义监控 http://blog.51cto.com/kaliarch/1923429 此处只举了一个例子, 各不同云厂商如果具有自定义监控功能, 那都可以类似的来进行操作.
在此监控展示两张代表性国内公有云厂商 Redis 监控图
腾讯云
阿里云
2.2 第三方监控工具
第三方成熟监控工具也很多, 提供服务的如:
2.2.1 安畅网络的 SmartEye
在此仅简略介绍应用监控
服务监控类型丰富, 常用应用及数据库监控都有
身处运维人员角度, 提供完善齐全服务监控指标
安装方式非常方便, 一条命令即可安装部署
监控模式多样化, 可直接安装 agent 代理, 或纯内网 proxy 模式监控
服务系统资源占用极小
监控频率细粒度, 1 分钟监控数据上报
可自定义脚本横向扩展指标或监控其他应用业务等
告警策略分级, 告警方式可选性多 详细信息可以官网介绍了解详情 SmartEye https://www.anchnet.com/service/smarteye
2.2.2 监控宝
监控宝的应用监控也较详细 可以参考之前的文章了解监控宝服务性能监控 http://blog.51cto.com/kaliarch/2045128
2.3 开源监控工具
2.3.1 RedisLive
RedisLive 是由 python 编写的并且开源的图形化监控工具, 非常轻量级, 核心服务部分只包含一个 web 服务和一个基于 Redis 自带的 info 命令以及 monitor 命令的监控服务, 界面上只有一个基于 Bootstrap 的 Web 界面, 非常简洁明了. 除此之外, 它还支持多实例监控, 切换方便, 而且配置起来也非常容易. 监控信息支持 Redis 存储和持久化存储 (SQLite) 两种方式. 操作方式可以参考: RedisLive 监控 Redis 服务 http://blog.51cto.com/kaliarch/1956594
2.3.2 Zabbix 监控
zabbix 作为运维人员总所周知的开源监控系统, 其功能强大, 监控方式多样深受技术人员喜爱, 有很多公司对其进行二次开发来定制化本公司监控系统.
本次为客户提供的也是 SAAP 云平台结合 Zabbix 私有监控来共同构建完整监控体系, 优势互补且监控冗余.
对于客户 SAAS 产品 Redis 使用自带云产品监控配合自定义监控项可以很好满足;
对于客户自建 Redis 和容器内跑的数据库利用 zabbix 监控;
云主机的 Redis 可以利用在云主机上安装 agent 采集数据, 被动发送给 server 监控 但是对于容器内, 在内部安装 agent, 对于目前已经整在运行的业务进行大规模在此部署显得不是非常的方便, 此时使用在 zabbix server 自定义脚本来实现监控.
A. 通过 Redis-cli 命令的 info 参数可以获取 Redis 的详细信息, 利用自定义脚本来截取想要的参数进行监控, 以下为记录的获取的参数, 还可以通过 Redis 参考指标 http://redisdoc.com/server/info.html 获取.
- # 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 可以考虑, 监控类型及指标全而完整, 细粒度, 高频率, 支持自定义, 可私有化部署, 成为下一代监控的首选.
来源: https://juejin.im/post/5c37ed76e51d4551ea7f20fa