享学课堂特邀作者:老顾转载请声明出处,谢谢!!!

前言

文章中还提到了几点问题:

  • 如何区分业务
  • 如何发现异常
  • 如何截断异常
  • 如何优雅扩容

今天老顾这篇文章就重点介绍如何发现异常,为什么从这个点去讲,因为这个点是前期的基础,只有具备发现一些问题,才能够有后续行为。

redis监控

在我们现在公司redis监控中,是对整个redis集群进行监控,如:内存使用情况,客户端连接数,有多少keys等从整体集群纬度上面去监控redis的使用情况。当然这些监控也是非常重要的。

现在常规的方案就是利用Prometheus采集数据,并用Grafana进行展示,如下图

可以这些只是个从整体纬度上面的监控,因为我们企业很多项目都在用一个公共的redis集群,那如何监控在每个项目,以及每个项目实例的对公共redis集群的请求情况呢?

公共Redis集群监控需求

我们先看下面的图:

现在公司很多都是微服务架构了,会涉及到会有很多服务实例了。上图中就是多个项目,多个服务实例在请求公用redis集群。

这种情况下,我们需要一个底线,就是一定要保证我们的公共redis集群是稳定的,一旦不稳定会导致我们所有的项目服务不稳定

但是这种架构会出现研发风险,因为在真实的开发过程中,我们是没法保证我们所有的开发人员不会出错,万一有个开发人员,在写一些业务时,用到了redis组件,写了个死循环导致了我们redis请求猛增,导致redis不稳定。或者对redis进行滥用,什么业务都放到redis中,导致内存崩溃。在这种情况下,我们都没法知道是哪个项目,哪个实例导致的。我们的运维会处在排查问题的混乱之中。那我们能不能提前设防呢?

我们整理一下需求:

1)我们是否可以提前分配某个项目占用redis内存的大小,指定每个实例的单位时间最大请求数,最大容忍的异常数。
2)实时监控项目占用的redis内存情况
3)实时监控项目中每个实例的请求情况
4)一旦项目占用redis内存大于分配的,就报警;甚至可以自动让这个项目进入黑名单
5)一旦项目中的实例的请求数,异常数,大于分配的,就报警;甚至可以自动让这个项目进入黑名单

解决方案

既然需求过来,那我们作为开发人员,就要项目如何设计我们的方案。因为需求还是比较多的,我们来梳理一下这些需求业务流程:

项目分配规则其实是比较简单的,只要设计一下mysql,以及开发一个web服务,在界面进行操作;就是一些基本的CRUD。这边老顾就不讲了。

监控是这篇文章的重点,后面涉及到的监控后的策略,老顾放到后续文章里面介绍。

监控项目内存使用情况

如果要监控整个redis的内存使用情况,是比较简单的,上面就介绍了Prometheus+Grafana的方案,当然还可以配合alert报警策略做一些后续流程

基本原理就是利用redis自身的info命令,以及info stats等命令输出了一些redis服务性能指标

那我们如何细化到监控每个项目的内存占用情况呢?

小伙伴们是否还记得redis有个持久化的概念,会把一些缓存数据持久化到dump.rdb中,这个文件就存储了每个key和value的值,以及slot的占用情况。不过这个文件是二进制的,小伙伴们不能直接打开。

我们的方案就是来解析dump.rdb文件,分析项目内存的使用情况,因为我们会规定每个项目都会有唯一的项目名称,会对key有个固定的格式【项目名称:key名称】

projectName1:userprojectName2:order 

即每个key前面都会带上项目名称。这样有利于我们在解析dump.rdb后,通过项目名称前缀进行统计项目使用的内存大小。

原理小伙伴们应该知道了吧,但是怎么去解析dump.rdb文件呢,难度太大了吧;还好有开源社区的贡献,我们不需要重复造轮子。老顾采用了go语言解析dump.rdb的工具。

git地址为:

https://github.com/sripathikrishnan/redis-rdb-tools https://gitee.com/gujiachun/rdr(这个是老顾用的,上面的工具也可以考虑,功能更多)

那dump.rdb文件怎么获取到呢?redis配置文件中有对应的配置,当然我们解析dump.rdb这个操作要在redis从节点做,相对安全可靠,也可以覆盖所有业务的 Redis 集群。

整体流程如下:

这个开源的工具需要一些go语言相关的知识,当然老顾已经打包了一个bin,可以直接用

执行命令

./macos_start dump dump.rdb >> 111.txt 

我们可以看到导出来的数据,key表示设置的可以,Bytes就是这个key存储的value的占用的字节数,Type表示这对key-value的类型。

我们可以设置定时任务去执行dump操作,当然如果小伙伴会go语言的,可以在这个项目中自行添加业务。这样我们就可以获取到所有key占用内存的情况,再通过分析key的项目前缀,这样就可以算出来项目占用内存的情况。

