数据仓库中作业任务复杂性及其可视化探寻[一]

Posted 从Excel到Hadoop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据仓库中作业任务复杂性及其可视化探寻[一]相关的知识,希望对你有一定的参考价值。

大数据领域分工多,每个人切入点可能不一样,工作中,数据分析人员、数据开发人员应该都会用到仓库、调度系统,如果你用到过,相信你肯定想吐槽:跑个SQL怎么这么慢?任务怎么又跑挂了?数据到底是咋来的?  

   

数据仓库、任务调度应该是一对CP,彼此谁也离不开谁,他们之间的结合应该是顺利产生数据“结晶”,支持数据分析、支持数据应用。理想是美好的、现实是坎坷的,事物间普遍存在着矛盾。

                 

大数据仓库中的主要矛盾之一

数据关联的复杂性 与 快速获取想要数据 之间的矛盾。怎么理解这个矛盾呢?下面从数据源种类、数据处理方式、数据关联3个方面来解释这个复杂程度。


1



首先,大数据平台接入的数据源多。


行为数据:一般是指用户设备的操作记录、及页面访问点击浏览记录。大多需要另外埋点进行采集。例如,H5页面浏览点击记录、App操作记录。这一类的数据。除此,还包括用户所用的设备信息、网络情况、及地理位置等。采集行为数据的主要目的是为了留存率、寻找用户达成交易的最短路径等。目前App大多都比较“流氓”,不仅要获取你的位置、文件访问权限、通讯录、录音功能等,冷不防还会截屏回传。不否认大数据的价值,但技术做得无底线,呼吁更多得数据工作者有底线的进行数据采集、分析,相关的法律也应该健全,事关我们每一个人。行为数据采集也会占用用户设备的性能,产品设计不只是界面的优化,好的产品设计应该是兼顾设备内部性能的提升,让更多的资源让位于主要服务功能的体验上面。


例如网页端的行为数据,一般包括访问URL、来源URL、设备屏幕高宽度、操作系统、网络环境等:

{'visit_url': ['http://www.xxx.com/index2'], 'from_url': ['http://www.xxx.com/index1'], 'sw': ['1440'], 'sh': ['900'], 'ptag': ['1_2_3_4'], 'platform': ['MacIntel']}{'visit_url': ['http://www.xxx.com/index4'], 'from_url': ['http://www.xxx.com/index3'], 'sw': ['1440'], 'sh': ['900'], 'ptag': ['1_2_3_4'], 'platform': ['MacIntel']}{'visit_url': ['http://www.xxx.com/index6'], 'from_url': ['http://www.xxx.com/index5'], 'sw': ['1440'], 'sh': ['900'], 'ptag': ['1_2_3_4'], 'platform': ['MacIntel']}{'visit_url': ['http://www.xxx.com/index8'], 'from_url': ['http://www.xxx.com/index7'], 'sw': ['1440'], 'sh': ['900'], 'ptag': ['1_2_3_4'], 'platform': ['MacIntel']}{'visit_url': ['http://www.xxx.com/index0'], 'from_url': ['http://www.xxx.com/index9'], 'sw': ['1440'], 'sh': ['900'], 'ptag': ['1_2_3_4'], 'platform': ['MacIntel']}


日志类数据:应用程序日志、服务器日志、操作类日志。一般说日志,更倾向于说服务器日志、用户设备日志。你大概会遇到,会有弹窗提醒“是否允许上报数据,以便我们进行客户端优化计划”。我们操作的日志会上报会服务器,以便通过日志发现问题,优化客户端体验。另一些日志是服务器端的运维日志,以便监测服务器、系统应用硬软件的运行情况。

另一方面,大数据平台由于昂贵的成本,会通过日志记录,获取每一次、每一个用户的资源利用情况。简单总结一下,日志可以对内分析服务性能、资源使用情况等,对外可以分析设备操作情况等。


一般日志格式如下,记录了日志时间、程序名称、日志级别、日志具体内容等:

