浅谈大数据技术之测试

最近参与大数据测试,主要工作就是造源数据-跑脚本-结合测应用端的一整套流程,在结合自己对技术架构的浅度了解加上标签的原理等一些知识整理一下我所学习到的大数据测试全路程

前置条件

  1. 开通各种账号,找公司运维
  2. 要准备的(mysql、Linux环境、标签逻辑等)

测试全流程

  • 先按照自己的理解画的流程图,上图ligoIx.png
  • JSON是源数据
    • crm_members_dim 消费者维度表
    • crm_order_pay_detail_d 订单付款方式明细表
    • crm_orders_fact_d 交易事实表
    • crm_order_items_fact_d 交易明细事实表
    • crm_refunds_fact_d 退单事实表
    • crm_refund_items_fact_d 退单明细事实表
    • coupon_detail 优惠券维度表
    • crm_coupons_used_detail_d 订单优惠券使用明细
    • crm_categories_dim 品类字典表
    • crm_online_channels_dim 线上消费渠道维度表
    • crm_offline_channels_dim 线下消费渠道维度表
    • crm_products_dim 商品维度表
  • HDFS的作用是将源数据文件存放到hdfs中后再loadHive中,Hive与HDFS之间又有什么关系呢?因为Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的 sql 查询功能,可以将 sql 语句转换为 MapReduce 任务进行运行。其优点是学习成本低,可以通过类 SQL 语句快速实现简单的 MapReduce 统计,不必开发专门的 MapReduce 应用,十分适合数据仓库的统计分析。
  • Hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。
  • Tags是通过基础的维度表、字典表、事实表执行脚本后跑出中间表和tag表的数据,存到hive中。按照一定的先后顺序执行脚本,执行每一个tag都会有依赖表,看下图。Yd9mge.png 为什么要依赖这些表呢?我整理的部分表和表之间的执行逻辑,再次看下图,剩下的执行tags表的逻辑也是一样的。YdC9G8.png
  • SQLhive表里有很多数据了,通过后端开发工程师将数据存储到SQL中。比如人群绩效功能涉及到的Mysql表为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    库名-geek-dmp-api
    1. crowd_coustomr_relationship_report:人群客户关系表,包含 时间、客户关系类型、订单统计信息表
    对应业务:前五张表:'客户关系类型 1 入会未购买 2 会员购买 3 粉丝购买 4 分享会员'
    2. crowd_level_report:人群等级表,包含时间、等级类型(客户CRM等级、消费者价值等级)、客户订单统计信息表
    对应业务:前5张表中的V1-V5
    3. crowd_member_join_report:人群入会表,包含 时间、 人群入会渠道 、 入会所在地、订单统计信息表
    对应业务:后3张表的三种图
    4. crowd_performance_report:人群绩效基础表,包含 时间 与 订单统计信息表
    对应业务:前5张表的'1 未购买、2 首购、 3 复购、4 活跃、5 沉睡、6 流失'的表
    5. crowd_performance_tag_report:人群绩效统计概览表
    对应业务:横tab数据
  • 前端不用过多解释了,主要是用html5cssjs等前端相关技术加上Vue前端开发框架实现面向用户操作界面。

    技术架构

  • 技术架构不是测试工程师必须要知道的,但了解了原理能更好的知道为什么测试要这样造数据,跑数据等,接下来就简单的介绍一下(适用版),看下图
    l1azOP.png
  • 简单解释一下ODS DWD DWS ADS的定义:

    • ODS:Operation Data Store 原始数据
    • DWD(数据清洗/DWI) data warehouse detail 数据明细详情,去除空值,脏数据,超过极限范围的 明细解析 具体表

      1
      load data inpath '/dmp/data/dev/members20191020/members20191020.log' into table crm_members_dim  PARTITION (ds = '20191020')
    • DWS(宽表-用户行为,轻度聚合) data warehouse service —–>有多少个宽表?多少个字段 服务层–留存-转化-GMV-复购率- 日活 点赞、评论、收藏; 轻度聚合对DWD

    • ADS(APP/DAL/DF)-出报表结果 Application Data Store 分析数据库服务,做分析处理同步到RDS(关系型数据库)数据库里边
  • EasyScheduler
    • 是一个分布式工作流任务调度系统,主要解决数据研发ETL(Extract-Transform-Load:用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程-常用在数据仓库中)错综复杂的依赖关系所带来的各种问题
      lNsGdg.png
  • Datax
    • 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、MaxCompute(原ODPS)、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能
      1
      2
      1. ./datax.py ~/qa/datax-json/daily_stats-qa.json
      2. 为了实现HDFS----->Hive中的数据同步