小伙伴们会问,dump.rdb文件很大,那解析需要要多久啊。老顾尝试了一下,80几万的key,dump文件300M左右,用这个工具分析只要 5秒;还是蛮强大的,Go语言实现

实例请求监控

上面我们已经解决了项目内存的占用情况,这边我们在解决一下如何监控每个服务实例的请求情况,需要知道请求数,成功数,异常数,最大耗时,最小耗时,平均耗时指标

这块是参考了限流降级框架Sentinel的源代码中,实时统计请求指标。

Sentinel是以Bucket(桶)为单位记录一段时间内的请求总数、异常总数、总耗时的,而一个Bucket可以是记录一秒内的数据,也可以是10毫秒内的数据,我们称这个时间区间为Bucket的统计单位,是由使用者自定义的:

Bucket存储一段时间内的请求数、异常数等这些数据用的是一个LongAdder数组,LongAdder保证了数据修改的原子性,数组的每个元素分别代表一段时间内的请求总数、异常数、总耗时。

用枚举类型MetricEvent的ordinal作为下标。LongAdder被我替换为j.u.c包下的atomic类了。

当需要获取Bucket记录的总的成功请求数、或者异常总数、或者总的请求处理耗时时,可以通过MetricEvent从LongAdder数组中获取对应的LongAdder,调用sum方法。

当需要往Bucket添加1个请求、或者一个异常,或者处理请求的耗时时,可以通过MetricEvent从LongAdder数组中获取对应的LongAdder,调用add方法。

有了Bucket之后,假设我们需要让Bucket存储一秒钟的数据,这样我们就能够知道每秒处理成功的请求数(成功QPS)、每秒处理失败的请求数(失败QPS),以及处理每个成功请求的平均耗时(avg RT)。但是我们如何才能确保Bucket存储的就是精确到1秒的数据呢?最low的做法就是启一个定时任务每秒创建一个Bucket,但统计出来的数据误差绝对很大。

而Sentinel是这样实现的。它定义一个Bucket数组,根据时间戳来定位到数组下标。假设我们需要统计每1秒处理的请求数等数据,且只需要保存最近一分钟的数据。那么Bucket数组的大小就可以设置为60,每个Bucket的windowLengthInMs窗口大小就是1000毫秒(1秒)。

由于每个Bucket存储的是1秒的数据,那么就可以将当前时间戳去掉毫秒部分,就能得到当前的秒数,假设Bucket数组的大小是无限大的,那么得到的秒数就是当前要获取的Bucket所在的数组下标。

但我们不能无限的存储Bucket,一秒一个Bucket得要多大的内存才能存一天的数据。所以,当我们只需要保留一分钟的数据时,Bucket数组的大小就是60,将得到的秒数与数组长度取余数,就得到当前Bucket所在的数组下标。这个数组是循环使用的,永远只保存最近1分钟的数据。

取余数就是循环利用数组。如果想要获取连续的一分钟的Bucket数据,就不能简单的从头开始遍历数组,而是指定一个开始时间和结束时间, 从开始时间戳开始计算Bucket存放的数组下标,然后循环每次将开始时间戳加上1秒,直到开始时间等于结束时间。

整体原理如上,还是比较挠的,直接上案例代码,看效果如何。

请求案例

上面是业务中加入监控埋点,下面我们直接输出

小伙伴们看到了FlowHelper这个类,就在老顾的开源项目中;

git地址:https://gitee.com/gujiachun/rb-qps-helper

通过这样的方式,我们就可以改造我们的redis请求client方法了,进行监控埋点就行了。

现在还剩下一个问题,就是我们监控到的数据如何给监控平台?

如何上报监控数据

一开始老顾想着用定时任务的方式,提交给监控平台;最后想了想,那监控平台地址是什么呢?太耦合了。然后想到了我们spring boot中就有一些监控指标。

通过访问http://localhost:1100/actuator/metrics就可以看到监控的指标,再通过http://localhost:1100/actuator/prometheus直接可以看到指标数据。

我们也是可以参考一下的,我们每个实例只要暴露出来,让prometheus自己来拿,而且又是标准流程。具体实现:

引入依赖

实现MeterBinder接口

在利用Gauge 监控类实现就ok了

这样就可以把我们redis实例的请求指标,展现在http://localhost:1100/actuator/prometheus中了

是不是很酷啊?

总结

这篇文章的知识点很多,想要完成我们文章开头的需求,需要这些知识一起组合起来,就能够实现监控的目标了;当然我们需要搭建一个DashBoard界面查看监控数据

我们看每个项目的内存占比请求,以及有没有达到阀值,以及对哪些Key占用比较多的内存,进行排名。也可以监控到每个实例的请求情况,请求数排名,异常数排名等。

