专栏名称: DBAplus社群
围绕数据库、大数据、PaaS云,顶级大咖、技术干货,运营几个月受众过十万!成为运维圈最专注围绕“数据”的学习交流和专业社群!欢迎投稿,加入探讨。
目录
相关文章推荐
AustinDatabases  ·  哎,马上删,马上 ·  昨天  
终码一生  ·  如何加快 SQL 查询速度的同时保持 ... ·  昨天  
数据中心运维管理  ·  弱电智能化中究竟有多少个子系统? ·  3 天前  
数据中心运维管理  ·  超大规模数据中心如何重新思考冷却效率 ·  5 天前  
数据中心运维管理  ·  锂电池火灾处理难度 ·  4 天前  
51好读  ›  专栏  ›  DBAplus社群

万字干货还原美团Flink实时数仓建设

DBAplus社群  · 公众号  · 数据库  · 2020-10-14 07:15

正文

请到「今天看啥」查看全文



在实时数仓里面,所谓 APP 层的应用表,实际上就已经在应用系统的数据库里了。上图,虽然画了 APP 层,但它其实并不算是数仓里的表,这些数据本质上已经存过去了。


为什么主题层次要少一些?是因为在实时处理数据的时候,每建一个层次,数据必然会产生一定的延迟。


为什么汇总层也会尽量少建?是因为在汇总统计的时候,往往为了容忍一部分数据的延迟,可能会人为的制造一些延迟来保证数据的准确。


举例,统计事件中的数据时,可能会等到 10:00:05 或者 10:00:10再统计,确保 10:00 前的数据已经全部接受到位了,再进行统计。所以,汇总层的层次太多的话,就会更大的加重人为造成的数据延迟。


建议尽量减少层次,特别是汇总层一定要减少,最好不要超过两层。明细层可能多一点层次还好,会有这种系统明细的设计概念。


第二个比较大的不同点就是在于数据源的存储。


在建设离线数仓的时候,可能整个数仓都全部是建立在 Hive 表上,都是跑在 Hadoop 上。但是,在建设实时数仓的时候,同一份表,我们甚至可能会使用不同的方式进行存储。


比如常见的情况下,可能绝大多数的明细数据或者汇总数据都会存在 Kafka 里面,但是像维度数据,可能会存在像 Tair 或者 HBase 这样的 kv 存储的系统中,实际上可能汇总数据也会存进去,具体原因后面详细分析。除了整体结构,我们也分享一下每一层建设的要点。


1)ODS 层的建设


  • 数据来源尽可能统一

  • 利用分区保证数据局部有序



首先第一个建设要点就是 ODS 层,其实 ODS 层建设可能跟仓库不一定有必然的关系,只要使用 Flink 开发程序,就必然都要有实时的数据源。目前主要的实时数据源是消息队列,如 Kafka。而我们目前接触到的数据源,主要还是以 binlog、流量日志和系统日志为主。


这里面我主要想讲两点:


首先第一个建设要点就是 ODS层,其实ODS层建设可能跟这个仓库不一定有必然的关系,只要你使用这个flink开发程序,你必然都要有这种实时的数据源。目前的主要的实时数据源就是消息队列,如kafka。我们目前接触到的数据源,主要还是以binlog、流量日志和系统日志为主。


这里面我主要想讲两点,一个这么多数据源我怎么选?我们认为以数仓的经验来看:


首先就是数据源的来源尽可能要统一 。这个统一有两层含义:


第一个统一就是实时的数据源本身要跟自己统一,比如你选择从某个系统接入某一种数据,要么都从binlog来接,要么都从系统日志来接,最好不要混着接。在不知道数据生产的流程的情况下,一部分通过binlog接入一部分通过系统日志接入,容易出现数据乱序的问题。


第二个统一是指实时和离线的统一,这个统一可能更重要一点。虽然我们是建设实时数仓,但是本质上还是数仓,作为一个团队来讲,仓库里的指标的计算逻辑和数据来源应该完全一致,不能让使用数据的人产生误解。如果一个数据两个团队都能为你提供,我们建议选择跟离线同学一致的数据来源。包括我们公司本身也在做一些保证离线和实时采用的数据源一致的工作。


第二个要点就是数据乱序的问题 ,我们在采集数据的时候会有一个比较大的问题,可能同一条数据,由于分区的存在,这条数据先发生的状态后消费到,后发生的状态先消费到。我们在解决这一问题的时候采用的是美团内部的一个数据组件。


其实,保证数据有序的主要思路就是利用 kafka 的分区来保证数据在分区内的局部有序。至于具体如何操作,可以参考《 美团点评基于 Flink 的实时数仓建设实践 》。这是我们美团数据同步部门做的一套方案,可以提供非常丰富的策略来保证同一条数据是按照生产顺序进行保序消费的,实现在源头解决数据乱序的问题。


2)DW 层的建设


