陆家靖——收钱吧监控系统的历史发展发展

卢嘉静——2020年复旦大学博士毕业,学习期间获得国家留学基金委资助赴意大利国家核物理研究所联合培养。 开源爱好者,,,,-主要贡献者。 目前就职于上海书前吧,主要负责APM系统的开发。

-1-

介绍

随着分布式系统和微服务的日益发展,系统开发和运维对可观察性的需求越来越迫切。 可观测性一词的起源[1]最初借用自控制理论。 当我们谈论可观察性时,我们通常指以下三个方面:

这三者并不完全是三个独立的概念,而是相辅相成的。 谈到这三个方面,我们总是不得不提到Peter的文章[2],以及最经典的Venn:

-2-

现金吧监控系统的历史发展

手前吧从2017年开始逐步建设应用监控系统,系统建设的主要方向是提供链路跟踪()和性能监控()能力。

在监控系统的选择上,我们尽量使用开源系统:

在接入层,我们用最原始的方式为每个Java模块和组件提供各种工具包。 业务研发同学可以以pom依赖的形式引用到自己的业务服务中,比如:

该系统支撑我们度过了一段业务快速发展的时期,为大量问题的解决和故障诊断提供了一些线索。 但业务发展逐渐开始对这套系统感到不满,主要集中在以下几个方面:

1.由于我们早期使用MySQL作为底层时间序列数据的存储,这在当时似乎是主流解决方案[6],但是我们遇到了很大的性能问题。 毕竟MySQL等数据库提供的存储引擎并没有对此类场景进行优化[7]。 同时MySQL并没有提供丰富的时间序列查询运算符。

PgSQL 9.6.2 数据插入吞吐量随表大小变化[8]

在链路跟踪或应用监控的场景中,我们需要的是高吞吐量和线性性能[9]。 同时,我们还需要添加数据生命周期管理的功能:因为随着新数据的写入,历史数据的价值会随着时间的推移而减少。

2、由于我们需要从数据中导出指标数据,所以我们“神奇地改变”了传输部分的逻辑,在客户端聚合所有非采样数据()然后批量上报,这导致了大量的升级我们。 困难。 尤其是以后将不再允许用户定制开发服务器。

3、业务侧升级依赖需要采集器组件升级支持,导致工作量增加。 同时,还有大量的组件很难通过这种侵入式的方式来支持,或者需要大量的人力成本来开发和适配。

—3—

新一代应用监控系统-Hera

基于以上原因,我们决定开发一套新系统,同时满足几个条件:

存储成本低:能够以低成本存储较长时间的数据,指标至少需要四个星期,链接需要一周,因此我们排除了这种选择,

实时查询性能高、灵活性高:不再使用MySQL等关系型数据库作为时序存储,使用或兼容的存储系统,

优化研发效率:利用字节码编织技术,无侵入埋点,与流程结合更紧密。

链接追踪

分布式链路追踪的概念和心智模型大多受到2010年发表的论文[10]的影响。论文中,作者明确指出了Trace的树形结构,

我们倾向于将跟踪视为 RPC 树。

并提出了Span的概念,

在跟踪树中,树节点是基本的工作单元,我们将其称为跨度。 边aa 跨度及其跨度。

在链接树中,跨度之间存在因果关系和时间关系。

在链路跟踪的系统选择方面,我们比较了当时活跃的几个开源项目。

它是 Uber[11] 于 2016 年开源并捐赠给 CNCF 云原生基金会的链接跟踪平台。

主要组件及控制流和数据流示意图,其中使用Kafka作为缓冲管道。

它受到开源社区的广泛支持,例如

链路追踪后端系统及存储选择

我们主要考虑的是它们对存储系统的支持和扩展能力。

各开源链接跟踪实现的存储能力

In-、MySQL、AWS X-Ray、GCP

Logz.io、APM、卡夫卡

In-、3.4+、5.x 6.x、卡夫卡、gRPC

,通过 grpc-,Logz.io,

H2(内-)、6.X 7.X、MySQL、TiDB