可以极大的帮助我们运维和开发人员更多的了解我们的redis使用情况。文章里面只是介绍了核心思想。老顾已经全部实现了,小伙伴们需要源码,可以联系老顾。

redis监控工具_企业级别Redis监控,细化到每个项目实例相关推荐

  1. java redis监控工具_聊聊redis的监控工具

    序 本文主要研究一下redis的监控工具 redis-stat redis-stat是一个比较有名的redis指标可视化的监控工具,采用ruby开发,基于redis的info命令来统计,不影响redi ...

  2. php redis 投票_高可用Redis服务架构分析与搭建

    HorstXuhttps://www.cnblogs.com/xuning/p/8464625.html 基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经 ...

  3. 狂神redis笔记_狂神说redis笔记(三)

    八.Redis.conf 容量单位不区分大小写,G和GB有区别 可以使用 include 组合多个配置问题 网络配置 日志 # 日志 # Specify the server verbosity le ...

  4. 狂神redis笔记_狂神说redis笔记(一)

    一.Nosql概述 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以下问题: 数据量增加到一定程度,单机数据库就放不下了 数据的索引(B+ ...

  5. Redis教程--redis分布式锁+企业解决方案+redis实战

    Redis,目前全国甚至是全球最常用的缓存中间件之一,在现在公司的开发中,可以说是离不开Redis. 在企业越来越注重用户体验的今天,Redis因具有高性能.高响应的特性,大大提升应用的响应速度和用户 ...

  6. linux redis客户端_为什么单线程Redis能那么快?

    我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程.但 Redis 的其他功能,比如持久化.异步 ...

  7. redis 经纬度_原来用Redis实现查找附近的人这么容易

    1. 前言 老板突然要上线一个需求,获取当前位置方圆一公里的业务代理点.明天上线!当接到这个需求的时候我差点吐血,这时间也太紧张了.赶紧去查相关的技术选型.经过一番折腾,终于在晚上十点完成了这个需求. ...

  8. redis 多线程_唬人的Redis多线程,也就那么回事

    不羡鸳鸯不羡仙,一行代码调半天.原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. 周末被一位小同学憋的很窝火. 他要和我探讨一下,redis到底是多线程的还是单线程的.这个 ...

  9. python 运维管理架构_企业运维监控平台架构设计与实现(ganglia篇)

    一.Cacti/Nagios/Zabbix/centreon/Ganglia之抉择 1.cacti Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具. 简 ...

  10. 开源运维管理软件排名_企业运维监控平台架构设计与实现(ganglia篇)

    一.Cacti/Nagios/Zabbix/centreon/Ganglia之抉择 1.cacti Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具. 简 ...

最新文章

  1. deeplearning量化
  2. Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录)
  3. [LeetCode] NO. 100 Same Tree
  4. linux centos yum 报错 获取GPG密钥失败 Errno 14
  5. Eclipse报错:!!MESSAGE Job found still running.......
  6. pyqt5中sender方法介绍_【第五节】PyQt5事件和信号
  7. Fluent Ribbon 第三步 应用程序菜单
  8. LightOJ 1112 - Curious Robin Hood 树状数组
  9. linux -组管理和权限管理
  10. 一起开心集训队第一周训练赛2021/3/14
  11. [Leetcode][第40题][JAVA][数组总和2][回溯][剪枝]
  12. 访问属性与类数据成员
  13. Fragstats计算景观生态指数
  14. 如何用计算机算回归方程,简单线性回归方程与在线计算器_三贝计算网_23bei.com...
  15. esxi安装参考文章及见解
  16. java 打开 覆盖文件_如何用JAVA实现文件的覆盖
  17. bootstrap 检验 法 原理_三种中介效应检验方法及操作步骤
  18. oracle 停掉job,oracle 如何停job
  19. 学python编程从入门到实践方法-python自学Day07(自学书籍python编程从入门到实践)...
  20. 奋斗者——一个高级咨询师是怎样炼成的

热门文章

  1. Atitit 提升开发效率总结 目录 1. declara dynamic Dsl化 fp script 1 1.1. 各种语法新特性 linq等 2 1.2. duck typing。 2
  2. Atitit 嵌入式tomcat 嵌入式服务器 attilax 你感觉艾提拉 总结 比起嵌入jetty ,文件可以自动刷新貌似还不错。。方便调试debug package com.attilax.
  3. Atitit.java eval功能的实现  Compiler API
  4. Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结
  5. paip.proxool连接池 :Attempt to refer to a unregistered pool by its alias 'xx'
  6. PAIP.MYSQL数据库比较
  7. paip.提升ASP编程安全性之脚本部件
  8. Voleon Group:一家『纯』用机器学习策略的对冲基金
  9. 富国基金:基金公司是如何进行数据架构规划与实践的
  10. 真格基金王强:判断一个项目好坏,我会做五个思考!