简介: 作为阿里经济体基础设施的阿里云日志服务(SLS),服务了上万级的用户,每天处理20PB日志/Metric/Trace数据,为AIOps、大数据分析、运营服务、大数据安全等场景提供支撑,解决工程师可观察性的问题。经过几年的锤炼和演进,正在向统一的可观察性中台发展。本文分享阿里云存储团队构建SLS中台的背景和设计中的Trade Off,并通过两个最佳实践介绍如何通过中台构建智能的应用程序。
笔者是飞天最早的研发人员之一,曾经参与从0到5000台飞天集群和操作系统的构建。飞天是一个庞大的软件系统,既有非常多的模块,也要跑在几万台物理机上,如何让分布式软件高效地运行离不开监控、性能分析等环节,因此在飞天研发的第一天我们就同时开始研发飞天监控系统“神农”。神农通过采集大量的系统数据,帮助我们更好地理解系统、软件协作复杂性背后的关系。同时神农也在伴随着越来越大、越来越多海内外集群的飞天操作系统成长,支撑阿里巴巴集团和阿里云的业务。在2015年,经历过一番思考,我们决定把神农抽象成一个更底层的服务——SLS(日志服务,第一天主要focus在日志场景中),希望通过SLS能够服务支撑更多的Ops场景,包括AIOps(智能分析引擎)。
一 构建可观察性中台的背景
先说说从一个工程师的角度看到的变化:对一个工程师而言,5年前的工作是非常细分的,研发的工作就是把代码开发好。但随着互联网的发展,业务系统Scope越来越大,需要在质量、可用性和可运维性上有更高的要求。并且为了保障我们的业务是持续改进的,必须在工作中涉及到更多运营的因素,例如统计系统访问、留存和体验等情况。
从个人视角转化到行业视角也能发现一个趋势:在十几年前,研发的时间会花在三个部分:创新(编码),部署+上线,观察+分析,并且部署+上线会花费大量的时间。近几年云计算和云原生的兴起解放了开发运维在部署、上线和环境标准化上的精力。但业务的高要求需要在各个环节中承担更大的Scope,从多个视角来看待问题。背后就会有大量、碎片化的数据分析工作。
如果我们把具体的数据分析工作进行拆分,可以拆解成一个简单的黑盒。黑盒的左边是数据源,右边是我们对数据源观测判断后的行动。例如:
- 在安全场景中,安全运营工程师会采集防火墙、主机、系统等日志、根据经验对日志进行建模,识别其中的高危操作,生成关键性事件,系统根据多个事件进行告警。
- 在监控和运营场景中,这个过程是类似的。无非是把数据源和建模的方法做了替换。
所以我们可以看到,虽然各个场景角色不同,数据源不同,但在机制上我们是可以建立一套系统性分析框架来承载这类可观察性的需求的。
二 中台的技术挑战
构建中台的思路看起来很直接,要做这件事情有哪些挑战呢?
我们可以从数据源、分析和判别这三个过程来分析:
- 第一大挑战来自于数据源接入。以监控场景为例,业界有不同的可视化、采集、分析工具针对不同的数据源。为了能建立监控可观察性体系,需要引入大量的垂直系统。这些系统之间有不同的存储格式,接口不统一,有不同的软件体验,往往难以形成合力。
- 第二大挑战来自于性能与速度。数据分析的过程实际上是把专家经验(Domain Knowledge)沉淀的过程,而Ops场景一般都是Mission Critical过程,因此需要非常快地分析速度和所见即所得能力。
- 第三大挑战来自于分析能力。在接入足够多的数据后,往往会面临监控项太多,数据量太多,线索太多等问题,我们需要有成套的方法帮助我们去降维、去发现、去关联、去推理。AIOps算法目前聚焦在这一层上。
前两个问题本质上是一个系统问题,而后面两个问题和算法与算力相关。中台的推出可以解决第1和第2个问题。
三 阿里云SLS,自研自用可观察性中台
2015年我们研发了SLS,经过几年的锤炼和演进,正在向统一的可观察性中台发展。SLS向下对接各种开源的协议与数据源,向上对各种场景提供支撑能力。核心能力在于围绕可观察性的各种监控数据,提供统一的存储与计算能力,平台可以用 “1、2、3、4” 四个词来概括。
- “1” 代表一个中台。
- “2” 代表提供两种基本的存储模型:Logstore与MetricStore,分别面向适合Trace/Log类型的日志存储(Logstore),适合监控数据Metric类型的时序存储(MetricStore)。这两种存储并不是孤立的,建立在统一的存储概念上,并且可以非常灵活的相互转化。
- “3” 代表三类分析引擎:数据加工引擎(DSL)、SQL查询分析引擎(SQL)、智能分析引擎(AIOps)。DSL主要面向数据加工和与预处理场景,解决格式多样化的问题;SQL查询分析引擎面向存储数据提供清洗、计算能力;而内嵌的AIOps可以给特定问题提供智能算法。
- “4” 代表四类典型场景:例如ITOps、DevOps、SecOps、BusinessOps等。涉及到运维、研发、运营和黑客增长等领域。阿里集团80%以上类似场景都基于SLS来构建。
平台始终向用户提供支撑能力,兼容各种数据源与协议,支撑业务但不做业务产品。
1 存储设计
为了构建可观察性的中台,我们先看看目前存储系统的现状。在运维领域AIOps系统的构建过程中,长期并存四种类型的存储系统,分别是:
- Hadoop/Hive:存放历史日志,Metric等数据,存储成本便宜,分析能力较强,但延时较高。
- ElasticSearch:存放需要实时访问的Trace,Log信息,检索速度快,但成本较高,适合近线的热数据,分析能力中等。
- NoSQL:用来存储经过聚合的指标类数据,TSDB类是NoSQL存储扩展,检索聚合后的指标速度快,成本较便宜,缺点是分析能力较弱。
- Kafka:用来导入导出路由各种数据,主要存储临时数据,上下游接口丰富,没有分析能力。
这四类独立的存储系统较好地解决了四种不同类型的需求,但存在两大挑战:
数据流动性
数据存储后能够支撑某个场景的服务能力,但随之而来的问题就是流动性。数据存在于多个系统中,做数据关联、对比、整合时就需要去搬数据,这往往需要花费非常多的时间。
接口易用性
面对不同的存储对象的接口不统一,例如Log一般使用ES的API来包装,而Metric一般会用Prometheus协议或通过NoSQL接口直接调用等等。为了集成数据往往需要涉及到不同的API与交互方式,增加了系统的整体复杂性。
目前四种存储系统的现状导致数据使用需要较长的周期及一定的开发量,限制了AIOps,DataOps等场景发挥更大的作用。
2 如何抽象存储
如果我们把监控数据的生成过程做一个抽象,可以发现一般会由两个过程组成:变化+状态。所有的事物都是一个待续变化的过程,例如数据库的一张表在某一个时刻(例如2点)的状态实际上是由历史上所有变化累计的结果。在监控领域中也是一样,我们可以通过Log、Trace等方式把系统状态的变化尽可能保存(或采样)下来。例如用户在1小时内做了5次操作,我们可以把这5次操作的日志或Trace捕捉下来。当我们需要一个状态值时(比如2点的系统状态是什么),我们可以对这些所有的操作日志做一个回放,形成某一个时间点的一个汇总值,例如在窗口大小为1小时的区间内,操作QPS为5。这里就是一个简单的Log转为Metric的关系,我们可以使用其他逻辑,例如对Log中的Latency字段做一个Avg来获得该窗口的Latency。
在SLS存储设计的过程中,我们也遵循了这样的客观规律:
- 底层提供了一个FIFO Binlog队列,数据写入和读取都是顺序的,以严格的写入时间(Arrival Time)作为排序。
- 在Binlog之上,我们可以挑选某些字段生成一个Logstore,Logstore可以认为是数据库的一个表:是带Schema的,至少有EventTime这个字段(事件发生的原始时间),可以指定列的类型和名字。这样我们就可以通过关键词和SQL检索Logstore中的内容。
- 除此之外,我们可以根据需求对Logstore中的某些列生成多个Metric存储,例如根据Host+Method+Time构建一个以Host+Method作为Instance的监控数据存储表,从而可以根据时间段把数据捞出。
让我们来看一个例子:以下是一个站点的访问记录,在1秒内经历了4次访问。
time, host, method, latency, uid, status
[2020-08-10 17:00:00, Site1, UserLogin, 45ms, 1001, OK]
[2020-08-10 17:00:01, Site1, UserBuy, 25ms, 1001, OK]
[2020-08-10 17:00:01, Site1, UserBuy, 1ms, 1001, OK]
[2020-08-10 17:00:01, Site1, UserLogout, 45ms, 1001, OK]
[2020-08-10 17:00:01, Site2, UserLogin, 45ms,1002, Fail]
当这些数据写入Logstore后,相当于写入了一张存放日志的数据库,可以通过SQL对其中任意字段进行查询与分析。例如“ select count(1) as qps”,获得当前汇总的QPS。
也可以通过预定义好一些维度,例如希望通过host+method组合来构建最小监控粒度,每隔1秒钟获得QPS,Latency等数据,那我们可以定义如下的MetricStore,当数据写入后,能够自动根据规则生成如下结果:
[host, method, time], [qps, latency]
[site1, userLogin, 2020-08-10 17:00:00], [1, 45]
[site1, userBuy, 2020-08-10 17:00:01], [2, 15]
[site1, userLogout, 2020-08-10 17:00:01], [1, 25]
通过这种方式,我们就可以在一种存储中通过原始数据的存储、聚合形成日志与Metric转移。
3 计算设计
根据平时遇到的场景,我们把监控数据的计算抽象成三类问题:
- 非结构化数据如何变为结构化数据
- 面对复杂系统,能否设计一套所见即所得低门槛语言进行数据分析
- 面对海量信息,是否有降维算法来降低问题复杂度
我们构建了三类计算方法分别来处理以上问题:
第一个问题实际上一个业务复杂度的问题,根源来自产生数据的人和使用数据的人之间的GAP。在大部分开发流程中打日志的往往是开发者,但分析日志的往往是运维和运营,在写日志过程中没有足够预见性导致数据无法直接被使用。这里需要有一套低代码开发的语言来做各种各样的数据转化、分派、富化,把多个业务系统不同格式的数据进行简化。为此我们设计了一套面向数据加工(ETL)场景的语言(DSL),该语言提供了300多个常用算子,专制日志格式的各种疑难杂症。
例如在原始日志中,只有一个project_id字段在访问url参数里,ip这个字段对应的设计我们无法拿到。在SLS的DSL语言中,我们只需要写3行代码,从url中提取参数,与数据库中字段进行富化。原来看起来无用的访问日志就立即盘活,可以分析出主机和使用者之间的访问关系了。
第二个问题是一个多语言融合的问题,我们的选择是以SQL作为查询和分析框架,在框架中融入PromQL及各种机器学习函数。这样就可以通过子查询+主查询进行嵌套,对结果进行计算并预测。
SLS SQL = Search + SQL92(Agg,WIndow,GroupBy...)+ PromQL + ...
以下就是一个复杂分析的例子:
- 先通过调用promql算子拿到主机每分钟的监控值
- 通过窗口函数对原始数据进行降采样,例如变为每秒的数值
- 通过外层的预测函数对查询结果进行预测
第三个问题是算法的问题,我们内置了大量基于AI的巡检、预测、聚类、根因分析等算法,可以在人工分析和自动巡检告警中直接使用到。这些算法通过SQL/DSL函数向用户提供,可以在各种场景中用到。
四 中台支撑案例
SLS在阿里集团内外有万级的用户,大量运用到AIOps各种数据分析场景中,这里列举两个比较有意思的案例。
案例1:流量解决方案
流量日志是最常见的访问日志类型,无论是Ingress,Nginx还是CDN Access Log都可以抽象成访问日志类型,在SLS解决方案中:
- 采集一份原始日志保留7天时间(LogStore)进行查询,更长时间备份到对象存储(OSS)。
- 通过SLS原生的SQL对日志进行数据加工+各维度聚合,例如根据微服务接口进行Group By。
- 对聚合后的数据进行时序类型存储(MetricStore)。
- 通过AIOps巡检函数对数以千计的接口进行智能巡检,生成告警事件。
整个过程从采集到配置到运行只需要花5分钟,满足多样性需求。
案例2:云成本监控与分析
阿里云的用户每天会面临大量的账单数据,云成本中心就利用SLS采集、分析、可视化与AIOps功能开发了一款成本管家应用,智能帮助用户分析云产品成本,预测成本的趋势,找到账单中异常的原因。
五 写在最后
虽然过去几年我们没有直接做AIOps应用,但通过把数据能力、AI能力中台化,反而支撑了更多的用户与场景。最后简单总结下过去两年做可观察性中台的心得体会:
AIOps = AI + DevOps/ITOps/SecOps/BusinessOps…
目前大部分人觉得AIOps解决的是运维的问题,实际上该套方法可以无缝地切换到各种OPs场景中,例如DevOps,SecOps(Bigdata Security),以及通过AI来进行运维与用户增长,方法都是通用的。和AI所在的任何一个领域一样,数据是根本、算力是基础、算法是核心,缺一不可。
Domain Knowledge是AIOps落地关键
一个有经验的运维或分析师,对系统有深刻的见解和建模经验。因此AIOps要落地,我们必须尊重专家系统的经验沉淀,例如通过模板化、知识表示与推理、或在一些场景中使用迁移学习等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。