【升职加薪秘籍】我在服务监控方面的实践(7)-业务维度的redis监控

大家好,我是蓝胖子,关于性能分析的视频和文章我也大大小小出了有一二十篇了,算是已经有了一个系列,之前的代码已经上传到github.com/HobbyBear/performance-analyze,接下来这段时间我将在之前内容的基础上,结合自己在公司生产上构建监控系统的经验,详细的展示如何对线上服务进行监控,内容涉及到的指标设计,软件配置,监控方案等等你都可以拿来直接复刻到你的项目里,这是一套非常适合中小企业的监控体系。

在上一节我们完成了对mysql的监控,这一节我们来讲讲如何对redis进行监控,同样的,我们需要让监控指标更好的反映业务情况,由于我们生产上的服务是部署到云环境的,常见的redis监控指标,云服务商已经提供了,所以没必要重读对其造轮子了。

我们新建立的指标是redis key维度的qps,这样在看到redis 总qps升高时,能一眼看出是哪些key造成的,并根据key定位到具体业务代码。

监控系列的代码已经上传到github

github.com/HobbyBear/easymonitor

redis_14">按key维度建立redis监控

要想让redis的监控指标能更好反映业务情况,那就只有按key维度建立监控指标,这样能知道是哪部分业务访问redis最频繁。

想想我们通常使用redis时,建立key的规范,是不是一般都是 服务名:业务名:业务key 这种形式,其中业务key可以是uid,也可以是其他类型id,如果按完整的key建立redis的qps监控,将会导致key维度过多,影响prometheus聚合性能,并且由于key维度过于分散,不好定位到具体业务,所以我们需要在记录指标时,需要将业务key去掉进行记录。比如对key webapp:login:uid1 和 webapp:login:uid2 的操作都将记为webapp:login 对redis的操作,这样便能很好的反映业务访问redis的情况

下面,我们来看看如何实现这段逻辑。

实现方式

我们的项目用的是go-redis这个库,它提供了一个WrapProcess函数可以在命令执行前后添加一些自定义的操作。如下所示,我在命令执行前记录了对应key的访问次数。其中matchkey则是将应用程序的key排除掉业务key获得最终的只携带业务名的redis key。

func (r *redisMonitor) AddRedisHook(client *redis.Client, redisInstanceName string) {  
   client.WrapProcess(func(oldProcess func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {  
      return func(cmd redis.Cmder) error {  
         start := time.Now()  
         dealKey, match := matchKey(truncateKey(100, strings.TrimSuffix(strings.TrimLeft(fmt.Sprintf("%v", cmd.Args()), "["), "]")))  
         if match {  
            // 记录redis前缀key的访问次数
            RecordClientCount(TypeRedis, cmd.Name(), dealKey, redisInstanceName)  
         }  
         err := oldProcess(cmd)  
         cacheWrapper(cmd, start, err, redisInstanceName)  
         return err  
      }  
   })  
  
}

matchKey 的实现逻辑是看应用服务传来的redis key是不是在监控的key范围内,是的话,才会对key访问次数进行监控,所有需要监控的key都是monitorKeys 这个切片里保存的。


var (  
   monitorKeys = make([]string, 0, 100)  
)


func matchKey(key string) (string, bool) {  
   var (  
      matchKey string  
   )  
   for _, k := range monitorKeys {  
      if strings.Contains(key, k) {  
         matchKey = k  
         break  
      }  
   }  
   if len(matchKey) == 0 {  
      return "", false  
   }  
   return getCmdFromKey(key) + " " + matchKey, true  
}

应用服务会将它需要监控的key写入到monitorKeys 这个切片里,写入时只写业务前缀,像下面这样。

infra.RedisMonitor.AddMonitorKey("webapp:login")

方式弊端

不过上面的方式弊端很明显,那就是需要业务方较大的改动,基本上每次定义redis key时,都需要手动添加一下到monitor keys里,侵入性比较大,不过我目前还是没有想好特别好的方法让redis比较透明的按业务范围监控key的办法,如果你有任何新的点子,欢迎留言,我们一起探讨探讨。


http://www.niftyadmin.cn/n/4962893.html

相关文章

基于swing的在线考试系统java jsp线上试卷问答mysql源代码

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 基于swing的在线考试系统 系统有2权限:管…

分布数据并行计算(单机多卡)训练记录

首先,我们先把我们的pytorch版本提升到2.0.1,这样会防止很多不必要的报错(但这样的坏处就是我们没有办法使用nvidia-apex进行加速了,除非等到版本的更新 DistributedSampler 我们使用分布数据采样器来保证我们的每个进程(每一块…

Linux 安装mysql(ARM架构)

添加mysql用户组和mysql用户 安装依赖libaio yum install -y libaio* 下载Mysql wget https://obs.cn-north-4.myhuaweicloud.com/obs-mirror-ftp4/database/mysql-5.7.27-aarch64.tar.gz安装mysql 解压Mysql tar xvf mysql-5.7.27-aarch64.tar.gz -C /usr/local/ 重命名 …

2022美亚杯个人赛复刻

案件详情 于2022年10月,有市民因接获伪冒快递公司的电邮,不慎地于匪徒架设的假网站提供了个人信用咭资料导致经济损失。 警方追查下发现当中一名受骗市民男子李大輝 (TaiFai) 的信用卡曾经被匪徒在区内的商舖购物。 后来警方根据IP地址,锁定…

石油和天然气行业如何实现数字化转型和工业4.0

石油和天然气行业的数字化转型正面临着前所未有的挑战和机遇。尽管过去相对滞后,这个复杂而庞大的行业正逐渐意识到数字化的紧迫性,以应对市场变化、降低运营成本、提高效率和确保可持续性。然而,数字化转型的进程并非一帆风顺,行…

微服务中间件--http客户端Feign

http客户端Feign http客户端Feigna.Feign替代RestTemplateb.自定义Feign的配置c.Feign的性能优化d.Feign的最佳实践分析e.Feign实现最佳实践(方式二) http客户端Feign a.Feign替代RestTemplate 以前利用RestTemplate发起远程调用的代码: String url "http:…

基于卷积神经网络的种子等级识别

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 基于GUI的卷积神经网络和长短期神经网络的语音识别系统 代码下载链接:基于MATLABGUI编程的卷积神经网络和长短期神经网络语音识别系统…

打造完美的跨境电商系统,助力企业海外扩张!

打造理想的跨境电商系统:关键要素和优势 在如今全球化和互联网时代,跨境电商已成为企业迅速发展的必然选择。打造一套完美的跨境电商系统,不仅可以提升企业的国际竞争力,还可以助力企业实现海外市场的扩张和增长。本文将为您介绍…