写点什么

如何解决看起来不可能的工程问题?

  • 2015-08-07
  • 本文字数:2396 字

    阅读完需:约 8 分钟

Scalyr 是一个基于云的服务器日志监控工具。其官方博客曾发表过一篇文章,描述如何使用蛮力方法实现数十 GB 日志数据的秒级查询。在对所有日志进行实时探索性分析时,那是个行之有效的方法,但无法实现 Scalyr 某些功能(如仪表板、预警)所需要的、TB 级数据的秒级查询。近日,前谷歌员工、Scalyr 创建者 Steve Newman 撰文介绍了他们如何遵循如下两个原则解决该问题:

  • 常用的用户行为对应简单的服务器行为;不常用的用户行为则可以对应复杂的服务器行为
  • 寻找一种可以简化关键操作的数据结构

Steve 指出,重定义可以让一个看似不可能的挑战变得容易处理,而这两个原则有助于寻找一种合适的重定义方法。

“不可能”的问题

Scalyr 提供了许多服务器监控和分析工具。为了支撑这些工具,他们将每项功能都实现为一个通用数据集上的一组查询。有些功能需要多个查询。例如,仪表板可以包含任意数量的图表,每个图表又包含多条曲线,而每条曲线对应一个复杂的日志查询。假如一个自定义的仪表板容包含十二个图表,每个图表 4 条曲线,用户选择了一个时间跨度为一周的仪表板视图,而他们每天生成的日志量为 50GB,那么,就需要在 350GB 的数据上执行 48 个查询。没有哪个蛮力算法可以在零点几秒内提供查询结果。同样,预警功能也会产生大量的查询。Scalyr 的日志预警可以触发非常复杂的条件,比如,过去10 分钟内99% 的Web 前端响应时间超过800 毫秒。单个用户可能有成百上千的预警,它们每分钟就需要计算一次。而通常,预警查询对延迟很敏感,需要在几毫秒内响应。

重定义问题

综上所述,仪表板和预警都会产生大量的查询,但都不能接受太长的查询执行时间。所幸,它们有一个共同点:查询事先已知,查询很常用,而新查询很少。按照上文提出的原则,他们需要一种可以简化仪表板和预警查询的数据结构,哪怕创建查询变得复杂也可以接受。

Scalyr 支持多种输出结果,包括文本、数值、直方图和键 / 值数据。不过,仪表板和预警查询总是生成一个数组。每个查询定义了一个时间上的数值函数,可能是“每秒产生的错误信息”、“服务器 X 上的空闲磁盘空间”等。执行查询就意味着使用函数求值,计算结果为数值序列,每个数值对应一个特定的时间区间。

他们通过预计算来简化函数求值过程。他们采用的数据结构非常简单:每个查询对应一个数组。查询每隔 30 秒执行一次,并输出一个数值。他们将那个数组称为“时间序列(timeseries)”。例如,用户仪表板上有一张图表,上面显示了 Web 服务器池产生 5xx 错误的速率。为此,他们创建了一个时间序列,每 30 秒记录一个错误数:

这样,他们就可以快速生成任意时段的图表(为了生成更长时段的图表,他们还以逐步增大的时间间隔存储一些冗余数组)。

时间序列维护

当有日志消息到达时,他们需要对每个相关时间序列进行增量更新。例如,如果一个新的 Web 访问消息包含有介于 500-599 之间的状态码,那么他们就需要增加对应特定时间间隔的“5xx 错误”时间序列的计数器。这里有个问题,就是针对一个新消息,如何确定哪些时间序列需要更新。由于仪表板和预警查询通常使用相同的字段进行过滤,如主机名、指标名,所以他们使用这些字段构建了一棵决策树,通过它快速确定与日志消息匹配的候选时间序列列表。

Steve 举了一个例子。假如有十二个时间序列,遵循下面的消息选择标准:

复制代码
host="frontend1" && metric="memfree"
host="frontend1" && metric="diskfree"
host="frontend2" && metric="memfree"
host="frontend2" && metric=diskfree"
host="backend1" && metric=memfree"
host="backend1" && metric=diskfree"
host="backend2" && metric="memfree"
host="backend2" && metric="diskfree"
pool="webapp" && status >= 400 && status <= 499
pool="webapp" && status >= 500 && status <= 599
pool="api" && status >= 400 && status <= 499
pool="api" && status >= 500 && status <= 599

这些时间序列可以组织成下面这样一棵决策树:

如果收到了下面这样一条消息:

复制代码
host=frontend1
metric=memfree
value=194207

则该消息会从决策树的根节点开始匹配,首先会进入host=“frontend1”host=[any]节点。从host=“frontend1”向下,可以进入metric=“memfree”节点,并匹配到该节点下的时间序列(host="frontend1" && metric="memfree");从host=[any]节点向下,未能找到匹配的分支,不再向下匹配。就是说,在这种情况下,只需要检查时间序列host="frontend1" && metric="memfree"是否需要更新。而对于消息host=frontend1, metric=memfree, pool=webapp,则需要检查 3 个时间序列。

