NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇

时间:2022-10-30 23:09:35

上期回顾

上一期:NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇

上次介绍了NanoProfiler的基本功能,提到,NanoProfiler实现了MiniProfiler欠缺的多线程和异步代码的支持,并且,由于采用不同的内部数据结构,NanoProfiler拥有更高的执行效率,而且占用极少的系统资源,因此,是适合在生产环境下使用的性能监控类库。并且,我们也提到了,NanoProfiler设计理念的另一大不同,即面向大数据分析。

这一期,我重点介绍一下NanoProfiler之大数据分析理念。

面向大数据分析的数据结构

上一期,我们曾经简单介绍了,NanoProfiler和MiniProfiler相比的,由于采用了不同的数据存储结构,因而具有更高的执行效率。这一节,首先,详细介绍一下NanoProfiler的数据存储结构。

首先,我们先来举一个简单的例子。假设我们有个对APP1的Web页面请求R,请求R的执行过程中,我们有以下几个Step:R-step-1, R-step-2,R-step-2的执行过程中,调用了APP2的一个WCF服务方法W.而W的执行过程中,又有以下几个Step:W-step-1, W-step-2。

如果使用MiniProfiler进行性能监控,R这个请求,可以得到类似下面的一整个树形结构的数据:

R (start, duration)
|
- R-step-1 (start, duration)
|
- R-step-2 (start, duration)
|
- W (start, duration)
|
- W-step-1 (start, duration)
|
- W-step-2 (start, duration)

start和duration表示,每个步骤相对整个请求开始的开始时间和执行时间。

MiniProfiler运行时,在内存中对一个逻辑请求,维护这样一个树形结构的数据,即使执行过程中有WCF调用,它也会通过WCF的EndpointBehavior和MessageInspector,将在APP2中执行的WCF调用内部的性能监控数据,返回并且合并到APP1的R请求这棵树结构数据。如果,当前请求包含一些前端的性能监控步骤,所有前端性能监控数据,也会实时保存到同一个内存中的数据结构中。如果要持久化,也会将整棵树,保存为一个JSON。这样做,虽然方便查看整个请求整体的性能数据,但是,不可避免的有以下一些问题:

  • 因为要在内存中维护这棵树,如果有并行的步骤,运行时,不得不加锁,因而,执行效率较差;
  • 跨应用(比如例子中APP1的请求调用了APP2的WCF)的调用,需要被调用方,将监控数据返回到调用方,增加了不必要的数据传输,因而,影响执行效率,也占用了不必要的内存(更何况,如果这个WCF服务是One-Way的呢?);
  • 如果同一个逻辑请求包含相关的多个子请求(比如,包含多个前端的AJAX请求和后端的WCF调用),R请求至少要等待所有这些子请求的性能监控数据全都返回并且合并之后,才能通知R请求的调用方R请求执行完毕,但是,这些子请求如果不是为了性能监控,R请求本身的执行逻辑,其实本来未必有依赖,因此,这样的机制,既导致了额外的内存开销,还导致了对R请求本身的执行时间的影响;
  • 将整个逻辑请求的性能监控数据整体保存为一个JSON,虽然方便后期查看这个请求本身的数据,但是,由于这个整体的树结构嵌套层次数量不可控,因此,不利于后期的数据分析,比如:如果我想分析某一天,上例中W这个WCF服务总的执行次数,平均执行时间等,将不得不需要解析和索引每一个嵌套层次的JSON,很难保证执行效率;

那么,NanoProfiler是怎么存储性能监控数据的呢?

假设还是上面的例子,如果使用NanoProfiler代替MiniProfiler,在在APP1的内存中,请求R的性能监控数据结构大概是下面这样的:

R (type=web, start, duration, tags=request_token_of_R) :{
Steps: [
R-step-1 (type=step, parent=R, start, duration),
R-step-2 (type=step, parent=R, start, duration)
],
Customs: [
W-client (type=wcf_call, parent=R-step-2, start, duration)
]
}

同时,在APP2的内存中,有另一个WCF服务调用W的性能监控的数据结构:

W-server (type=wcf_server, start, duration, tags=request_token_of_R) : {
Steps: [
W-step-1 (type=step, parent=W-server, start, duration),
W-step-2 (type=step, parent=W-server, start, duration)
],
Customs: [
]
}

