本文由 dbaplus 社群授权转载。
一、运维在广告体系中的价值
运维的工作来源已久,但直到近些年,随着互联网的发展,产品的维护工作越来越复杂,以及服务可用性的提升,都让运维的工作越来越重要。我们可以回顾下运维发展至今都经历了哪些阶段。
① 人工阶段
这个阶段的运维主要通过人肉操作我们的服务,由于这个阶段的服务大都是单实例,流量服务器都比较少,所以我们通过命令行就能够解决绝大多数的问题。
② 工具阶段
随着互联网影响逐渐变大,我们的流量也开始变大,我们的产品功能也开始变得丰富,曾经我们单实例的服务也开始朝着多实例、分布式发展,为了应对逐渐增加的服务器、服务数,我们开始使用一些如 Puppet 的运维工具,通过 Shell、Python 写一些脚本来提升运维的工作效率,减少重复的劳动。
③ DevOps
前几年,运维领域开始提出 DevOps 的理念,开始着手解决运维与开发的合作问题,开始让运维的工作走向规范化、平台化。让一个产品从功能开发到测试交付、再到后期运维能够更加的快捷、频繁、可靠,更快的响应互联网快速的发展和产品迭代。
④ AiOps
这两年,人工智能和大数据的异常火热,而运维领域的许多工作都为 AI 和大数据的实施落地提供了良好的土壤。我们也希望通过 Ai 和大数据等技术的引入,能够将运维的技术层次带入一个更高的台阶。
通过以上描述,我们可以看到运维的工作在互联网的产品技术链中是不可或缺的一环,那么下面我们再来看下在微博广告团队,我们都是通过哪些方案举措来服务微博广告的产品。
对于我们微博广告团队来说,服务的可用性是至关重要的,也是我们的核心 KPI,所以保障广告服务的稳定性也是我们运维工作的重中之重。我们主要会通过优化系统和提升效率两个方面来保障和提升我们服务的可用性。
具体涉及的内容包括系统性能评估、故障迅速定位、应急事件处理、请求链路跟踪、代码快速迭代、指标走势预测等等。
▲ 图 1-1 运维在微博广告的价值
二、复杂业务场景下的运维建设之路
1、服务治理
图 2-1 是去年 IG 夺冠时,王思聪发了一条博文,而这条博文对微博广告的影响就如图 2-2 所示。这种突发的流量波动是微博典型的特征之一,它不同于双十一等活动,可以提前预估流量,做好前期准备工作。在传统的运维场景下,也许在你也还没准备好的情况下,流量的高峰就已经过去了。所以如果应对这样突发的流量高峰是我们需要重点解决的问题之一。
▲ 图 2-1
▲ 图 2-2
从去年开始,我们运维团队开始进行基于机房的服务治理工作。在以前,广告的很多服务部署都是单点单机房、很多多机房的部署也面临部署不均衡,流量不均匀等现象。跨机房的请求更是无形的增加了整个广告链路的请求耗时。所以再出现机房级故障时,我们的服务就可能像图 2-4 所示的那样,那么服务的高可用性也就无从谈起了。
▲ 图 2-3
▲ 图 2-4
在 19 年的上半年,经过大半年的时间,我们完成了微博广告基于机房级别的服务优化改造。共治理服务一百多个,所有的服务都分布在两个及以上的运营商和机房中,从而避免了单机房出现故障时,造成广告服务的不可用。而我们治理过程中坚持的准备主要有以下几点:
服务多机房均衡部署
分布在不同运营商
机房承载能力冗余
流量请求均匀分布
上下游同机房请求
同时,我们还会定期做流量压测,来发现我们系统链路中的服务瓶颈。我们将生产环境的流量重新拷贝到生产环境中去,来增加线上流量,发现服务性能瓶颈。
图 2-5 是我们对某广告产品的整体性能压测所展示的效果,我们可以清楚的发现图中有两个模块的在流量高峰下,出现了耗时波动较大的问题。由此我们可以针对性的进行优化。
▲ 图 2-5
2、自动化运维平台
随着互联网的发展,我们的广告产品也是日新月异,迭代频繁。我们运维团队每天需要面对来自三百多个业务方提过来的上线需求,在三千多台机器上进行服务的变更等操作,如何提升服务上线的效率和质量,如何让变更变得安全可靠也是我们重要的目标之一。
▲ 图 2-6
从 17 年开始,我们运维团队自研了一套自动化运维平台 Kunkka,该平台主要基于 SaltStack、Jenkins 等技术,可以实现服务的快速上线、快速回滚等操作。整体架构如图 2-7 所示。
▲ 图 2-7 Kunkka 整体架构图
开发同学在提交代码到 Gitlab 后,自动触发 Jenkins 的编译操作,并将编译后的包上传至 Nexus 中,这时开发同学只需要选择他们想要部署的目标主机就可以了。
同时,为了应对平常突发的流量高峰和节假日的流量高峰,我们还对接了公司的 DCP 平台,可以在我们的 Kunkka 平台上自动生成 Docker 镜像文件,并上传公司的镜像仓库中,这样就可以在快速的将服务部署到云主机上,实现服务动态扩缩容。
整个服务部署过程中,我们还加入了多级审核机制,保障服务上线的安全性。具体流程如图 2-8 所示。
▲ 图 2-8 Kunkka 上线流程图
3、有效的报警
在服务上线后,我们要做的一个很重要的工作就是给我们的服务添加监控报警机制,否则我们就像瞎子一样,对我们系统服务运行情况一无所知。
关于报警系统业界优秀的报警系统有很多,使用的方案也基本大同小异。我们目前主要用的是开源的 Prometheus 报警系统,这里就不详细介绍了。
这里主要想说下我们在做报警的一些想法。比如我们经常遇到的一个问题就是报警邮件狂轰滥炸,每天能收到成百上千的报警邮件,这样很容易让系统中一些重要的报警信息石沉大海。对此,我们主要以下三个方面来考虑:
质疑需求的合理性
报警聚合
追踪溯源
首先,在业务方提出报警需求的时候,我们就需要学会质疑他们的需求,因为并不是每个需求都是合理的,其实很多开发他们并不懂报警,也不知道如果去监控自己的服务。这时候就是发挥我们运维人员的价值了。我们可以在充分了解服务架构属性的前提下提出我们的意见,和开发人员共同确定每个服务需要报警的关键指标。
其次,我们可以对报警做预聚合。现在我们的服务大都都是多机部署的,一个服务有可能部署到成百上千台机器上。有时候因为人为失误或者上线策略等原因,可能导致该服务集体下线,这时就会有成百上千来自不同主机的相同报警信息发送过来。
对于这种场景,我们可以通过报警聚合的方式,将一段时间内相同的报警合并成一条信息,放在一封邮件里面发送给开发人员,从而避免邮件轰炸的情况发生。关于报警聚合,像 Prometheus 这样的报警系统自身已经支持,所以也不会有太多的开发量。
最后,再高层次,我们就可以通过一些策略、算法去关联我们的报警。很多时候,一条服务链路上的某个环节出现问题可能导致整条链路上的多个服务都触发了报警,这个时候,我们就可以通过服务与服务之间的相关性,上下游关系,通过一些依赖、算法等措施去屏蔽关联的报警点,只对问题的根因进行报警,从而减少报警触发的数量。
图 2-9 是我们运维团队 17 年优化报警期间,报警数量的走势。
▲ 图 2-9 有效的报警
4、全链路 Trace 系统
除了添加报警以外,在服务上线后,我们还会经常需要跟踪我们整个服务链路处理请求的性能指标需求。这时就需要有一套全链路的 Trace 系统来方便我们实时监控我们系统链路,及时排查问题,定位问题。
在全链路 Trace 系统中,最重要的就是 Traceid,它需要贯穿整个链路,我们再通过 Traceid 来关联所有的日志,从而跟踪一条请求在整个系统链路上的指标行为。图 2-10 是我们约定的用于全链路 Trace 的日志格式信息。
▲ 图 2-10 日志格式与解析
有了日志后,我们就可以基于这些日志进行分析关联,就像上面说的,Traceid 是我们整个系统的核心,我们通过 Traceid 来关联所有的日志。如图 2-11 所示,所有的日志会写入 Kafka 中,并通过 Flink 进行实时的日志解析处理,写入 ClickHouse 中。有了这些关键指标数据后,我们就可以在此基础上去做我们想做的事,比如形成服务拓扑进行请求跟踪、日志的检索以及指标的统计分析等。
▲ 图 2-11 数据收集与处理
在所有的数据收集解析完成后,业务方就可以根据一些维度,比如 UID,来跟踪用户的在整个广告系统中请求处理情况,如图 2-12 所示。随后再将查询的数据以 Traceid 维度进行关联展示给用户。
▲ 图 2-12 业务查询
三、海量指标监控平台 Oops 实践
最后我们看下我们如何应对微博广告海量指标数据下多维的监控需求。前文也说了,监控报警就像我们的眼睛,能够让我们实时的看到我们系统内部的运行情况,因此,每一个服务都应该有一些关键指标通过我们的监控报警系统展示出来,实时反馈系统的健康状态。
如图 3-1 所示,做一个监控平台很容易,我们将指标、日志等数据进行 ETL 清洗后写入一个时序数据库中,再通过可视化工具展示出来,对于有问题的指标通过邮件或者微信的方式报警出来。但是在这个过程中,随着我们数据量的增长、我们指标的增长以及查询复杂度的增加,我们可能会遇到监控指标延迟、数据偏差以及系统不稳定等问题。
▲ 图 3-1 监控平台的挑战
因此,在设计我们的监控系统时,就不能仅仅基于实现考虑,还需要考虑它的稳定性、实施性、准确性,同时还应尽量把系统做的简单易用。
▲ 图 3-2 监控平台的目标
而我们目前的监控平台 Oops,也是基于上述原则,经历了多年的迭代和考验。图 3-3 是我们 Oops 监控平台当前的整体架构。
▲ 图 3-3 Oops 监控平台架构
① 数据采集
整个平台分为四个层次,首先是我们的数据采集。我们当前主要通过 Filebeat 这样一款优秀的开源采集客户端来采集我们的日志。对我们使用而言,Filebeat 足够的高效、轻量,使用起来也很灵活易用。
▲ 图 3-4 Filebeat 架构图
② 指标清洗
数据采集到 Kafka 后,我们再根据具体的业务需求将指标提取出来。如图 3-5 所示,当前我们主要通过 Flink 来解析日志,并写入 ClickHouse 中。
同时,针对一些业务需求,我们需要将一些指标维度做关联处理,这里主要通过 HBase 实现指标的关联,比如,有曝光和互动两个日记,我们将曝光日志中的 mark_id 字段作为 rowkey 写入 HBase 中,并储存一个小时,当在时间窗口内互动日志匹配到相同的 mark_id 时,就将曝光日志的内容从 HBase 中取出,并与互动日志组合成一条新的日志,写入到一个新的 Kafka Topic 中。
此外,我们还将 Kafka 中数据消费写入 ElasticSearch 和 HDFS 中,用于日志检索和离线计算。
▲ 图 3-5 指标清洗
③ 指标储存
当前,我们通过 ClickHouse 来储存查询我们的监控指标。最初也是选择了流行的时序数据库 Graphite。但是在长期的使用中,我们发现在复杂的多维分析上,Graphite 并没有很好的体验。在去年,我们将我们的监控指标引擎替换成了现在的 ClickHouse,ClickHouse 是一款优秀的开源 OLAP 引擎,它在多维分析等功能上相比传统的时序数据库具有很大的优势。
同时,我们基于 ClickHouse 强大的函数功能和物化视图表引擎构建了一个实时的指标仓库。如图 3-6 所示,我们会将清洗后的指标写入到一张原始表中,比如这里的 ods_A,我们再根据具体的监控需求在 ods_A 表上进行维度的聚合。再比如,我们将请求维度按秒聚合成 agg_A_1s,或者按照 psid 维度按分钟聚合成 agg_A_1m_psid,又或者我们按照用户 id 维度来统计每个用户的访问次数。
由此我们可以实现不同时间维度和不同业务维度的组合分析查询,同时提升了查询响应速度,以及数据的重复利用率。而原始表的存在也让我们可以根据不同的需求定制不同的复杂的聚合表数据。
▲ 图 3-6 实时指标仓库
④ 指标可视化
最后,我们通过 Grafana 实现我们的指标可视化,Grafana 应该是当前全球最受欢迎的监控可视化开源软件,它支持很多的数据源,而 ClickHouse 也是其中之一,我们只需要写一条 SQL 就可以按照我们的想法在 Grafana 上以图表的形式呈现出来。如图 3-7 呈现的监控图就是图 3-8 这样一条简单的 SQL 实现的。
▲ 图 3-7 折线图监控指标
▲ 图 3-8 折线图监控指标 SQL 语句
对于表格的指标监控展示,也很简单,也是一条 SQL 就能完成的,如图 3-9 所示。
▲ 图 3-9 表格监控指标
当前我们的实时指标仓库存储 120T 的数据量,峰值处理 QPS 在 125 万左右,秒级查询、多维分析,为微博广告的指标监控、数据分析以及链路跟踪等场景提供了底层数据支撑。
作者介绍:
朱伟,微博广告 SRE 团队负责人,书籍《智能运维:从 0 搭建大规模分布式 AIOps 系统》作者之一。目前负责微博广告业务可用性的保障与优化、资源利用率的提升、监控报警系统的建设以及自动化体系的推进。
原文链接:
https://mp.weixin.qq.com/s/95oLNOX8P_OjM1PD9XRszA
评论