AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

Salesforce 如何连续分析数以万计的生产服务器

  • 2020-03-17
  • 本文字数:3791 字

    阅读完需:约 12 分钟

Salesforce如何连续分析数以万计的生产服务器

本文最初发布于 Salesforce 工程博客,经原作者授权由 InfoQ 中文站翻译并分享。


Salesforce CRM 应用程序是一个运行在 JVM 上的多租户单体应用,整个生产环境运行在数万台服务器上。这些主机每天处理数十亿个请求,为不同的租户处理报告查询和各种同步或异步任务。每天都有成千上万的工程师对单库源代码进行修改。此外,对底层数据以及 Salesforce CRM 之上的用户自定义扩展进行的大量更改,可能会导致我们在生产环境中观察不同服务器/集群时看到不一致的行为。

挑战和解决方案

当功能中断或性能退化时,准确确定在那天的关键点上发生了什么,对于调试非最佳行为至关重要。单个单体应用程序负责处理这么多不同租户的多样化要求,每个工作线程都会有丰富的上下文数据(例如,租户 ID、用户、URL),为了能够迅速查明生产环境的问题,必须维护好这些数据。


我们的团队在 Salesforce 主要职责是,确保在任何时候都可以从每个生产服务器获得正确的诊断数据。我们开发了一个完全自主的应用程序性能管理系统,不断地从所有生产服务器捕获性能分析和诊断数据。


我们遇到了一些 Salesforce 应用程序特有的问题,但是,我们相信这些问题的解决方案可能对构建类似系统的工程师有用。这篇文章简要地描述了一些主要的挑战和我们采用的解决方案。

扩展性

挑战

代理在数万个 JVM 上运行。每个数据中心都有很多主机,从每个主机都会捕获大量的数据,再加上跨数据中心的网络延迟,这意味着我们无法有效地将所有数据持久存储到一个集中化的存储解决方案。在所有服务器上,每秒写次数达 300 多万次,每一次有几 KB 的数据,总计超过每秒 1GB。这种速率对于单个网络或存储解决方案来说太高了(在合理的成本下)。

解决方案

将负载分布到多个数据中心,然后从一个可以访问所有数据中心并知道如何将请求路由到特定数据中心的中心站点协调检索。用户请求指定需要哪些主机集群的性能分析数据,中心站点将请求路由到正确数据中心内的相应服务器。这为调查工程师提供了良好的体验,依靠一个中心站点查看整个站点的所有性能分析数据。我们在存储中维护一个路由查找表(可以由系统管理员在运行时修改),将集群映射到相应的数据中心。

容错

挑战

对于 JVM 性能分析来说,许多最重要或最有趣的时间段都是在极端状况下,要么是故障原因,要么是故障征兆。当慢速请求堆积、客户工作负载模式改变或贪婪作业分配太多大对象时,内存和 CPU 会急剧增加。在紧急关头,JVM 可能会宕机或终止,或丢失网络连接;因此,如果只是将性能分析数据缓冲到内存中,而不是立即将其持久化到某种形式的永久存储中,那么性能分析数据可能会丢失。

解决方案

为了避免丢失最重要的数据,同时保持批量保存数据的能力,需要以弹性的方式缓存数据。当应用程序受到威胁时,将缓冲区保存在内存中可能容易丢失数据,因此,我们实现了一个磁盘上的循环缓冲区。从 JVM 捕获样本(线程转储和相关上下文)后,立即将它们保存在本地磁盘上。这样,在服务器或网络故障时,可以防止在将数据转发到集中存储之前丢失缓存数据。为了防止在长时间停机时对磁盘空间产生负面影响,缓冲区的循环特性是必须的,因此,缓冲区会根据配置的时间间隔覆盖。

多语言运行时支持

挑战

Salesforce 为 Apex 编程语言提供了一个定制的解释器,客户可以使用该解释器来添加特定于其组织的自定义业务逻辑。在处理生产环境的问题时,能够分析用户定义的扩展很有价值,这可以减少服务成本或响应时间。我们的解决方案必须能够捕获和表示性能分析和可观测数据,而不用管底层的语言是什么。此外,Salesforce 运行着各种基于 JVM 的服务,其中许多都是很好的性能分析候选对象。因此,我们的解决方案必须能够适应各种各样的 JVM,而不能仅仅适用于 CRM 的单体应用。

解决方案

我们的系统设计没有对所使用的编程语言做任何假设。底层实现语言作为另一个元数据附加到所有性能分析数据点,允许用户基于该语言进行查询。此外,为了能够支持不同的语言和环境,实现多语言支持,用于抽象堆栈跟踪和元数据的数据结构是以一种通用且足够灵活的方式表示的。

上下文元数据

挑战

通常情况下,领域专属上下文会触发调查和调试:报告花费的时间比它应该花费的时间长、请求失败或花费的时间太长、特定于租户的性能问题或加载了畸形数据的页面。允许调试工程师使用这个领域专属上下文来驱动他们的调查,可以极大地加快得出结论的过程。