决策树生成算法

决策树生成采用了一个简单的贪婪算法:

  1. 找出所有用于==检验并在至少一个时间序列中出现的字段名(比如,上例子中的 _host_、metric_ 和 _pool)。
  2. 根据每个字段名划分时间序列。如果一个时间序列无法匹配该字段值域中的某个值,那么就将其划分到 [any] 组。计算每个组中时间序列的数量,并找出最大的组。在上例中,_host_ 字段产生了 4 个大小为 2 的组和一个大小为 4 的组([any] 组)。因此,最大组的大小为 4。
  3. 创建一棵树,其根字段要能够使最大组最小化。在上例中,如果以 _host_ 和 _metric_ 字段为根节点,则最大组的大小均为 4;如果以 _pool_ 字段为根节点,则最大组为 [any],大小为 8。因此,可以使用 _host_ 和 _metric_ 的其中一个作为根节点,而不使用 _pool_。
  4. 在每棵子树上递归执行步骤 3。

在 Steve 举的一个例子中,与蛮力算法相比,该算法带来了 33 倍的性能提升。在实际的生产环境中,它对性能的提升更明显。

另外,Steve 还列举了一些具体的实现细节,此处不再一一赘述。感兴趣的读者可以查看原文


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群InfoQ 好读者)。

2015-08-07 08:002725
用户头像

发布了 1008 篇内容, 共 439.9 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

来2023用友BIP技术大会,与北京地铁等领先企业探索数智化转型路径

用友BIP

技术大会 用友iuap 用友技术大会 数智底座 技术底座

想让 ChatGPT 帮忙进行数据分析?你还需要做......

Kyligence

数据分析 指标平台

一站式指标平台 Kyligence Zen 登陆亚马逊云科技 Marketplace

Kyligence

数据分析 指标中台

软件测试/测试开发丨电商业务的性能测试必备基础知识

测试人

软件测试 Jmeter 性能测试 测试开发

软件测试/测试开发丨UI自动化测试,PageObject设计模式

测试人

软件测试 自动化测试 测试开发 UI自动化 pageobject

京东技术专家首推:微服务架构深度解析,GitHub星标120K

程序知音

Java 微服务 springboot java架构 Java进阶

理一理事务实现

Zhang

MySQL 事务 数据库·

公厕一体化智慧管理解决方案@光明源智能科技

光明源智慧厕所

智慧城市

捷行十周年庆,惊喜活动

ShineScrum

重新理解RocketMQ Commit Log存储协议

Apache RocketMQ

RocketMQ 消息队列

小红书自研小程序:电商体验与效果优化的运行时体系设计

小红书技术REDtech

架构 前端

AIGC爆火的背后需要掌握的基础原理

飞桨PaddlePaddle

人工智能 AI 百度飞桨 AIGC

大普微DapuStor完成阿里云PolarDB数据库产品生态集成认证

阿里云数据库开源

国产数据库 polarDB PolarDB-X PolarDB-PG 大普微

数据产品经理的三大底层思维

小鲸数据

数据产品经理 产品思维 数据产品 数据思维 #商业思维

人人可用的敏捷指标工具!Kyligence Zen 正式发布 GA 版

Kyligence

数据分析 Kyligence Zen 指标平台 大数据管理

从一场文学奖评选,看金山文档To B 转型怎么走

B Impact

图文介绍 Windows 系统下打包上传 IOS APP 流程

ios 开发

T 级数据量迁移!知名云巨头如何从 Jira 切换至 ONES?

万事ONES

中南财经政法大学教授施先旺:事项法会计促进业财合一和会计变革

用友BIP

技术大会 业财合一 业财融合 事项会计

在高并发场景下保证数据一致性:sync.Map的并发安全性实践

Jack

上干货!小红书“薯条”业务竞价策略及最优公式详解

小红书技术REDtech

广告 机制策略

MobPush创建推送

MobTech袤博科技

低代码开发,是稳打稳扎还是饮鸩止渴?

引迈信息

前端 低代码 JNPF

天天预约|如何使用「代预约」功能?全在这篇文章里!

天天预约

线上预约 预约工具 预约 预约小程序

实力担当!焱融文件存储再次中标中国移动项目

焱融科技

#高性能 #分布式文件存储 #文件存储 #中国移动

什么是文件传输协议,文件传输协议又是怎么工作的

镭速

尚硅谷CDH 6.3.2视频教程发布

小谷哥

码头风云——5G降临

脑极体

5G

降本增效不是“盲目减脂”,利用亚马逊云科技达成云成本正循环

Lily

例行汇报,看看 FinClip 3月都干了啥

FinClip

如何解决看起来不可能的工程问题?_语言 & 开发_谢丽_InfoQ精选文章