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

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

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

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

github.com/HobbyBear/easymonitor

按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的办法,如果你有任何新的点子,欢迎留言,我们一起探讨探讨。

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

  1. DB监控-redis监控

    公司的redis业务很多,redis监控自然也是DB监控的一大模块,包括采集.展示.监控告警.本文主要介绍redis监控的主要指标和采集方法. 一.Redis监控系统逻辑 1.DBA通过前台页面添加r ...

  2. 工作不到一年,做出了100k系统,老板给我升职加薪

    看了下自己上一次发技术文还是在6月15日,算了算也是两个来月了.别怕,短暂的离开,是为了更好的相遇. 来到新公司以后啊,发现公司的搜索业务是真的太多了,大大小小有几百个搜索业务.来了之后得先梳理.熟悉 ...

  3. 不懂DevOps!他在升职加薪的那天下午,提出了离职

    不久前我们一个已毕业的学员向班主任老师分享了前几天他遇到的一件事: 一个许久未联系他的朋友突然打电话给他,寒暄了几句后突然说,想来北京找工作,问能不能帮忙给介绍一些工作. 在接下来的通话中,我们学员了 ...

  4. jmeter & 性能测试:从0到实战(实操易用、面试造火箭、升职加薪必备)

    [性能基础] 性能测试概念.术语:https://www.cnblogs.com/uncleyong/p/10706519.html 性能测试流程(新):https://www.cnblogs.com ...

  5. 一文搞懂秒杀系统,欢迎参与开源,提交PR,提高竞争力。早日上岸,升职加薪。

    前言 秒杀和高并发是面试的高频考点,也是我们做电商项目必知必会的场景.欢迎大家参与我们的开源项目,提交PR,提高竞争力.早日上岸,升职加薪. 知识点详解 秒杀系统架构图 秒杀流程图 秒杀系统设计 这篇 ...

  6. 改造断路器集群监控Hystrix Turbine实现自动注册消费者、实时监控多个服务

    在上一篇文章中,我们搭建了Hystrix Dashoard,对指定接口进行监控.但是只能对一个接口进行监听,功能比较局限: Turbine:汇总系统内多个服务的数据并显示到 Hystrix Dashb ...

  7. 《一头扎进》系列之Python+Selenium框架实战篇7 - 年底升职加薪,年终奖全靠它!Merry Christmas

    1. 简介 截止到上一篇文章为止,框架基本完全搭建完成.那么今天我们要做什么呢????聪明如你的小伙伴或者是童鞋一定已经猜到了,都测试完了,当然是要生成一份高端大气上档次的测试报告了.没错的,今天宏哥 ...

  8. 📚C#/.NET/.NET Core推荐学习书籍(升职加薪,你值得拥有)

    前言: 作为一名程序员,我们无时无刻都要考虑着如何通过不断地学习来提升自己的核心竞争力.古人有云:"书中自有黄金屋,书中只有颜如玉",说明了书籍的重要性,没错工作多年来,发现身边那 ...

  9. TDengine在浙商银行微服务监控中的实践

    作者:楼永红 王轩宇|浙商银行    浙商银行股份有限公司(简称"浙商银行")是 12 家全国性股份制商业银行之一,总部设在浙江杭州,全国第13家"A+H"上市 ...

  10. 微服务探索之路04篇k8s增加子节点,metrics资源监控,ingress-nginx域名配置及https配置

    1 k8s增加子节点 1.1 子节点服务器安装docker,使用脚本自动安装 curl -fsSL https://get.docker.com | bash -s docker --mirror A ...

随机推荐

  1. 2021-09-01:三数之和。给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

    2021-09-01:三数之和.给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组. ...

  2. 卷积神经网络(Convolutional Neural Network,CNN)思想 实例 具体代码实现

    在前面我们讨论了神经网络初步,学习了神经网络中最基础的部分:全连接层,并且实现了搭建两层全连接实现图片分类的问题,达到了50%左右的正确率,全连接层的主要思想是构建出一个映射函数,使得前一层的所有输入 ...

  3. JDK动态代理和CGLIB代理有什么区别

    JDK动态代理和CGLIB代理都是实现Spring框架中AOP的代理方式,它们的实现原理和应用场景有所不同, 具体区别如下: 1. 实现原理: JDK动态代理是基于Java反射机制实现的,它要求目标类 ...

  4. SPI通信协议

    1. SPI 通信协议简介 SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设 备接口,是一种高速全双工的通信总线.它被广泛地使用在 A ...

  5. 从0搭建Vue3组件库(十三):引入Husky规范git提交

    为什么要引入 husky? 虽然我们项目中引入了prettier和eslint对代码格式进行了校验,但是多人开发的时候难免依然会有人提交不符合规范的代码到仓库中,如果我们拉取到这种代码还得慢慢对其进行 ...

  6. 曲线艺术编程 coding curves 第四章 利萨茹曲线(Lissajous Curves)

    第四章 利萨茹曲线(Lissajous Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池 ...

  7. 一文吃透Java并发高频面试题

    内容摘自我的学习网站:topjavaer.cn 分享50道Java并发高频面试题. 线程池 线程池:一个管理线程的池子. 为什么平时都是使用线程池创建线程,直接new一个线程不好吗? 嗯,手动创建线程 ...

  8. Python 包安装和 postgresql 的一些问题

    今天安装 hgvs 这个 python 包的时候,遇到几个比较有代表性的问题,记录分享一下. hgvs is a Python package to parse, format, validate, ...

  9. CMU15445 (Fall 2020) 数据库系统 Project#2 - B+ Tree 详解(上篇)

    前言 考虑到 B+ 树较为复杂,CMU15-445 将 B+ 树实验拆成了两部分,这篇博客将介绍 Checkpoint#1 部分的实现过程,搭配教材 <DataBase System Conce ...

  10. CKS 考试题整理 (11)-沙箱运行容器gVisor

    Context 该 cluster使用 containerd作为CRI运行时.containerd的默认运行时处理程序是runc. containerd已准备好支持额外的运行时处理程序runsc (g ...