如果工程师已经知道花费很长时间才能加载的 URL,那么搜索与该 URL 相关的堆栈跟踪信息可以让他们快速地将视野缩小到相关数据。这样就省去了许多常见的起始步骤,比如根据线程 ID 搜索日志和交叉引用 URL。

解决方案

我们的实现会针对每个线程收集领域专属上下文和它收集的堆栈跟踪信息。我们将流程设计得足够通用,以便每个经过性能分析的服务都可以确定将哪些相关信息映射到每个线程抽样:一个 JVM 处理请求,这些请求可能附加了 URL、HTTP 方法和请求参数;一个 JVM 运行批处理作业,这些作业可能附加了作业名称、ID 和作业类型。领域专属上下文与标准性能分析元数据一起存储,完全索引,并允许在查询时添加适当的过滤器,以避免额外的干扰。


此外,我们还允许对堆栈跟踪信息进行深度搜索,用户可以在其中通过正则表达式查找包含特定栈帧的抽样数据。这是最有用和最受欢迎的查询参数之一,因为在许多情况下,开发人员只对某些代码路径感兴趣,而不是对应用程序中执行的所有代码的抽样数据感兴趣。特性团队知道其模块的入口点(接口/API),因此,他们可以使用这些知识验证其特性在生产环境中的行为,从而提供一个反馈循环来识别潜在的进一步优化机会。

高线程数

挑战

为了及时处理请求或活动的激增,Salesforce 应用程序维护着大量的活动线程池。这将导致一定百分比的活动线程始终处于空闲状态,不做任何重要的工作。各个服务器上各种类似的情况会使这种影响成倍地增加,因此,任何给定的线程转储都至少包含 1500 个单独的线程。来自这些线程的数据将很快淹没我们的存储基础设施。

解决方案

抛弃捕获的那些空闲线程的数据!我们的目标不是在给定时刻完美地表示每个线程,而是表示在给定时刻正在进行的工作。过滤掉那些无所事事地等待工作的线程,或者是在检查一个值时休眠的线程,可以让我们更频繁地分析数据并更长时间地保存数据。在给定的 JVM 中,我们能够过滤掉 99%的初始线程转储。供参考:在整个生产环境中,我们平均每分钟丢弃数亿的堆栈跟踪信息,每分钟仅保留 500 万跟踪信息供以后使用。

压缩和去重

挑战

代码库经常变化,但是整体来看,它们的变化并不大。此外,在特定的时期内,最常执行的代码基本上没有变化。因此,线程转储包含大量的重复数据。这就提出了一个挑战,将性能分析数据直接捕获并存储会导致巨大但合理的存储需求。

解决方案

将数据分割成离散的部分,并跟踪数据的关系,使我们能够尽可能减少存储线程转储时的重复。选择正确的存储解决方案和正确的存储模式至关重要,这样构建的系统可以减少重复,从而使存储这些数据成为可能。我们在HBase上使用Apache Phoenix构建了相关的表。每个数据中心只存储每个堆栈跟踪信息帧一次,并且为了实现快速查找建立了索引。堆栈跟踪信息也只存储一次。堆栈跟踪信息以栈帧 ID 列表的形式存储,并根据它们的散列 ID 值建立索引。在给定的线程转储中,各个线程抽样被存储为时间序列事件,堆栈跟踪信息记录为对散列 ID 值的引用。所有这些结合起来,使我们减少了堆栈跟踪信息(任何给定线程转储的最大部分)存储的空间占用。


为了减少 HBase 集群上的写入负载,我们保留了可配置的堆栈跟踪信息和栈帧缓存。我们可以检查这些缓存,看看堆栈跟踪信息是否已经写入,而不是写入每条堆栈跟踪信息或栈帧。这些缓存消除了 99%的栈帧写入和 75%的堆栈跟踪信息写入。

回归识别

挑战

对应用程序(例如新版本)进行更改后的回归检测和识别是我们希望解决的主要问题之一。回归可能是由于对特定代码路径的调用频率增加,或者是由于子系统的运行时性能下降。

解决方案

通过将性能分析数据保存较长的时间(我们目前的 TTL 为 90 天),我们的系统支持在不同的版本、库和平台升级以及对软件的其他(较长时间有效)更改之间进行比较分析。


可以在运行时进行短时间(少于一小时)的比较分析。这些数据被表示为火焰图和树形差异图。这种可视化使得工程师可以很容易地识别代码路径的差异,在他们调查的时间段内找出罪魁祸首。


此外,对于时间跨度较大的查询,因为通过如此大量的数据在运行时确定回归是不可行的,所以我们开发了一种通用的作业和报表框架,用户可以定义和调度在所有数据集上执行的作业,作业结果会被持久化,并且可以从 UI 上查看。作业框架内置支持与 Salesforce 其他内部工具的交互,使我们能够将性能分析数据与日志、系统级和应用级监控数据、站点可靠性工具等关联起来。

未来工作