解决原始数据中数据存在噪声、不完整和数据形式不统一的情况。形成规范,统一的数据源。如果可能的话尽可能和离线保持一致。


明细层的建设思路其实跟离线数仓的基本一致,主要在于如何解决 ODS 层的数据可能存在的数据噪声、不完整和形式不统一的问题,让它在仓库内是一套满足规范的统一的数据源。我们的建议是如果有可能的话,最好入什么仓怎么入仓,这个过程和离线保持一致。


尤其是一些数据来源比较统一,但是开发的逻辑经常变化的系统,这种情况下,我们可能采用的其实是一套基于配置的入仓规则。可能离线的同学有一套入仓的系统,他们配置好规则就知道哪些数据表上数据要进入实时数仓,以及要录入哪些字段,然后实时和离线是采用同一套配置进行入仓,这样就可以保证我们的离线数仓和实时数仓在 DW 层长期保持一个一致的状态。


实际上建设 DW 层其实主要的工作主要是以下4部分:



唯一标红的就是模型的规范化,其实模型的规范化,是一个老生常谈的问题,可能每个团队在建设数仓之前,都会先把自己的规范化写出来。但实际的结果是我们会看到其实并不是每一个团队最终都能把规范落地。


在实时的数仓建设当中,我们要特别强调模型的规范化,是因为实施数仓有一个特点,就是本身实时作业是一个7×24 小时调度的状态,所以当修改一个字段的时候,可能要付出的运维代价会很高。在离线数仓中,可能改了某一个表,只要一天之内把下游的作业也改了,就不会出什么问题。但是实时数仓就不一样了,只要改了上游的表结构,下游作业必须是能够正确解析上游数据的情况下才可以。


另外使用像 kafka 这样的系统,它本身并不是结构化的存储,没有元数据的概念,也不可能像改表一样,直接把之前不规范的表名、表类型改规范。要在事后进行规范代价会很大。所以建议一定要在建设之初就尽快把这些模型的规范化落地,避免后续要投入非常大的代价进行治理。


3)重复数据处理


除了数据本身我们会在每条数据上额外补充一些信息,应对实时数据生产环节的一些常见问题:



4)唯一键和主键


我们会给每一条数据都补充一个唯一键和一个主键,这两个是一对的,唯一键就是标识是唯一一条数据的,主键是标记为一行数据。一行数据可能变化很多次,但是主键是一样的,每一次变化都是其一次唯一的变化,所以会有一个唯一键。唯一键主要解决的是数据重复问题,从分层来讲,数据是从我们仓库以外进行生产的,所以很难保证我们仓库以外的数据是不会重复的。


可能有些人交付数据给也会告知数据可能会有重复。生成唯一键的意思是指我们需要保证 DW 层的数据能够有一个标识,来解决可能由于上游产生的重复数据导致的计算重复问题。生成主键,其实最主要在于主键在 kafka 进行分区操作,跟之前接 ODS 保证分区有序的原理是一样的,通过主键,在 kafka 里进行分区之后,消费数据的时候就可以保证单条数据的消费是有序的。


5)版本和批次


版本和批次这两个其实又是一组。当然这个内容名字可以随便起,最重要的是它的逻辑。


首先,版本。版本的概念就是对应的表结构,也就是 schema 一个版本的数据。由于在处理实时数据的时候,下游的脚本依赖表上一次的 schema 进行开发的。当数据表结构发生变化的时候,就可能出现两种情况:第一种情况,可能新加或者删减的字段并没有用到,其实完全不用感知,不用做任何操作就可以了。另外一种情况,需要用到变动的字段。此时会产生一个问题,在 Kafka 的表中,就相当于有两种不同的表结构的数据。这时候其实需要一个标记版本的内容来告诉我们,消费的这条数据到底应该用什么样的表结构来进行处理,所以要加一个像版本这样的概念。


第二,批次。批次实际上是一个更不常见的场景,有些时候可能会发生数据重导,它跟重启不太一样,重启作业可能就是改一改,然后接着上一次消费的位置启动。而重导的话,数据消费的位置会发生变化。


比如,今天的数据算错了,领导很着急让我改,然后我需要把今天的数据重算,可能把数据程序修改好之后,还要设定程序,比如从今天的凌晨开始重新跑。这个时候由于整个数据程序是一个 7x24 小时的在线状态,其实原先的数据程序不能停,等重导的程序追上新的数据之后,才能把原来的程序停掉,最后使用重导的数据来更新结果层的数据。


在这种情况下,必然会短暂的存在两套数据。这两套数据想要进行区分的时候,就要通过批次来区分。其实就是所有的作业只消费指定批次的数据,当重导作业产生的时候,只有消费重导批次的作业才会消费这些重导的数据,然后数据追上之后,只要把原来批次的作业都停掉就可以了,这样就可以解决一个数据重导的问题。







请到「今天看啥」查看全文