实时数据可视化

实时数据特征 通常来说,可视化的报表会以更高效率的方式将数据背后隐藏的信息传递给我们。通过一个简单的BarChart,我们就很容易对比某商品在第二季度中的销量差异;而通过一条简单的LineChart,则很容易看出员工平均工作时间在某个月份的分布。这些报表都或多或少与时间相关:随着时间的流逝,某项指标会因为各种各样的因素而产生变化。 另一方面,在某些领域,我们需要更高时效性的报表。比如产品的线上指标分析:有多少用户当前在线,主站的负载情况如何,有多少在线交易正在形成等等。此外,很多运维数据也希望有更高的实时性,比如目前服务器的负载如何,过去的5分钟的负载情况又是什么样子的等等。 这类报表的特点是: 高时效性 对于细粒度的指标,数据量可能会很大 过了某段特定的时间段,数据的价值会骤降 比如上图是Mac上的CPU使用情况的实时报表,它展现了一段时间内的各个核上的计算负载。这些信息不断产生,有不断被丢弃,没有人关注一个小时之前的CPU占用,只要能展示出最近几分钟的就好。 基于这些特性,如何存取数据、如何分析度量结果、如何滚动历史数据等等都会遇到和其他图表不尽相同的问题。另外,由于实时数据的可视化与时间是强相关的 – 它本质上必须是一个动态的图表,这与其他的图表类型又有不同。我们在这篇文章中将会讨论这些问题,以及解决这些问题的常见方案。 数据指标 对于实时数据,我们关注不同事件发生的次数,以及事件发生时持续的时长等。我们首先需要定义一些对象: 计数器(counter) 计时器(timer) 标量(gauge) 计数器 计数器涉及需要被记录次数的事件(通常是每发生一次,计数器加一/减一),这类数据的增长/减少规律比较固定,比如: 响应为200的请求 - response.code === 200 从某个session产生的请求 - session.id === 'b1b2b3bab22123bb1a' 计时器 计时器涉及所有应该记录时间长度的事件,通常这类时间我们可以通过引入一个时间段(interval)来计算一些统计信息,比如平均值,方差,标准差,最大值,最小值等。比如: 请求响应时间 - response.time 停留时间 - stay.time 标量 还有一种经常会用到的量,我们不关注过程中它的变化倾向,只关注某个时刻上的数字/状态,比如: 节点是否可用 某一时刻的进程数 某一时刻的CPU负载/内存占用率 数据处理典型流程 对于生产环境,实时数据既可以以日志的形式提供,也可以是来源于事件数据库。日志是最常见的形式,几乎所有的系统都会以各种各样的方式记录日志,大部分的日志会提供滚动机制:日志会被记录到一个固定尺寸的文件中,旧的日志会被滚动的写入到另一个文件(通常还会有配套的定时任务来清理更早的日志等)。另一方面,对于很多基于事件的软件系统中,事件会被写入到数据库中,这些数据也可以用作实时数据可视化的来源。 原始数据往往不能直接用来做可视化展现,通常我们需要做一些预处理,这些过程包括: 原始数据获取 结构化 初步统计 高阶统计 数据结构化 有很多的工具可以帮助我们实现这些步骤,比如我们通过一个简单的配置,就可以让logstash自动将源源不断产生的日志数据写入到statsd(最终周期性的写入到graphite数据库中): input { stdin {} } filter { grok { match => { "message" => "%{DATA:time} %{DATA:status} %{NUMBER:request_time} %{DATA:campaign} %{DATA:mac} %{DATA:ap_mac} %{GREEDYDATA:session}" } } } output { stdout { codec => rubydebug } statsd { host => 'localhost' increment => "airport....

June 17, 2018 · 3 min · 邱俊涛 | Juntao Qiu