引文
本文是参加QCon全球软件开发大会(2023·北京站)专题分享后的一些总结。参加此次大会的最大感受是疫情后的快速恢复,到现场的听众座无虚席,一些场次甚至出现无座。同时也学习了其他多个专题分享,总体感觉是整个大会专业度很高,无论是从专题分享的内容、还是Q&A环节的听众互动。此次大会的所有专题简介可参考QCon专题列表。
先做下自我介绍,本人就职于阿里云SLS团队,负责SLS数据加工服务研发工作,服务阿里云上客户的海量日志处理。对机器数据处理场景痛点、核心技术和架构有深刻理解。当前主要关注实时计算、云原生等技术,欢迎交流。顺便附上几张参会的现场照片如上。
专题简介
在此专题分享中,我们讨论的主题是数据密集型系统的云原生架构与稳定性保障,将针对大规模数据实时加工场景深入探讨。从实际案例出发,针对此类规模场景下系统稳定性建设中遇到的典型问题,比如作业资源上限不可控性、算力扩缩容触发机制灵活性、系统变更潜在风险、上百集群统一监控等,探讨这些问题的根源,以及落地的处理实践。
以下是演讲的提纲:
- 第一部分,我们将讨论数据密集型服务进行一个概览
- 第二部分,基于SLS的数据密集型服务解决什么问题,以及怎么实现的
- 第三部分,实现以上数据服务我们遇到的问题、和痛点
- 第四部分,我们如何解决掉以上问题的
- 最后,讨论未来的技术发展思路
数据密集型服务架构
数据密集型系统其实包含了计算资源(CPU、内存),IO(磁盘、网络),数据规模等因素的完整架构。关于数据密集型系统的设计感兴趣可以参考Martin Kleppmann的书籍《Designing Data-Intensive Applications》。Lamdba架构与Kappa架构可参考博文《Questioning the Lambda Architecture》。
上图是从数据处理链路的角度对SLS的描述,其中包含两个方面。一方面SLS本身是一个开放的日志数据平台。用户可以通过开放API,把其存储在SLS的数据与已有的大数据平台连接起来,这一点与阿里云上很多大数据产品也有紧密合作。另外今年iLogtail开源(iLigtail开源库)、阿里云Terrform集成、阿里云统一CLI等等都在推动SLS越来越开放化。
另一方面SLS为客户提供一站式数据处理链路服务,支持客户快速完成非结构化数据实时加工处理。如上图所示,整个数据处理链路包含四个功能点:
- 数据导入:打通阿里云上客户自建服务、外部开放服务与SLS的无缝对接
- 实时加工:对数据进行实时行处理、以及链路编排
- 聚集加工:对数据进行定时分析、聚合加工
- 数据导出:围绕“数据入湖”等场景给出相应的技术实现与解决方案
本文重点将放在实时加工场景上。
云原生下数据密集型服务的架构适配
云原生下数据密集型服务整体框架
对于云上数据实时加工服务而言,其面临的是超大数据规模(每秒数百万级的tps),以及苛刻的可用性和稳定性要求。一个严峻的挑战是作业处理的数据规模与用户的业务场景强关联,往往会出现流量洪峰,且不可预测。比如对于游戏服务,开服、活动等时间点会数据量出现瞬时数百倍的突增,对于数据处理系统产生极大压力。
基于上述的调度设计目标,我们设计了可观测性任务调度框架,如上图所示,下面从下到上来介绍。
- 存储层:主要包括任务的元数据存储和任务运行时的状态和快照存储。任务的元数据主要包括任务类型,任务配置、任务调度信息,都存储在了关系型数据库;任务的运行状态、快照存储在了分布式文件系统中。
- 服务层:提供了任务调度的核心功能,主要包括任务调度和任务执行两部分,分别对应前面讲的任务编排和任务执行模块。任务调度主要针对三种任务类型进行调度,包括常驻任务、定时任务、按需任务。任务执行支持多种执行引擎,包括presto、restful接口、K8s引擎和内部自研的ETL2.0系统。
- 业务层:业务层包括用户直接在控制台可以使用到的功能,包括告警监控、数据加工、重建索引、仪表盘订阅、聚集加工、各类数据源导入、智能巡检任务、和日志投递等。
- 接入层:接入层使用Nginx和CGI对外提供服务,具有高可用,地域化部署等特性。
- API/SDK/Terraform/控制台:在用户侧,可以使用控制台对各类任务进行管理,对于不同的任务提供了定制化的界面和监控,同时也可以使用API、SDK、Terraform对任务进行增删改查。
- 任务可视化:在控制台我们提供了任务执行的可视化和任务监控的可视化,通过控制台用户可以看出看到任务的执行状态、执行历史等,还可以开启内置告警对任务进行监控。
实时加工应用场景
这里我们总结下实时加工的常见场景(具体场景很多,这里仅列出典型、常见的场景):
- 规整:这是使用频率最高的场景,比如从文本日志数据中提取出关键信息,将其转为规范化的数据
- 富化:比如用户的点击数据中只包含商品ID,在分析时需要从数据库关联起详细信息
- 脱敏:随着我国信息安全相关法律的完善,对于敏感数据(比如个人信息)的处理要求越来越高
- 分裂:在数据写出时,出于性能、便捷性考虑会将多条数据合并输出,在分析前则需要拆分出独立数据条目
- 分发:将不同类型的数据分别写到不同的特定目标中,以供下游定制化使用
上图中右侧是实时加工在无规则数据字段规整的使用场景,这里的例子是 Nginx 访问日志的解析。通过4行代码表达式就可以完成了无规则文本解析、KV数据提取、字段精简、数据流编排一系列操作,而且无需手动写复杂的正则表达式,直接使用内置 GROK 模式即可。
上图是实时加工在信息富化的使用场景,这里的例子接着上一场景,在http请求中,我们需要将请求状态码(http_status字段)的详细描述(http_code_desc字段)添加到原始数据中。
实时加工实现架构、及其在云原生下的适配
上图描述的是实时加工服务整体架构。左侧源logstore基于分片(shard)存储,分片方便存储实现备份与扩展,数据加工服务的伸缩也是依赖存储的分片机制。当数据加工调度器启动一个新的作业时,会自动创建并绑定到源logstore的一个消费组,消费组内部的多个消费者独立负责处理不同分片中的数据。随着数据量增多,存储需要产生更多的分片,同时数据加工作业便可以扩展更多的消费者独立工作。
当作业需要关联外部资源的时候,每一个消费者独立维护一份资源的拷贝,实现高性能关联计算。
上文讨论的实时加工的一般架构在云原生下的架构适配如上图所示,以POD作为处理单元,充分利用k8s的资源与伸缩机制。调度器的调度过程则转换通过k8s的API server为作业分配与管理其所需的资源。
该架构下稳定性常见挑战
用户场景、以及数据流量带来的系统挑战
上图所描述的是用户使用场景所带来的系统挑战,包括用户代码复杂度、作业资源开销等。右侧所展示的是在常驻作业的场景中,业务在低峰/高峰时期的CPU使用情况。可以看出,在低峰时期所有节点的CPU使用差距并不大;但是到达高峰期时,就出现了明显的热点,此热点问题在不重新调度部分作业的前提下是无法做到再平衡的。
基于K8s的系统挑战
HPA伸缩灵活性
原生的K8S HPA内置支持CPU和内存两个指标,这对于绝大多数数据密集型作业来说已经足够了。但是在数据实时加工中,用户需要对数据流进行编排,完成跨地域数据流转,面对这类网络/IO敏感场景,内置的HPA指标就无法满足。另外,基于HPA的资源伸缩动作存在滞后。
系统变更的稳定性风险
集群运维中存在业务之间资源争抢、业务规模导致超大集群(社区版k8s限制是每个节点不超过110 POD、单集群不超过5000节点)、变更发布灰度范围难以精确控制等稳定性风险等待挑战。
另外,随着k8s的版本快速发布,集群升级也存在潜在风险。由于集群中运行大量线上作业,集群升级过程对于作业有潜在影响,所以集群升级需要一个确保线上作业稳定性的方案。这一点也导致了集群的升级无法频繁操作。
近百个集群带来的运维挑战
作为云上数据处理服务,全球多地域、单地域内多可用区部署是必备基础,以满足不同的用户需求。另外同一可用区内也需要多集群以保证高可用,这两个原因导致线上运行非常多的k8s集群。为了保障服务的稳定性,其网络必须完全隔离,这导致运维成本随着集群数目呈几何级增长。
对应问题处理方案与实践
执行引擎方案:作业运行核心优化
执行引擎是实时加工作业运行的计算核心,我们从不同角度进行了优化提升。比如针对计算密集型场景,我们对用户的逻辑在ast层进行优化、考虑到日志数据的重复性特征增加数据缓存等。针对IO/网络密集型场景,则是对数据协议做了优化。另外我们也对计算单元进行资源使用做了反压等能力。
系统架构方案
作业计算扩缩容触发机制扩展
针对k8s的HPA灵活性限制,我们需要引入更灵活的HPA指标(由计算单元自动上报),以支撑多种多样业务场景下的作业需求。技术上使用的是external metric service能力,自定义指标则是存储在SLS MetricStore中。
另外,我们还使用智能算法对HPA指标进行续升级优化,比如基于作业的历史运行特性,提前做资源分配,更进一步提升作业运行的稳定性。
跨集群作业调度系统
针对集群升级、变更存在的稳定性风险,我们的方案是在调度层实现多集群负载均衡的能力,需要升级集群时,将新建作业创建至新集群,逐步地将旧版本集群汰换掉。除此之外,该方案也解决了同集群内不同服务的资源争抢、单一集群变更灰度、超大集群限制等挑战。
此方案也应如一个痛点,新旧版本集群会同时存在很长一段时间,这使得运维工作进一步增加,这也驱动我们进一步完善运维自动化,并且对于大量的集群统一监控的紧迫性,接下来我们就讨论这一点。
K8s可观测方案:SLS全栈监控
- 实时监控各类系统,包括主机监控、Kubernetes监控、数据库监控、中间件监控等。
- 支持ECS、K8s一键安装,支持图形化的监控配置管理,无需登录主机配置采集监控项。
- 运维老司机多年经验的报表总结,包括资源总览、水位监控、热点分析、详细指标等数十个报表。
- 支持自定义的分析,支持包括PromQL、SQL92等多种分析语法。
- 支持对接AIOps指标巡检,利用机器学习技术自动发现异常指标。
- 支持自定义告警配置,告警通知直接对接消息中心、短信、邮件、语音(电话)、钉钉,并支持对接自定义WebHook。
如上图所示,实时加工系统的监控架构分为三部分:
- 左侧部分是监控数据的生成与采集。在k8s侧的组件包括开源的事件监测node-problem-detector、采集agent iLogtail、SLS监控sls-monitoring。采集的指标包括k8s event、节点配置数据、节点资源使用指标、k8s资源监控指标,以及服务的运行日志和加工作业的运行日志。
- 中间部分是针对Log、Metric、Trace数据的统一存储、消费、分析引擎。
- 右侧部分是监控数据的应用。底层是用于系统研发运维人员对系统运行、资源使用等的监控;上层则用于实时加工用户对其创建的作业的可视化观测与监控。
接下来我们看下全栈监控的效果。左侧显示的是主机资源使用大盘、与k8s核心组件状态。右侧显示的是基于DevOps经验内置的监控告警规则列表。
未来展望
- 伸缩指标算进一步深入:应对超大级别的数据突增,伸缩更灵敏。
- 多集群调度系统增强:并发单元级别负载均衡,加快旧集群汰换效率。
- 数据处理引擎核心效率提升:将部分计算逻辑下推至存储层执行,极致提升数据处理链路的效率。
结语
以上专题分享中,我们讨论的主题是大规模数据处理服务(实时加工场景)的云原生架构稳定性建设。从实际案例出发,针对此类规模场景下系统稳定性建设中遇到的典型问题,比如作业资源上限不可控性、算力扩缩容触发机制灵活性、系统变更风险、大量集群统一监控等,探讨这些问题的根源,以及落地的处理实践。
上图是SLS团队的技术博客,我们会不定期推出技术文章分享和产品更新介绍,欢迎大家订阅,有任何问题也欢迎与我们反馈。