写点什么

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

  • 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:002703
用户头像

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

关注

评论

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

我是如何使用Spring Retry减少1000 行代码

越长大越悲伤

Java spring retry spring-retry

ARTS 薪火重启之第二周

渣渣辉

ARTS 打卡第 2 周(8.21~8.27)

向东是大海

ARTS 打卡计划

以财证道,终身成长

少油少糖八分饱

读书笔记 思维 搞钱 致富 有钱人

代码随想录Day48 - 动态规划(九)

jjn0703

KaiwuDB 荣获哈佛商业评论 2023“高能韧性团队奖”

KaiwuDB

KaiwuDB 高能韧性团队

走进大模型

统信软件

人工智能 深度学习 大模型

如何将数据从 InfluxDB 无缝接入到 TDengine 中?来看看

TDengine

tdengine Influxdb 时序数据库

ARTS 打卡第 13 天

自由

科兴未来 | 百万奖金!香港科大,2023人工智能国际创业大赛启动!

科兴未来News

人工智能 双创比赛 香港科大 香港

融云:AI 机器人在社交软件中的花样存在

融云 RongCloud

AI 融云 社交软件 AIGC My AI

k8s发布应用

tiandizhiguai

微服务 云原生 k8s

MurmurHash 真的比 MD5 速度快吗?

向东是大海

murmurhash

融云深度参与「新加坡 GTLC 大会」,连接亚太机遇、开拓国际市场

融云 RongCloud

通信 服务 融云 GTLC 东南亚

专业PDF编辑和阅读软件:PDF Expert for mac激活中文

胖墩儿不胖y

PDF编辑 pdf编辑工具 编辑pdf

代码随想录Day49 - 动态规划(十)

jjn0703

什么是HTTP代理?HTTP代理的作用?HTTP代理怎么设置?

巨量HTTP

代理IP IP地址 http代理 socks5代理

图智能在反洗钱方向的应用实践丨Fabarta 技术专栏

Fabarta

图计算 图分析 反洗钱 图智能 智能风控

国内智慧工业的实践,在一首曙光《长歌行》中

脑极体

AI 算力 数智化 曙光

C++头文件和std命名空间

芯动大师

Kyligence Copilot 登陆海外,斩获 Product Hunt 日榜 TOP 2

Kyligence

指标平台 Kyligence Copilot 数据分成

电商店铺管理,为何需要华为云云耀云服务器L实例

YG科技

避雷干货丨初创或中小企业公司该如何选择云服务器?

YG科技

R语言之数据获取操作

timerring

R 语言

如何在App里拉起小程序?

没有用户名丶

2023年科技趋势展望报告,这几个领域程序员可以恰饭

互联网工科生

人工智能 软件开发 麦肯锡

唯一受邀参会通信服务商!融云出席数字经济头部盛会「中数大会」并发言

融云 RongCloud

人工智能 互联网 通信 数字 融云

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