社区具有出色的存储扩展性,并提供基于gRPC[14]的插件机制,方便定制化扩展。

+----------------------------------+                  +-----------------------------+
|                                  |                  |                             |
|                  +-------------+ |   unix-socket    | +-------------+             |
|                  |             | |                  | |             |             |
| jaeger-component | grpc-client +----------------------> grpc-server | plugin-impl |
|                  |             | |                  | |             |             |
|                  +-------------+ |                  | +-------------+             |
|                                  |                  |                             |
+----------------------------------+                  +-----------------------------+

       parent process                                        child sub-process

在具体的存储选择上,我们当时注意到SLS可以支持链路跟踪的后端,并正式提供了实现。 基于这个思路,我们内部实现了gRPC插件版的SLS后端实现,目前在生产环境稳定运行,

[15] 中引入了对 gRPC 插件的本机支持,它在启动时将插件的二进制文件复制到共享存储卷。 同时,我们也积极向社区反馈,为社区提供gRPC插件的自我观察功能(Self):

业务方访问优化

其美妙之处不仅在于其强大的功能,还在于其优秀的代码实现[16]

过去,我们使用侵入式方法来提供应用程序监控访问。 监控服务提供商需要为各个业务方提供插件和模块,并且花费了很大的精力来实现版本兼容。 这种方法缺乏统一的切面,工作机制需要在各个组件上一一“打破”。 它是华为吴胜等人在2015年开源的APM产品,目前已经成为顶级项目。 -Java采用字节码增强技术,提供非侵入式的链​​接埋点,大大降低了使用成本。 在Java中,常用的字节码工具如下:

ASM、BCEL属于Low Level,而CGLib、和更容易使用。

字节码技术的具体分析可以参考上面的答案[17]。

易用性和性能均达到一流水平。

官方性能测试结果。

为了充分利用-Java提供的插件,我们在接口上实现了一套完整的链接跟踪模型。 具体来说,链接跟踪语义包括三层:

添加了一层概念:一个绑定到一个线程,其中包含的所有内容都是在这个线程上创建和销毁的。 这对应于 OT 中的跨度,其中跨度按照创建顺序从 0 开始编号。

陆家靖——收钱吧监控系统的历史发展发展

当然型号也有差异

通过在接口上实现一致的语义,我们可以几乎零成本地移植和使用它的所有插件。我们在使用-Java的过程中也发现了很多问题,我们也积极向社区反馈并做出了一些贡献,主要包括

服务依赖分析

服务依赖分析一直是公司内部业务发展急需的功能。 在服务能力规划、问题诊断、服务依赖判断等方面具有实用价值。 在社区的实现中,建议生产使用Spark批处理[20]来实现全局依赖分析。 还有基于Flink[21]的实时处理,但状态不再维护。

为了实现这个功能,我们使用Flink通过消费Kafka中的链路数据来实时计算服务之间的依赖关系,并通过协议将Tuple格式的数据传输到我们的时序数据库中。

前端根据用户提供的时间窗口,通过Java服务暴露的API进行上下游查询。

未来我们将进一步优化用户交互和通话量的分析和展示。

| 指标监控

在旧版本的监控程序中,我们使用关系数据库作为时序数据的存储系统,这导致我们在查询灵活性和性能方面遇到了很大的瓶颈。 我们在设计新系统时需要做一些调整。 反射。 这几年,云原生的概念逐渐深入人心,已经成为云原生时代监控的事实标准。

经过一些研究,我们认为单机版无法支持超过百万个活跃指标和一周以上的数据存储。 我们主要关注国内技术社区分享较多的 、 、 、 。 但我们对比发现架构非常复杂,给系统运维带来了新的挑战,也存在一定的运维复杂度,并且由于使用对象存储(S3等)作为冷数据存储、查询时可能会导致部分服务不可用,导致返回部分数据。 同时我们还发现国内知乎在QCon 2020上分享了他们的使用经验[22]。 我们最终选择的原因如下:

它在各种性能测试中都表现良好[23]。

作者精通Go语言性能优化,是高性能Go语言组件的作者。