30-01-2019 15:55:29 CST flow_instu_active INFO - INFO  : Compiling command(queryId=hive_20190130155555_cc17822c-d20d-4862-be70-585107205be3): drop table tmp.ind_mau_class_t30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : UserName: caijy30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : Semantic Analysis Completed30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : Returning Hive schema: Schema(fieldSchemas:null, properties:null)30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : Completed compiling command(queryId=hive_20190130155555_cc17822c-d20d-4862-be70-585107205be3); Time taken: 0.579 seconds30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : Executing command(queryId=hive_20190130155555_cc17822c-d20d-4862-be70-585107205be3): drop table tmp.ind_mau_class_t30-01-2019 15:55:29 CST flow_instu_active INFO - INFO : Starting task [Stage-0:DDL] in serial mode30-01-2019 15:56:03 CST flow_instu_active INFO - ERROR : FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:javax.jdo.JDOUserException:


用户行为数据、日志类数据占比很大,最大一般估计会占70%-90%左右。


关系型数据:ERP、CRM、呼叫中心等企业运营产生的数据,这种数据的采集要求比较高,行为数据、日志数据少几条没关系,但关系型数据不能出错,哪怕出错一条,可能会影响比较大。数据仓库不仅应用于数据分析之上,有时会用在有关员工切身利益的数据统计上、或者用于对外服务上,所以这类数据不容出错!


关系型数据格式如下:

|  Id    | User     | City  | Order_Id |+-----------+---------------+----------+| 123456 | Lily     | sz    | Y123453  || 123457 | Tom      | bj    | N535636  || 123458 | Xiaoming | sh    | N68344   |+--------+----------+-------+----------+


外部Api数据:外部服务对接数据,典型的就是与第三方合作,对方提供Api数据接口,我们通过接口获取数据,数据格式上,一般是Json类型的数据,也有可能是文本文件、压缩后的文件。例如在百度搜索投放的广告,可以通过百度提供的API接口,获取每个账户计划的展现量、点击量、点击单价等,以便和内部的数据进行关联做分析。


通过Http协议,一般获取Api接口中的数据格式如下:

HTTPS/1.1 200 OK{    "message"u"OK",    "code"0,    "data": [ {            "activate"4835,            "show"2112418,            "click_install"10918,            "active"0,            "send"1570380,            "click"81755,            "download_finish"15290,            "stat_cost"29501.4,            "phone"0,            "convert"4835,            "install_finish"5431,            "stat_datetime""2017-02-17 00:00:00", } ]}



爬虫类数据:公司为了数据的广度、完整性,会采集相关领域的网站信息,同行业、上下游等。例如,卖房卖车的会爬取网上的评论、做地理位置服务会爬取poi信息。爬虫应该也是大多分析师、非技术同学接触比较多的,也会通过一些采集软件或者直接写Python,去爬取一些评论进行分析等。


网页上的表格信息,格式如下,tr表示行,td表示单元格:

<tr>  <td class=""><a class="zbExp" exp="经济活动人口指在16周岁及以上,有劳动能力,参加或要求参加社会经济活动的人口。包括就业人员和失业人员。" href="javascript:void(0);"><img src="images/icon-1.png"></a>经济活动人口(万人)</td> <td align="right" class="">80686.0</td> <td align="right" class="">80694.0</td> <td align="right" class="">80091.0</td> <td align="right" class="">79690.0</td> <td align="right" class="">79300.0</td> <td align="right" class="">78894.0</td> <td align="right" class="">78579.0</td> <td align="right" class="">78388.0</td> <td align="right" class="">77510.0</td> </tr>

注:上面数据是近年经济活动人口(万人),来源http://data.stats.gov.cn/easyquery.htm?cn=C01


数据源一般就分为行为数据、日志数据、关系型数据、外部API数据、爬虫数据,这几种数据源我分别举了具体的例子。这几种数据源接入到数据仓库前,除了关系型结构化数据,非结构化数据一般是以两种格式存在:JSON格式、CSV格式。