看出区别了吗?

  • 首先,NanoProfiler的数据结构不是一棵树,而是一些平面的数组,因而,即使要维护一棵树的父子关系(即使在有并行步骤的情况下),也无需关心树结构的层次嵌套,只需要将每个步骤的监控结果,添加到平面数组,执行效率显然更高;

  • R和W虽然属于同一个逻辑请求,但是,他们分别在自己的APP里维护自己的性能监控数据,仅通过tags的方式进行关联,好处是什么?很明显,R执行结束,无论子请求是不是One-Way的,都不需要等待相关的其他子请求完成,并且返回性能监控数据就能通知调用端执行完毕,存放监控数据的内存也能立即释放,所以,即使开启了性能监控,也基本不会影响R请求的执行时间和整体的内存消耗;

  • NanoProfiler,并不将每个请求的监控数据整体保存为一个对象,而是会将每一个步骤,保存为一个对象,例如,对上面的例子,我们一共会得到下面这些事件数据:

    • R (type=web, start, duration, tags=request_token_of_R)
    • R-step-1 (type=step, parent=R, start, duration)
    • R-step-2 (type=step, parent=R, start, duration)
    • W-client (type=wcf_client, parent=R-step-2, start, duration)
    • W-server (type=wcf_server, start, duration, tags=request_token_of_R)
    • W-step-1 (type=step, parent=W-server, start, duration)
    • W-step-2 (type=step, parent=W-server, start, duration)

上面这样的存储结构有什么好处呢?

  • 首先,没有嵌套层次,非常容易被解析和存储;
  • 即使,对同一个逻辑请求的性能监控,被拆分成多个事件,但是,他们之间可以方便的通过每个事件的tags和parent属性的值进行关联和追踪;
  • 方便只对某一种type的监控数据进行宏观的大数据分析,比如,我要分析一天之内W这个WCF服务的调用次数和执行的平均时间非常容易;
  • 由于避免了不同子请求的性能监控数据之间的直接耦合,而通过tags进行关联,方便和其他异构log系统的数据,进行大数据整合,例如,对这个请求的微观和宏观性能分析,可以包含跨应用,跨服务器甚至集群的异构的异常日志,前端日志,服务器日志等等(只要,这些相关日志之间能够通过相同的request_token进行关联),而不用像MiniProfiler那样,只局限于单个请求的数据,只局限于MiniProfiler能支持的类库产生的监控数据的整合,这就大大提高了大数据分析的灵活性;
  • 事实上,在NanoProfiler中,对需要监控性能的每一个步骤,无论是代码步骤,还是DB请求,WCF请求,都可以指定0到多个tag,请求的token作为tag只是一种应用方式,我们完全可以对某个步骤,指定其他各种目的(无论是业务的还是非业务)的tags,实现各种维度的微观和宏观的大数据分析;

面向大数据分析的数据存储

数据结构Ready了,下面是怎么存储的问题。NanoProfiler的性能监控数据,由上面举例的相同结构,但类型可能不同的平面事件数据组成。我们假设,平均每一个逻辑页面请求会产生20个event,如果,某个APP一天有500万页面请求(包含各种服务调用,AJAX请求等等),就会有1亿个event。这个数据夸张吗?对一个稍大一点互联网应用来说,一点也不夸张。所以,这里的数据,必然有那么点“大”的。这还是只一个APP,如果,有10个100个APP呢?

对于超大量的类日志数据,传统的文件系统,或者关系型数据库,很可能已经不能很好的胜任了。不仅仅读写性能未必能达到要求,数据的维护也会成为大问题。

所以,我们需要特别适合类日志数据存储的数据存储方案。很幸运的,很多走在前面的大数据公司,已经铺了不少路,我们现在有Cassandra,有HBase这些本身就是类日志存储的NOSQL数据库,非常适合类日志的超大量密集写操作的数据存储。

以Cassandra为例,早在3年前,就已经可以达到每秒超过百万次的写操作,这里也有一个中文的翻译。Netflix当时使用了288个节点达到的每秒百万写,而最近Datastax公司的测试,已经能达到1000个Cassandra节点的线型性能扩展了,可以简单计算,即使三年后,Cassandra单个节点的写并发能力没有增加,支持每秒几百万的写操作也是很轻松的事情。

大数据分析工具

说起大数据分析,大家一定首先想到Hadoop。但是,如果各位做大数据分析,却还没尝试过elasticsearch和kibana,那真的有点out了。

园子里关于kibana的介绍文章也早就有不少了,我就不说太多安装使用细节了。

//本文完

NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇的更多相关文章

  1. NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇

    背景 NanoProfiler是一个EF Learning Labs出品的免费性能监控类库(即将开源).它的思想和使用方式类似于MiniProfiler的.但是,设计理念有较大差异. MiniProf ...

  2. NanoProfiler - 适合生产环境的性能监控类库 之 实践ELK篇

    上期回顾 上一期:NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇 上次介绍了NanoProfiler的大数据分析理念,一晃已经时隔一年多了,真是罪过! 有朋友问到何时开源的问题 ...

  3. Java生产环境下性能监控与调优详解视频教程 百度云 网盘

    集数合计:9章Java视频教程详情描述:A0193<Java生产环境下性能监控与调优详解视频教程>软件开发只是第一步,上线后的性能监控与调优才是更为重要的一步本课程将为你讲解如何在生产环境 ...

  4. Java生产环境下性能监控与调优详解

    1:JVM字节码指令与 javapjavap <options> <classes>cd monitor_tuning/target/classes/org/alanhou/m ...

  5. 生产环境zabbix3&period;2上亿的表数据通过表分区的方式进行历史数据清理

    生产环境zabbix3.2上亿的表数据通过表分区的方式进行历史数据清理 zabbix服务器经常报警io过载,在报警的时候发现是数据库在删除历史数据时耗时较长 数据库积攒了大量的历史数据信息,主要集中在 ...

  6. 【HADOOP】&vert; 环境搭建:从零开始搭建hadoop大数据平台(单机&sol;伪分布式)-下

    因篇幅过长,故分为两节,上节主要说明hadoop运行环境和必须的基础软件,包括VMware虚拟机软件的说明安装.Xmanager5管理软件以及CentOS操作系统的安装和基本网络配置.具体请参看: [ ...

  7. Android 性能监控系列一(原理篇)

    欢迎关注微信公众号:BaronTalk,获取更多精彩好文! 一. 前言 性能问题是导致 App 用户流失的罪魁祸首之一,如果用户在使用我们 App 的时候遇到诸如页面卡顿.响应速度慢.发热严重.流量电 ...

  8. 直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控

    线上服务的有效监控和数据收集,一直是后端服务离不开的话题.直播作为一种经典的分布式系统,监控以及数据收集更是必不可少的工作.如何对海量的服务集群有效的监控和保活,又如何抓取集群中的碎片数据中来优化服务 ...

  9. Sentry 监控 - Discover 事件大数据查询分析引擎

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

随机推荐

  1. 一段神奇的代码(python 2&period;7)网上抓图小Demo

    二话不说 先上代码: #coding=utf-8 import urllib import re import time global x x = 1 def getHtml(url): page = ...

  2. 浅谈echo、print、var&lowbar;dump&lpar;&rpar;、print&lowbar;r&lpar;&rpar;的区别

    1.echo 和 print 的区别 共同点:首先echo 和 print 都不是严格意义上的函数,他们都是语言结构;他们都只能输出 字符串,整型跟int型浮点型数据.不能打印复合型和资源型数据: 而 ...

  3. &num;Node&period;js的fs导入遇到的问题和解决方案

    一直在使用VS Code,今天打算用Node.js进行文件IO时候遇到了一些问题,fs是Node.js的核心功能之一,一开始我用Javascript编写fs模块的导入. var fs = requir ...

  4. CF932G Palindrome Partition

    思路 首先把字符串变为\(S[1]S[n]s[2]s[n-1] \dots\) 这样原来的一个合法的划分方案就变成了用k个长度为偶数的回文子串划分的方案, 然后直接DP,对i位置,可转移的位置就是它的 ...

  5. 探索SQL Server元数据(三):索引元数据

    背景 在第一篇中我介绍了如何访问元数据,元数据为什么在数据库里面,以及如何使用元数据.介绍了如何查出各种数据库对象的在数据库里面的名字.第二篇,我选择了触发器的主题,因为它是一个能提供很好例子的数据库 ...

  6. POJ 3461 Oulipo&lpar;KMP&comma;模式串在主串中出现次数 可重叠&rpar;

    题意:给你两个字符串p和s,求出p在s中出现的次数. 显然,我们要先把模式串放到前面,之后主串放后面,中间隔开,这样就可以根据前缀数组的性质来求了. 我先想直接把p接到s前面,之后求Next数组对st ...

  7. Linux下出现permission denied的解决办法

    Linux下经常出现permission denied,原因是由于权限不足,有很多文章通过chmod命令更改权限为777,但是很不方便也不适合新手,简单粗暴的方法如下: 命令行中输入 sudo pas ...

  8. python之爬虫&lowbar;并发(串行、多线程、多进程、异步IO)

    并发 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢 import requests def fetch_async(url): res ...

  9. &lbrack;BZOJ4561&rsqb;&lbrack;JLOI2016&rsqb;圆的异或并&lpar;扫描线&rpar;

    考虑任何一条垂直于x轴的直线,由于圆不交,所以这条直线上的圆弧构成形似括号序列的样子,且直线移动时圆之间的相对位置不变. 将每个圆拆成两边,左端加右端删.每次加圆时考虑它外面最内层的括号属于谁.用se ...

  10. IE9以下不支持placeholder属性

    jquery.placeholder.min.js 这个js可以去这个网站搜索https://www.bootcdn.cn/jquery-placeholder/ 使用这个jquery.placeho ...