最重要的是VM集群架构简单,易于运维。

VM的各个组件都是独立的,可以水平扩展。 只有核心是有状态的,其他组件是无状态的。

推或拉

对于指标数据,究竟采用主动推送还是被动拉取模型一直存在较大争议[24]。 我们照常使用推送模型,原因如下:

我们目前使用的一些统计数据,

我们还开发了自己的查询面板,限制查询时间范围(最多3天)和查询模式(针对服务作业查询)。

我们自主开发了一些重要的指标插件,其中在应用性能分析和故障定位方面比较实用的维度包括:

由于公司的一些核心服务也部署在ECS上,因此我们实现了基于API的服务发现机制[26],并将其合并到社区版本中。

| 全面拥抱云原生

2020年已经成为分布式操作系统事实上的标准,公司内部大部分服务已经全面迁移到自建集群上。 为了更好地利用新功能,我们在2020年中期启动了集群升级计划,将集群升级到1.16版本(目前升级到1.20),并迁移到阿里云的ACK托管集群。 监控系统的实施将完全取决于系统:

我们提供Java Agent镜像版本,方便业务开发接入。

在生产环境中,我们在容器启动阶段使用[27]注入Java Agent,并通过贡献[28]在两者之间传递Agent Jar包。 这使得我们可以在生产环境中静默升级Agent版本:即使生产环境中的Agent出现问题,我们也可以快速修复问题,然后升级初始化容器。

时序数据库的运维和组件的运维也是通过

我们为-和-组件启用了HPA,这是基于CPU和内存使用情况的水平动态扩展。

集群版本的各个组件也通过[29]进行维护。

—4—

外表

| 实施后采样

由于我们目前采样的是Head-Based方案,一旦链路中间的服务抛出异常而该链路没有被采样,就会出现错误日志和报警,但链路跟踪系统无法查询到该链路的状态,给开发和故障排除带来很大的障碍。 目前业界有几种典型的实施方案,

计划

OT社区的解决方案[30]主要来自公司的贡献[31]。 同时可以通过以下方式实现高扩展性,

(第一层)r:将属于同一个的所有Trace和Log分发到一组固定的下游,

r:等待足够长的时间,将属于一个的所有Span打包并传递给下游。

r:通过预定义的组合策略进行采样

字节跳动解决方案

如果未对链接进行采样,错误的服务将强制滚动采样决策。 然而,在这种情况下,采样决策改变之前的所有链路和其他分支链路的数据都会丢失。

啦啦出行计划

基于Kafka延迟消费+布隆过滤器实现,

实时消费队列:根据采样规则编写布隆过滤器,将所有热点数据写入热点存储。

延迟消费队列:基于布隆过滤器实现条件过滤逻辑,将冷数据写入冷存储。

| 时间序列中的异常检测

时间序列中的异常检测一直是一个热门话题,尤其是对于具有时间周期特征的数据。

计划

2019 年,他们分享了基于实现的简单异常检测 [32]。 例如,如果我们想确定当前时间对应的值,我们可以根据前三周数据的中位数,通过上周的增量进行修正,得到当前时间的预测值,

增量是指指标上周的时间平均值和前移后的时间平均值,例如指上周平均值与上期平均值的差值(表示为作业: :: – job:::1w),用于补偿期间之间平均值的变化。

其他选项

从行业总体发展趋势来看,通过大数据、人工智能手段检测系统异常也是大势所趋。

结尾

本周三晚上8点,卢嘉静和创始工程师高洪涛将做客K+Talk直播间,与大家聊聊一个基于开源生态而诞生的数据库的背景和特殊功能; 开源社区如何帮助项目开发; 和资金将与方式。

如果您有任何相关问题,可以在评论区留言。 编辑会写下来,两位老师会在节目开始后一一解答。

本次演讲嘉宾高洪涛将受邀参加2022K+全球软件研发产业创新峰会,并就“云原生可观测数据存储”主题进行内容分享。 有兴趣的同学可以点击下方阅读原文,了解更多关于峰会的内容。 细节。