JSON是由键值对或嵌套的键值对组成。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

CSV由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。


数据接入一般需要多部门协作,例如埋点需要前端协作,外部Api类的数据需要与第三方沟通。有的时候,分析师需要某一种数据,需要快速接入。麻烦的,数据接入不仅纯粹接入的是数据,更加需要的是数据间的联系。例如交易系统中,哪些表支持的是同一个功能,所以数据接入后,数据仓库人员或者分析师需要与业务系统的产品人员或者开发人员确认数据间的关系,加工处理后落实到数据仓库中。


另外,数据源的多样性,也考验数据是否完整、准确落地到数据仓库,数据采集有需要完整的规范文档,规定具体采集哪些信息,仓库人员和分析人员需要对采集过程有大概得了解,这样对数据质量更有保证,因为数据质量的一部分问题就是出在采集入库这个环节,会引起不必要的内耗成本。


P.S:了解数据源的种类还不够,还需要了解采集过程、了解各源的数据特点及相互间的联系!这样入库后的数据质量更有保证。



2



其次说起复杂性,主要是数据处理流程、数据种类及处理工具的多样:


1、数据接入,Kafka、Sqoop

2、数据清洗,Spark、MR任务、HiveSQL

3、数据建模,HiveSQL、Spark等

4、数据应用,Hbase、Kylin 、mysql


试想,如果数据源接入数据平台前,能够把数据格式统一,那么数据清洗环节就可以按统一格式方便处理,或者说,如果有种工具能够先接收各种数据源的格式,然后转换为统一的格式后,方便清洗。例如Kafka可以接入消息数据,也可通过接入Mysql日志以实现接入关系数据。


数据流动过程中,从数据接入、清洗、建模、到应用,每个过程都要用到不同的数据处理工作。由于数据采集源的不同,所以用到的接入工具不一样。上面说到,虽然数据源不一样,但数据的格式主要分为:JSON和CSV。Spark在清洗这两种格式上有很方便的方法。


1、Spark清洗JSON格式的文件。

from pyspark.sql import SparkSessionfrom pyspark.sql.types import StructType, StructField, StringType, LongType, ArrayType, IntegerTypespark = SparkSession.builder \    .appName("test") \ .config("spark.yarn.queue", "etl") \ .config("spark.scheduler.mode", "FAIR") \    .config("spark.jars""/user/spark/lib/") \ .enableHiveSupport() \ .getOrCreate()
dataframes = [spark.read.json( path=rdd,    schema=StructType([     StructField("uid", LongType(), True),        StructField("name", StringType(), True),        StructField("data"         ArrayType(StructType([                            StructField("authOperator", StringType(), True),                               StructField("resultCode", StringType(), True),                               StructField("resultMsg", StringType(), True),                           ]), True),                     True)         ]), mode='PERMISSIVE', columnNameOfCorruptRecord="corrupt_record" ).cache() for rdd in ["hdfs://nameservice1/user/log/1.json", "hdfs://nameservice1/user/log/2.json"]]


2、Spark清洗CSV格式的文件。

dataframes = [spark.read.csv( path=rdd, schema=StructType([ StructField("uid", LongType(), True), StructField("name", StringType(), True), StructField("data",  ArrayType(StructType([ StructField("authOperator", StringType(), True), StructField("resultCode", StringType(), True), StructField("resultMsg", StringType(), True), ]), True), True) ]),        sep='\t', mode='PERMISSIVE',  columnNameOfCorruptRecord="corrupt_record"    ).cache() for rdd in ["hdfs://nameservice1/user/log/1.txt""hdfs://nameservice1/user/log/2.txt"]]




一种工具不可能满足所有的需求。同样,一个人不太可能全部掌握所有的工具(也不一定噢),所以,数据平台是从一个数据支撑到数据服务产品的发展过程,考虑怎么把各种工具封装的更统一、更方便,例如Hive、spark、Hbase全部开放Sql查询窗口,如果平台做得棒,那么实时计算、流式计算、批处理、即席查询这些东西都可以让非开发人员直接使用。


