上节讨论了如何保障数据中台的数据质量,让数据“准”。除了“快”和“准”,数据中台还离不开“省”。随数据规模越来越大,成本越来越高,如不合理控制成本,还没等你挖掘出数据应用价值,企业利润就被消耗完。
能否做到精细化成本管理,关乎数据中台项目成败。
某电商业务数据建设资源增长趋势(CU= 1vcpu + 4G memory):
某电商平台的大数据资源消耗增长趋势,2019全年资源规模25000CU,全年机器预算3500W。对创业企业显然不小开支。
一天,数据团队负责人李好看被CEO叫到了办公室:
把李问懵,他心想:团队的成本是按机器又不是数据应用核算。在数据中台中,数据应用之间的底层数据是复用的,那具体每个数据产品或者报表花了多少钱,自己没有这样的数据啊,咋可能知道。
可对CEO这些很重要,因为资源有限,他须确保资源都用在战略目标的关键节点。如电商团队今年核心KPI是提升单个注册会员在平台的消费额,老板角度,他须确保资源都投入与KPI相关业务,如基于数据对注册会员精准化营销,提升会员在平台的消费额。
自己所在的团队是否发生过类似的事情? 数据部门是企业的成本中心,如要展现自己的价值:
所以,今天重点在省钱,聊数据中台的精细化成本管理。
一开始建设数据中台时,你往往会关注新业务的接入,数据的整合,数据价值的挖掘上,忽略成本管控的问题,从而落入陷阱中,造成成本爆炸式的增长。所以,有必要深入了解有哪些陷阱,尽量在日常开发中避免。
这里总结8种陷阱:
“知其然,更要知其所以然”,才能发现问题本质,深入掌握解决问题的方法。
某数据中台项目,表相关的使用统计。一半的表30d内都没有访问,而这些表占26%存储。如把这些表的产出任务单独拎出,高峰期需消耗5000Core CPU计算资源,换算成服务器需125台(按一台服务器可分配CPU 40Core计算),成本一年近500W。自己竟然有这么多无用数据?我经常把数据比作手机中的图片,我们不断拍照生图,却懒得清,最终手机存储经常不够。
无法及时清数据,数据开发也有苦衷。他们不知道一个表:
自然不敢停止这个表的数据加工,导致数据上线易,下线难。
数据看上去每天都被访问,但究竟产出多少价值,ROI值得吗?
有个宽表(拥有很多列的表,经常出现在数据中台下游的汇总层数据中),加上上游加工链路的任务,每天加工这张宽表要消耗6000块钱,一年200W,可追查后我们发现,这张宽表实际每天只有一个人在使用,还是一个运营的实习生。显然,投入和产出极不匹配。
间接说明,数据部门比较关注新的数据产品带给业务的价值,却忽略已存产品或报表是否还存在价值,最终导致低价值的应用仍大量耗资源。
不仅研发效率低,因数据重复加工,还资源浪费。一张500T表,加工这表,计算任务需高峰期消耗300Core,折合7台服务器(按一台服务器可分配CPU 40Core计算),加上存储盘成本(按照0.7 元/TB*天计算),一年消耗40W。
而这张表每复用一次,就可节省40W。所以模型复用,还可实现省钱。
第四,数据倾斜。
数据倾斜会让任务性能变差,也会浪费大量的资源,那什么是数据倾斜呢?
你肯定听说过木桶效应吧?一个木桶装多少水,主要取决于最短的那块板。对于一个分布式并行计算框架来说,这个效应同样存在。对于Spark计算引擎来说,它可以将海量的数据切分成不同的分片(Partition),分配到不同机器运行的任务中,进行并行计算,从而实现计算能力水平扩展。
但是整个任务的运行时长,其实取决于运行最长的那个任务。因为每个分片的数据量可能不同,每个任务需要的资源也不相同。由于不同的任务不能分配不同的资源,所以,总任务消耗资源=max{单个任务消耗的资源} * 任务数量。这样一来,数据量小的任务会消耗更多的资源,就会造成资源的浪费。
我们还是举个电商场景的例子。
假设你需要按照商户粒度统计每个商户的交易金额,此时,我们需要对订单流水表按照商户进行group by计算。在平台上,每个商户的订单交易量实际差距很大,有的订单交易量很多,有的却比较少。
我们利用Spark SQL完成计算过程。
在上图中,任务A 读取了左边某个分片的数据,按照供应商进行聚合,然后输出给下一个Stage的B、C、D任务。
你可以看到,聚合后,B、C和D任务输入的数据量有很大的不同,B处理的数据量比C和D多,消耗的内存自然更多,假设单个Executor需要分配16G,而B、C、D不能设置不同的内存大小,所以C和D也都设置了16G。可实际上,按照C和D的数据量,只需要4G就够了。这就造成了C和D 任务资源分配的浪费。
第五,数据未设置生命周期。
在06讲中,我强调,一般原始数据和明细数据,会保留完整的历史数据。而在汇总层、集市层或者应用层,考虑到存储成本,数据建议按照生命周期来管理,通常保留几天的快照或者分区。如果存在大表没有设置生命周期,就会浪费存储资源。
第六,调度周期不合理。
通过这张图你可以看到,大数据任务的资源消耗有很明显的高峰和低谷效应,一般晚上12点到第二天的9点是高峰期,9点到晚上12点,是低谷期。
虽然任务有明显的高峰低谷效应,但是服务器资源不是弹性的,所以就会出现服务器在低谷期比较空闲,在高峰期比较繁忙的情况,整个集群的资源配置取决于高峰期的任务消耗。所以,把一些不必要在高峰期内运行任务迁移到低谷期运行,也可以节省资源的消耗。
第七,任务参数配置。
任务参数配置的不合理,往往也会浪费资源。比如在Spark中,Executor 内存设置的过大;CPU设置的过多;还有Spark 没有开启动态资源分配策略,一些已经运行完Task的Executor 不能释放,持续占用资源,尤其是遇到数据倾斜的情况,资源浪费会更加明显。
第八,数据未压缩。
Hadoop 的HDFS 为了实现高可用,默认数据存储3副本,所以大数据的物理存储量消耗是比较大的。尤其是对于一些原始数据层和明细数据层的大表,动辄500多T,折合物理存储需要1.5P(三副本,所以实际物理存储5003),大约需要16台物理服务器(一台服务器可分配存储按照128T计算),如果不启用压缩,存储资源成本会很高。
另外,在Hive或者Spark 计算过程中,中间结果也需要压缩,可以降低网络传输量,提高Shuffer (在Hive或者Spark 计算过程中,数据在不同节点之间的传输过程)性能。
你看,我为你列举了8个典型的成本陷阱,那你可能会问了,老师,我已经中招了,该怎么办呢? 别急,接下来我们就看一看,如何进行精细化的成本管理。
成本治理应遵循全局盘点、发现问题、治理优化和效果评估四步。
对数据中台中,所有的数据进行一次全面盘点,基于元数据中心提供的数据血缘,建立全链路的数据资产视图。
全链路数据资产视图:
计算全链路数据资产视图中,末端数据的成本和价值(末端数据就是加工链路最下游的表,例如图中TableA,Table G)。
为什么一定要从末端开始? 因为中间数据在计算价值时,还要考虑下游表被使用的情况,较难计算清楚,所以从末端数据开始。这与下线表的顺序也一致,如数据的价值很低,成本很高,也从末端数据开始下线。
对上图中财务分析报表核算成本,这报表上游链路中涉及a,b,c,3个任务,A,B,C,D,E,F, 6张表:
这张报表的成本=3个任务加工消耗的计算资源成本+6张表消耗的存储资源的成本。
如一个表被多个下游应用复用,那这个表的存储资源成本以及产出任务消耗的成本,需分摊给多个应用。
如末端数据是一张应用层的表,它对接的是一个数据报表,那衡量这数据价值主要看报表的使用范围和使用频率。
计算使用范围时,通常用周活评估,同时还要考虑不同管理级别的人权重,对老板,他一个人权重可相当1000个普通员工。所以这样设计考虑到管理级别越高,做出商业决策影响越大,自然价值越大。使用频率一般使用单个用户每周查看报表的次数来衡量,次数越高,说明报表价值越大。
如末端数据对接的不是一个数据报表,而是面向特定场景的数据应用(比如我之前提到过的供应链分析决策系统,它面向的人群主要是供应链部门)。衡量这类产品的价值,主要考虑目标人群的覆盖率和直接业务价值产出。什么是直接业务价值产出呢?,在供应链决策系统中,就是通过系统自动生成的采购订单占所有采购订单的比例。
末端数据可能还是一张集市层的表,主要用于提供给分析师做探索式查询。这类表的价值看它被哪些分析师使用,使用频率。使用范围评估时,也要对分析师按级别加权。
全局盘点为发现问题提供数据支撑,关注:
持续产生成本,但已没有使用的末端数据(一般指30天内无访问)
没有使用,但一直在消耗成本的表,对应的就是我提到的陷阱1
数据应用价值很低,成本却很高,这些数据应用上游链路上的所有相关数据
低价值产出,高成本的数据应用,对应的是陷阱2
高峰期高消耗的数据
高成本的数据,对应陷阱4~8
陷阱3实际是在第6节模型设计中解决的。
针对这三类问题制订相应策略。
第一类,应对表下线。 数据下线要谨慎,参考数据下线的执行过程图:
末端数据删除后,原先末端数据的上游数据会成为新的末端数据,同样还要按发现问题到治理优化进行重复,直到所有的末端数据都不满足下线策略为止。
对第二类问题,我们需要按照应用粒度评估应用是否还有存在的必要。对于报表,可以按照30天内没有访问的应用自动下线的策略,先对报表进行销毁,然后对报表上游的表进行下线,如果该表还被其他的应用引用,就不能下线。下线步骤可以参考前面的下线步骤。
第三类问题,主要是针对高消耗的数据,又具体分为产出数据的任务高消耗和数据存储高消耗。对于产出任务高消耗,首先要考虑是不是数据倾斜。具体怎么判断呢?其实你可以通过MR或者Spark日志中,Shuffer的数据量进行判断。如果有某一个Task 数据量非常大,其他的很少,就可以判定出现了数据倾斜。
图 Spark task shuffer records:
图 MR reduce task records:
不同的场景有一些适用的解决方案:
推荐阅读
除数据倾斜,还应该查任务的配置参数。如Spark执行引擎:
一般executors-memorty 设4G-8G,executor-cores设2-4个(实践过利用率最高的配置项)。
还要考虑任务是否真有必要在高峰期执行,可根据集群负载情况,尽量将任务迁移到非高峰期执行,“削峰填谷”。
上面几点是产出任务高消耗的情况。
对存储消耗比较大的任务,先考虑是否要压缩,尤其对原始数据层和明细数据层,建议压缩
还要考虑生命周期是否设置:
整体上,底层表都是长期保留。关注重点应是汇总层以上的表(包括汇总层),一般可根据数据的重要性,制订7天,1个月保留策略。
若直接拿服务器数量来衡量,不能真实反应治理效果,因为还要考虑业务增长原因,可围绕任务和数据的成本考虑:
拿这些资源来计算成本,就能算出省了多少钱。如开头案例,任务A运行3h,在运行过程中,共消耗5384503 cpu*s,37007892 GB *s, 假设我们1个CU (1 cpu, 4g memeory)一年是1300元成本,折合每天为3.5元(计算公式为1300/365)。
不论是优化或下线任务,只统计高峰时间段内,因为优化低峰时间无法实际节省资源。
高峰时间段为8h,那折合每s费用0.00012153,则该任的费用为max{5384503*0.00012153, 37007892/4 * 0.00012153} = max{654, 1124} = 1124 。下线这任务后节省1124元,再加上表A占用的存储空间大小乘以每GB的成本,可得数据表A下线节省费用。
成本治理不是一劳永逸的工作,需要持之以恒,不断发现问题,然后治理优化,建立长久运行机制的前提是必须降低成本治理的门槛,接下来,看一下网易的一个成本治理的平台,EasyCost。
系统提供了数据诊断的功能,可以按照访问时间、访问频率、关联的应用,设置下线策略,支持一键灰度下线,大幅提高了管理的效率。
可通过系统化方式沉淀到产品,然后通过产品提高管理效率,实现治理机制的长久落地。
通过数据中台:
从常见成本陷阱入手,分析可能造成成本浪费的原因,然后介绍精细化成本管理的方法,最后强调:
在数据中台的集市层,存在一些大宽表,几百个字段,上游可能数十个表,如计算这个表的成本会非常高。这表中,字段访问频率不同,优化这张宽表?
垂直切分:将宽表按照字段的访问频率划分,将访问频率高的字段单独划分为一张表,访问频率低的字段单独划分为一张表。这样可以减少查询时扫描的字段数,提高查询效率
水平切分:将宽表按照行进行切分,将每个切分后的表中的字段数控制在可接受的范围内,这样可以减少单个表的字段数,提高查询效率
建立索引:对于宽表中的访问频率高的字段,可以建立索引,这样可以加快查询速度
缓存机制:对于查询频率高的数据,可以采用缓存机制,将数据缓存在内存中,这样可以减少查询时间
数据压缩:对于宽表中的冷数据,可以采用数据压缩技术,减少存储空间,提高查询效率
可根据实际情况选择合适的优化方式来提高查询效率。