我们正在寻求集成Java Flight Recorder,以添加 CPU 性能分析以及提供更高的采样率支持。这将使我们可以准确地度量在不同代码路径上花费的 CPU 周期的数量,帮助我们关联成本与系统中单个组件的服务价值。此外,我们正在考虑与Async Profiler集成,以便为非 JVM 应用程序提供更好的支持。


我们的下一篇博文将介绍使用诊断数据收集代理捕获可观测数据的方法。该文将详细介绍我们如何设计一个低开销、可配置的代理来从生产服务器收集系统和应用程序诊断数据。


原文链接:


How to Continuously Profile Tens of Thousands of Production Servers


2020-03-17 09:441663

评论

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

[教你做小游戏] 只用几行原生JS,写一个函数,播放音效、播放BGM、切换BGM

HullQin

CSS JavaScript html 前端 9月月更

数据治理的内核:元数据管理

小鲸数据

数据治理 数字化 元数据 元数据管理 元数据管理平台

C++后台开发学习路线(已多人拿下腾讯后台开发)

C++后台开发

后台开发 后端开发 C++后台开发 C++开发 腾讯后台开发

设计模式的艺术 第十二章装饰设计模式练习(开发一个数据加密模块,可以对字符串进行加密。最简单的加密算法通过对字母移位来实现,同时提供了稍复杂的逆向输出加密和更高级的求模加密。用户先用最简单的算法加密,如果觉得不够,可以使用其他算法进行二次加密和三次加密)

代廉洁

设计模式的艺术

小六六学Netty系列之Java NIO(一)

自然

网络 9月月更 neety

完美!华为大佬手码20w字Redis全栈小册,原来Redis性能可压榨到极致

Java全栈架构师

数据库 redis 程序员 面试 后端

SpringCloud 配置中心(Nacos)的简单使用

nacos SpringCloud 配置中心 9月月更

Java进阶(三)Java安全通信:HTTPS与SSL应用配置

No Silver Bullet

https SSL证书 9月月更

什么是 SAP Business Function

汪子熙

SAP abap Netweaver 业务流程驱动 9月月更

《游戏机图鉴》:发展、继承、崩溃、复兴,游戏机的前世今生

图灵社区

科普 游戏机

费时3个月啃烂了这份Redis技术笔记,我成功上岸进了字节

收到请回复

redis 架构 语言 & 开发 Java core redis 底层原理

分布式技术难学?谷歌大神首发纯手撸ZK+Dubbo笔记,网友看完直呼NB

收到请回复

Java zookeeper 架构 分布式 语言 & 开发

设计模式的艺术 第十一章组合设计模式练习(开发一个界面控件库。界面控件分为两大类:一类是单元控件,例如按钮、文本框等;另一类是容器控件,例如窗体、中间面板等。试用组合模式设计该界面控件库)

代廉洁

设计模式的艺术

首次发布!Java面试八股文让569人成功进入大厂,堪称2022最强面试八股文核心知识版!

退休的汤姆

Java 程序员 面经 秋招 Java八股文

上车上车,快速搞懂Redis 过期策略和内存淘汰策略

知识浅谈

redis 过期策略 9月月更

秋招国内大厂最牛的Java面试八股文合集(全彩版),不接受反驳

退休的汤姆

Java 程序员 面经 Java工程师 秋招

深入思考Schema管理的几个基本问题

HackMSF

Java工程师丨面试必会进程线程问答

陈橘又青

Java 面试 9月月更

数据存储与物联网

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

【大话 C 语言】春眠不觉晓,函数知多少?

Albert Edison

递归 C语言 函数 开发语言 9月月更

中小企业集成AI人工智能的窘境

felix

人工智能 中小企业 开放应用模型

软件复杂性的来源与应对

源字节1号

软件开发 前端开发 后端开发 小程序开发

设计模式的艺术 第十三章外观设计模式练习(为新开发的智能手机控制与管理软件提供一键备份功能。通过该功能可以将原本存储在手机中的通讯录、短信、照片、歌曲等资料一次性地全部复制到移动存储介质(如MMC卡或SD卡)中。实现过程中需要与多个已有的类进行交互)

代廉洁

设计模式的艺术

重学网络系列之(我的名字叫IP)

自然

网络 9月月更

小六六学Netty系列之Java BIO

自然

网络 9月月更 neety

远程TS全栈学习+远程全职工作+远程高质量外包=3R教室

pincman

node.js typescript react.js 远程工作 nestjs

阿里顶配版 Spring 全家桶高级笔记+300道硬核面试题,跪着啃完了

钟奕礼

Java 编程 程序员 架构 java面试

腾讯T4整合Spring+Spring MVC+MyBatis+Redis实现

退休的汤姆

Java 程序员 面经 Java工程师 秋招

DPDK技术学习路线总结,虚拟化专家之路

C++后台开发

后台开发 DPDK VPP OvS DPDK开发

Salesforce如何连续分析数以万计的生产服务器_软件工程_Paul Howden_InfoQ精选文章