P.S:选工具处理数据,需要依据公司的业务特点与需求,数据计算时效一般分为:批处理、流式计算、实时计算,另外Hadoop平台各组件的版本升级也影响着数据处理的效率。



3



最后数据关联的复杂性。一个公司,单个业务链条的数据关联就比较复杂(如供应链),要构建企业级的数据仓库,还要关联不同业务链条间的数据,包括推广、客服、订单、财务在内的不同模块,由于关联复杂,所以企业数据仓库的作业任务也会比较杂乱。


下图是公司数据仓库可能的任务依赖关系图(随机生成),一个点,你可以理解为一个脚本或者一条复杂的HiveSQL。

上面有向关系依赖图是用Python画出来的,如果你写想尝试画下,请看我写的这篇文章《》,冻手试试,你也可以了解你公司数据仓库整体作业任务的复杂情况。


业务需求越来越多,作业任务就越来越复杂,稍微有点规模的公司,就独立出数据仓库工程师、或者数据仓库建模工程师等仓库管理岗位,用来解决数据关联复杂的问题,采用流行的仓库分层措施,防止仓库的野蛮生长。


野蛮生长与分层优化


右图是理想的情况,数据经过一层层关联处理,最后落实在集市层或者应用层,但实际情况,大多公司的数据仓库像左图,分层上不明显,缺少总体设计,来了个需求就立马进入数据开发。互联网公司本身就变动快,做到数据仓库规划设计不容易,很可能还没设计完,业务就又调整了。所以,貌似数据部门各岗位都很齐全,从数据接入、数据清洗,到仓库建模、数据应用分析,每个环节都配备人员专门管理,但"搬砖"是日常主要工作之一。特别对于快速变动的产品、快速变动的业务,再加上人员的变动,让人措手不及。


这个时候怎么办,“元数据”管理该登场了。元数据决定上层建筑。每个表是怎么命名的,每个字段是怎么命名的,每个作业任务是怎么命名的。这个也是最基本、最容易先要做到的。不要小看元数据管理,哪怕你变动再快,再复杂,只要在元数据上统一口径,大家都会少加点班。


P.S:关联的复杂,需求变动,数据仓库也要考虑到易用性。如果是野蛮生长,最起码要做到的是数据字典、建表规范、脚本清晰规范,减少不必要的沟通成本。


数据流动的最终目的是要被应用的,数据工作者最好也能够熟悉或者参与过数据采集、清洗、建模整个流程环节。例如,对于分析师来讲,在查询数据前,数据已经经过一系列的处理步骤和关联,分析师完全有权利去质疑所拿到数据的靠谱程度,如果数据不靠谱,会严重影响数据的。


数据来源的复杂性,处理工具的多样性,加上数据仓库的野蛮生长,这都让数据关联越来越复杂,也耗用更多的存储资源、计算资源,同时给给调度工具带来挑战。


《数据仓库中作业任务复杂性及其可视化探寻》,打算分三篇文章写,本篇是第一篇。仓库作业任务需要调度系统,下一篇就写调度系统,关于调度的系统架构、复杂性等,欢迎继续关注。




近期文章链接


1、《》,Python代码举例

2、《》,了解数据“传输”的瘦身过程

3、《》,搭建简单Web服务

4、《》,从成本角度对大数据多一个认知维度。



专注于为想在大数据、技术方面发展的读者

用心写文章

以上是关于数据仓库中作业任务复杂性及其可视化探寻[一]的主要内容,如果未能解决你的问题,请参考以下文章

作业进程线程多线程多核

个人阅读作业+总结

通过github desktop 上传代码到github 远程仓库

打造一流的电商仓库

大数据思维导图-数据采集存储数据仓库计算框架资源管理&任务调度部署可视化

GitIntelliJ IDEA 提交代码到 GitCode 远程仓库 ( GitCode 创建远程仓库 | 将本地工程推送到 GitCode 远程仓库 | 验证权限 | 生成个人访问令牌 )(代码片