导读: 随着大数据技术的进步,各种计算框架的涌现,数据仓库相关技术难题已经从离线数仓逐渐过渡到实时数仓,越来越多的企业对数据的实时性提出了严格的要求,如何满足企业的低延时的数据需求,如何看待批量处理和实时处理的关系,实时数仓应该如何分级,各家可能都有自己的理解,本文主要介绍网易的实时计算平台的建设实践以及网易对于实时数仓方面的一些规划及展望,希望能够起到抛砖引玉的作用。
网易的实时计算平台Sloth译成中文是树懒的意思,继承了网易喜欢用动物系命名大数据组件的风格,如果你看过《疯狂动物城》,一定会对剧中的flash印象深刻。Sloth平台的建设始于2017年12月份,至今已有3年的时间,期间平台的弹性计算单元(ECU)规模一直呈现指数级增长,目前ECU已经突破50000个,运行的CPU数量已经达到15110核,内存超过了34T。
从功能的角度来看,Sloth平台主要分成两大块:
从数据层面来看,我们实时数仓的架构主要分为四个层面:
① Source层
关系型数据:NDC是公司专门处理关系型数据的组件,它会将mysql等关系型数据库的binlog日志解析成特殊的数据格式然后插入到我们的kafka消息队列。
日志型数据:datastream是公司的专门负责日志收集的平台,它会将收集的日志信息插入到我们的消息队列。
② 消息队列
目前我们选用的是kafka。
③ 计算层
目前我们选用的是flink来完成数据的清洗,转换及聚合。
④ Sink层
kudu是我们主推的存储格式,kudu不仅可以提供一个高效的用于数据分析的列存格式,同时也支持数据实时的upsert及delete。当体量比较小的时候,也可以选用mysql或者redis这种可以实时变更的存储组件。
我们主推的开发模式是sql模式,同时我们也支持jar包模式。
我们提供高度集成的IDE,支持代码的离线调试,线上调试,版本管理,版本比对及配置管理。
运维我们主要分为三大版块,分别是任务的运维,服务器监控及异常告警,下面我们分别看一下:
① 任务的运维
我们提供丰富的界面和菜单来支持任务的运维工作,通过页面的菜单点击我们可以轻松的查看任务信息,运行时的参数,高级的配置,运行记录,操作记录及运行日志。
② 服务器压力的监控
我们在grafana的基础上进行了二次开发,图形化的展示平台的吞吐量,延迟,IO,QPS等关键信息。
③ 告警的设置
在Sloth平台设置告警非常简单,你可以在界面上配置多个规则,比如说任务失败次数,数据延迟超多少阀值,报警间隔,告警的接收人,发送方式等。
无论是离线数仓还是实时数仓,都需要做好元数据的管理工作,Sloth平台也有统一的元数据中心,下面简单介绍一下我们的元数据管理方式,元数据登记以及统一元数据所带来的好处。
元数据管理:
Hive metastore元数据管理体系是业界公认的标准,包括flink在1.10版本之后也开始打造自己的catalog机制,网易也遵循了这套逻辑,将数据统一分成了instance-> database -> table 的层级。
数据源登记:
统一元数据所带来的好处:
下面我们以一个百度热词统计案例来分析一下流式处理与批量处理的成本消耗及网易目前遇到的一个存储痛点。
① 流式处理与批量处理
熟悉大数据的人都知道统计百度热词的过程相当于一个wordcount + topn 操作,这个任务既可以用spark跑批模式实现,也可以用flink流式计算实现,下面我们来分析一下跑批模式和流式计算模式完成这个统计的消耗情况。
跑批模式:
流式计算模式:
结果对比:
② Kudu痛点
目前市面上的支持实时读写的大数据存储基本上采用的都是PDT tree或者LSM tree这种数据结构,这种数据结构主要采用的是写优化策略,首先数据会有一个基线版本,当对数据进行修改时,不会立即修改基线版本的数据,而是写入一个新版本的数据,这种写入是采用append的模式实现的,所以写延迟非常低,那么读取的时候我们就需要合并多个版本的数据返回最新版本的数据,它的读延迟就会比较高。所以为了照顾到读延迟问题,隔一段时间就需要执行一次合并版本的操作形成一个新的基线版本,这个过程叫compaction。这种机制会带来一个问题,就是当一秒钟之内发生大量的修改时,这时数据就会有很多个版本,compaction的过程就会带来大量的cpu和内存消耗,这个问题我们称之为写放大问题。
因为compaction的存在,kudu成了一个存算不分离的存储系统,它需要去综合考虑写延迟,读延迟和compaction的性能,虽然他可以实时upsert或者delete,但是极端情况下它会遇到写放大的问题,而且网易线上也确实经历过这样的事故。
③ 实时规模与成本的负相关
根据前面的分析,我们得到了一个结论:
基于之前的提出的这些问题,我们展望一下如何实现一个流批一体的配套存储:
首先,我们需要实现存算分离,核心思路是:
其次,我们应该提供一个流批一体的API:
批量读取的api其实很好解决,我们的hdfs上的存储结构像parquet,kudu本身就是可以批量读取的,那么什么是流式读取的api呢?试想一下我们的消息队列,像kafka提供了一个时间戳,我可以随时回到这个时间戳对应的偏移,然后消费之后的数据,所以我们的想法是只要我们给定一个起始时间就能增量的读取某个时间点之后的数据就可以了,这个也类似mysql的binlog。
无论是批量的读取还是流式的读取,它们的存储应该是同一套。
我认为数仓可以根据实时性的要求分成不同的等级:
最后概括一下,如果把数仓比喻成交通的话,实时数仓就好比是城市交通,离线数仓就好比是城际交通。
在构建实时数仓时,我们通常需要考虑三个重要的环节:
本文主要讲述了网易的实时数仓的产品形态,并结合实际的案例分析了网易实时数仓目前面临的难点,一方面剖析了批计算与流计算各自的消耗情况,一方面剖析了现有存储体系的存算不分离问题,从而得出流计算的成本随数据体量呈指数级增长的结论,紧接着我们提出了一种存算分离且批流一体的存储架构,通过剥离compaction,把compaction交给外部服务或者计算框架来实现存算分离,以及提供统一的API来同时支持批计算和流计算,最后我们浅谈了数据仓库的等级划分以及建设实时数仓时需要考量的三个重要环节。
今天的分享就到这里,谢谢大家。
作者介绍:
马进,网易杭研技术专家
马进,网易杭研技术专家、网易流计算团队负责人。负责网易数据库中间件、数仓团队,主导数据库中间件的各类项目研发,曾先后参与分布式数据库DDB,缓存NKV,分布式事务协调器TCC,数据运河NDC等项目。专注于分布式系统架构与数据库技术,热衷于构建高效的,高性能的分布式后台系统。
本文来自 DataFunTalk
原文链接:
领取专属 10元无门槛券
私享最新 技术干货