Jenkins自动构建

  • 通过Jenkins从源数据到最后的数据自动落入到hive中,一键触发等待结果即可,以下是构建成功的历史记录
    l6NcV0.png
  • 详细介绍一下构建的执行脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    # 定义环境参数
    envir=${envir}
    namePath=${testerName}

    #从步步高远程上下载脚本
    wget http://****************************/dev/auto_datacreate/${envir}.tar.gz > /dev/null
    #dev/null是一个特殊的设备文件,这个文件接收到任何数据都会被丢弃
    tar -zxvf ${envir}.tar.gz > /dev/null
    rm -rf ${envir}.tar.gz

    #执行环境
    runhost="************"
    yd=$(date -d "yesterday" +%Y-%m-%d)

    #递归复制整个文件到执行测试环境下的目录
    scp -r shellzm/* bbg_dc@$runhost:/home/bbg_dc/qa/

    #删除hive表、Hdfs里的数据
    ssh -o StrictHostKeyChecking=no bbg_dc@$runhost "source /etc/profile;sudo sh -x /home/bbg_dc/qa/hive_zm.sh > /home/bbg_dc/qa/logs/hive.log"


    echo ${WORKSPACE}

    source /data/apps/envworkspaces/python3.7/bin/activate

    if [ ! -d outPut ];then
    mkdir outPut
    fi

    #根据变量envir从远程下载下来的文件输出到outPut下后统一复制到测试环境某目录下
    if [ "$envir" == "dev" ];then
    mv $namePath/crm_members_dim.log outPut/crm_members_dim.log.$yd
    mv $namePath/crm_orders_fact_d.log outPut/crm_orders_fact_d.log.$yd
    mv $namePath/crm_order_items_fact_d.log outPut/crm_order_items_fact_d.log.$yd
    mv $namePath/crm_categories_dim.log outPut/crm_categories_dim.log.$yd
    mv $namePath/crm_online_channels_dim.log outPut/crm_online_channels_dim.log.$yd
    mv $namePath/crm_offline_channels_dim.log outPut/crm_offline_channels_dim.log.$yd
    mv $namePath/crm_products_dim.log outPut/crm_products_dim.log.$yd
    scp outPut/*.log.$yd bbg_dc@$runhost:/data/apps/geek/logs/geek-data-access/$envir/
    fi

    #根据变量testerName执行源数据到hive后再执行中间表和Tags表使其都有数据
    if [ "$testerName" == "shouye1022" ];then

    ssh -o StrictHostKeyChecking=no bbg_dc@$runhost "sh -x /home/bbg_dc/qa/json2qa_20191022.sh $envir"
    ssh -o StrictHostKeyChecking=no bbg_dc@$runhost "sh -x /home/bbg_dc/qa/tags/bin/run_home.sh 20191022"
    else
    echo "请正确选择列表中选项"
    fi
  • 再详细的介绍.sh文件

    1. hive_zm.sh

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      #!/bin/bash
      #清除exchange中的全部数据
      rm -rf /data/apps/geek/logs/geek-data-access/dev/*
      # 清除Hdfs中存储的源数据
      sudo -u hdfs;source /etc/profile;hdfs dfs -rm -r /dmp/data/dev/*
      arr=(crm_members_dim members_oneid_dim...)
      for var in ${arr[*]};
      do
      hive -e "USE jieke_qa;truncate table ${var};"

      echo "${var}表数据已经清空"
      done
    2. json2qa_20191022.sh

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      source /etc/profile
      echo "$1"
      yd=$(date -d "yesterday" +%Y-%m-%d)
      blue " Exchange服务:json文件,并放到/data/apps/geek/logs/geek-data-access目录下 "
      lpath=/data/apps/geek/logs/geek-data-access/$1
      echo "$lpath"
      #带ds的表
      arr=(
      crm_members_dim.log/crm_members_dim
      crm_orders_fact_d.log/crm_orders_fact_d
      crm_order_items_fact_d.log/crm_order_items_fact_d ...)
      #对源数据文件循环判断
      for var in ${arr[@]};
      do
      #if [ ! -f "$lpath/${var%/*}.$yd" ]; then %/* 清除/右边的所有数据 #/* 清除/左边的所有数据 $# 是传给脚本的参数个数 $@ 是传给脚本的所有参数的列表
      if [ ! -f "$lpath/${var%/*}.$yd" ]; then
      echo "文件$lpath/${var%/*}.$yd不存在"
      else
      #清除hdfs的源数据,hdfs默认如果目录下存在文件,则不会进行覆盖,所以在下一次跑数据之前需要除
      #创建目录
      sudo -u hdfs;source /etc/profile;hdfs dfs -mkdir /dmp/data/dev/${var#*/}
      #取本次源数据文件存放到hdfs
      blue " 取源数据文件$lpath/${var%/*}.$yd 存放HDFS /dmp/data/$1/${var#*/}目录下 "
      #有日期
      sudo -u hdfs;source /etc/profile;hdfs dfs -put $lpath/${var%/*}.$yd /dmp/data/dev/${var#*/}
      #hdfs源文件数据加载到hive中
      blue " ${var%/*}.$yd 文件存放在 HIVE 表 ${var#*/}中"
      sql="load data inpath '/dmp/data/$1/${var#*/}/${var%/*}.$yd' into table ${var#*/} PARTITION (ds = '20191018')"
      #hive -e "USE jieke_qa;load data inpath '/dmp/data/dev/members20191020/members20191020.log' into table crm_members_dim PARTITION (ds = '20191020')"
      hive -e "USE jieke_qa;${sql}"
      fi
      done
      blue "执行完毕"
      #不带ds的表
      arrnew=(
      crm_categories_dim.log/crm_categories_dim
      crm_online_channels_dim.log/crm_online_channels_dim
      crm_offline_channels_dim.log/crm_offline_channels_dim
      crm_products_dim.log/crm_products_dim)

      for var in ${arrnew[@]};
      do
      if [ ! -f "$lpath/${var%/*}.$yd" ]; then
      echo "文件$lpath/${var%/*}.$yd不存在"
      else
      #清除hdfs的源数据,hdfs默认如果目录下存在文件,则不会进行覆盖,所以在下一次跑数据之前需要除
      #创建目录
      sudo -u hdfs;source /etc/profile;hdfs dfs -mkdir /dmp/data/dev/${var#*/}
      #取本次源数据文件存放到hdfs
      blue " 取源数据文件$lpath/${var%/*}.$yd 存放HDFS /dmp/data/$1/${var#*/}目录下 "
      #有日期
      sudo -u hdfs;source /etc/profile;hdfs dfs -put $lpath/${var%/*}.$yd /dmp/data/dev/${var#*/}
      #hdfs源文件数据加载到hive中
      blue " ${var%/*}.$yd 文件存放在 HIVE 表 ${var#*/}中"
      sql="load data inpath '/dmp/data/$1/${var#*/}/${var%/*}.$yd' into table ${var#*/}"
      hive -e "USE jieke_qa;${sql}"
      fi
      done
      blue "执行完毕"
    3. run_home.sh

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      #!/bin/sh
      > /tmp/qa-tags.sh
      echo "
      export BIPROG_ROOT=/home/bbg_dc/qa/tags
      alias writelog='echo'
      alias EXEHIVE_CMD='beeline -u jdbc:hive2://********:10000 -n hdfs -e \"\$CMD\"'
      " >> /tmp/qa-tags.sh
      cat /home/bbg_dc/qa/tags/oneid.sh | sed 's/\r$//g' | sed 's/union$/union all/g' | sed 's/jkcrm/jieke_qa/g' | sed 's/exit/echo/g' >> /tmp/qa-tags.sh
      cat /home/bbg_dc/qa/tags/intermediate_OrderAfterReturn.sh | sed 's/\r$//g' | sed 's/union$/union all/g' | sed 's/jkcrm/jieke_qa/g' | sed 's/exit/echo/g' >> /tmp/qa-tags.sh
      ...
      sh /tmp/qa-tags.sh dummy $1 1
  • 至此所有的大数据逻辑都梳理完成了,另外在调试脚本中遇到的一些问题及解决方法如下

    调试出现异常解决方案

  • 解决方案:先drop表再重新创建表

    1
    FAILED: ValidationFailureSemanticException table is not partitioned but partition spec exists: {ds=20191022}
  • 解决方案:pay_amt double COMMENT ‘付款金额’,表字段不支持decimal(20,4),修改表字段属性为double

    1
    Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.hadoop.hive.common.type.HiveDecimal
  • 解决方案:造的数据长度过长,修改源数据值

    1
    Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.NumberFormatException: Value out of range. Value:"800000934" Radix:10
  • 解决方案:造的数据格式不对,缺少逗号,用【select * from 表名 limit 行数】排查

    1
    Failed with exception java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: Row is not a valid JSON Object - JSONException: Expected a ',' or '}' at 44 [character 45 line 1]
  • 解决方案:先drop表再重新创建表

    1
    2
    truncate table tablename报错如下:
    FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Exception while processing
  • 解决方案:把脚本里的set hive.exec.dynamic.partition =true;一行删除

    1
    Faild with exception set hive.exec.dynamic.partition =true;

拓展

  • hadoop中有3个核心组件:

分布式文件系统:HDFS —— 实现将文件分布式存储在很多的服务器上(文件系统,数据存储技术相关)

分布式运算编程框架:MAPREDUCE —— 实现在很多机器上分布式并行运算(数据处理)

分布式资源调度平台:YARN —— 帮用户调度大量的mapreduce程序,并合理分配运算资源

参考文章