zoukankan      html  css  js  c++  java
  • 面试(串讲二)

    六、Hive

    6.1 基本架构

    6.2 与数据库的比较

      mysql hive
    速度 数据量小、快 数据量大、快
    场景 小数据量的增删查改 大数据量的查询分析

    6.3 内部表、外部表

      删除内部表:删元数据、原始数据

      删除外部表:删元数据

      企业怎么用?

        主要用外部表,临时表和测试表用内部表

    6.4 4个By

      order by:全局排序,最终只有一个reducer,结合limit一起使用

      sort by:分区内排序

      distribute by:分区,指定数据该进入哪个reducer

      cluster by:当sort by 与 distribute by字段一致时,且升序,可以用cluster by代替

    6.5 系统函数

      时间:date_add、date_sub、datediff、next_day、last_day、xxxofxxx、from_unixtime、unix_timestamp、now、date_format

      字符串:substring、split、concat、concat_ws、get_json_object、replace、regexp_replace

      行列转换:

        一行转多行:explode(数组、map)

        多行转一行:collect_list、collect_set

        一列转多列:if、case when

        多列转一列:concat、concat_ws

      空值处理:nvl、if

    6.6 窗口函数

      聚合类、排名、lead、lag、first_value、last_value  over(partition by ...order by ... 行的范围)

      行的范围:rows、range

      例如:sum() over()

      rows range
    1 1 1
    2 3 3
    3 6 9
    3 9 9
    4 13 13
    5 18 18

      order by 默认行范围:range 上无边界到当前行

    6.7 自定义函数

      UDF:一进一出

      UDTF:一进多出

      UDAF:多进一出

      项目里用到了什么?UDTF:用来解析Json数据里面的Array,实现一进多出

      为什么不用get_json_object?它只能一进一出

      怎么实现?定义一个类,继承GenericUDTF,重写3个方法

        初始化方法:输入参数的效验,比如个数、类型,返回类型的约束

        process方法:多次调用fowward

        close()

      完成之后打jar包,上传至HDFS,然后在客户端中输入:

    create function 方法名 as 全类名 using jar 'hdfs路径'

      为什么用自定义?

        1、解析Json中的Array,一进多出

        2、方便使用第三方依赖

    6.8 优化

      1)map join:大小表,默认打开

      2)列式存储:orc、parquet

        结构更紧凑,压缩比更高,适合查询更新

    id name age
    1 zs 18
    2 ls 20

        列式存储:1 2  zs ls  18 20

        行式存储:1 zs 18  2 ls 20

      3)分区、分桶

      4)压缩:lzo、snappy

      5)小文件:

        JVM重用:10

        使用CombineHiveInputFormat来进行切片:256m

        merge:单独再启动一个job,将平均小于16M的文件,合并为一个最大为256M的文件

          map-only:默认开启

          map-reduce:默认关闭,设置为开启

      6)行列过滤:

          避免select *

          能先过滤就先过滤

        谓词下推:在map阶段,提前过滤(若需要详细了解,请参考博客:https://www.cnblogs.com/LzMingYueShanPao/p/15167014.html

        两张表关联,过滤条件写在on和写在where有什么区别?

          select xxx from a join b on a.id > 10
          select xxx from a join b where a.id > 10

        首先先判断是什么Join

          如果是内连接,无任何区别

          如果是满外连接,on性能比where差,因为默认开启cbo优化,where可以进行谓词下推

          如果是left join或 right join,再判断条件来自哪张表

            如果判断条件来自保留表,则on性能比where差,因为on不能进行谓词下推

            如果判断条件来自非保留表,则无任何区别,因为默认开启cbo优化,where可以进行谓词下推

      7)Map数量

        切片大小 = max(minSize,min(maxSize,块大小))

      8)reduce数量

        估算机制:输入的数据量 / 单个Reducer处理的数据量

        参数设置:mapred.reduce.tasks,默认 -1,表示不开启

        特殊语法:order by  1个

        优先看是否指定了参数,如果没有,就走估算机制

      9)多引擎

        mr:年月指标

        spark:日常的天指标

        tez:临时用

        若不同引擎结果不一,以MR为主

        如何实现不同Job不同引擎来跑?

          1、部署spark环境

          2、set hive.execution.engine = spark;

             sql

             set hive.execution.engine = mr;

                sql

    6.9 数据倾斜

      1)现象:yarn页面,个别reduce执行时间明细特别长,卡在99%

      2)原因:

        数据本身就不均匀

        Null值

        类型不一致

      3)解决方案

        辅助措施:提前Combiner,在不影响最终逻辑的情况下

        数据本身就不均匀:二次聚合

          参数:hive.groupby.skewindata,解决group by数据倾斜,自动实现二次聚合

                hive.optimize.skewjoin,解决join的数据倾斜,自动实现二次聚合

        null值:

          null值无意义,先过滤

          null值有意义,二次聚合,使用到nvl

        类型不一致:先转换类型,再join    a join b on cast(a.id,string) = b.id

    6.10 分隔符问题:数据本身携带了hive的分隔符

      问题:hive表字段错误

      解决:

        1、参数 --> 默认分隔符为 01

        2、mysql表导一张到临时表,再同步到hdfs

        3、让后端人员改

    七、Sqoop

    7.1 遇到哪些问题

      1)空值问题

    mysql  Hive 
     null

        导入时:null-string、null-non-string

        导出时:input-null-string、input-null-non-string

      2)导出是,遇到一致性问题

        底层跑的是4个map任务,解决方法就是手动创建一张临时表,将数据导入临时表中,数据全部进入临时表后,再导入到目标表,有两个参数可以设置:

    –staging-table mysql表名_tmp   (将数据先导入临时表)
    –clear-staging-table       (清空临时表)

      3)数据倾斜问题

        我们一天1个G左右,没遇到

        但是以前有个朋友遇到过:split-by 指定自增主键,指定增加map数

    7.2 每天业务数据有多少?

      60万日活,平均每天6万订单,每个订单10条数据,每条数据平均1k

      6万 * 10 * 1k = 600000k ≈ 600M左右

    7.3 每天几点跑,跑多久?

      00:10开始跑,大概跑10多分钟

    7.4 参数

    sqoop --import
    --connect url
    --user
    --password
    --target-dir
    --delete-target-dir
    --query 'select xxx from where xxx $condition'
    --空值处理的两个参数
    --split-by
    --mapper

    7.5 导出时,parquet问题

      1)先将数据导入到格式为Text格式的临时表中,再导出

      2)一开始就不要用列式存储

      3)hcatalog导出,sqoop参数,要求版本1.4.5

    八、Azkaban

    8.1 每天几点跑,跑多久?

      第一个脚本:sqoop同步脚本,00:10开始跑

      平均3个多小时,不管怎么跑,早上八点一定会出结果

    8.2 日常跑多少指标?活动时多少?

      日常跑100来个指标,有活动时200来个

    8.3 任务挂了怎么办?

      告警:邮件、发短信、发微信、发钉钉、打电话

        实现:调用第三方接口,oneAlter

      尝试重启:自动重试、手动重试

      解决问题:看日志(资源不够、业务表发生改变)

              摇人

    九、项目架构

    9.1 从0到1

      1)集群规模:目前有没有服务器给你用,几台?一共有9台,后来增加到12台

      2)数据量:日志数据每天60G左右,业务数据每天600多M

      3)周期:采用敏捷开发模型,基本上一个月为一个开发周期,比如1.2.3版本号,一个星期更换数据为3的版本号,表示小范围的更新,2这个数据一般一个月更新一次,表示中等规模的更新,1的话一般半年或一年更新一次,表示大的一个版本更迭

      4)资金:服务器买了3台,每台服务4万块,3台一共12万多

      5)人员:5个人,包含组长

      6)指标规划:第一期指标20多个,比如求新老用户、留存率、页面跳转率、活跃人数、每日下单数、每日支付数、每日下单金额等

      7)数据来源:oracle、db2、sqlserver、qp、mysql

    9.2 数仓概念

      1)数据来源:前端埋点日志、javaee后台业务服务

      2)产出:报表、用户画像、推荐系统、风控系统

    9.3 版本选型

      开源版:apache,大厂

      商业版:cdh、hdp -->cdp,1个节点1万美金/年

        cdh:6.3.2

        hdp:3.1.4

      建议选哪个?建议选apache、虽然成本比较高昂,但安全性强

    9.4 集群规模:几台服务器,60万日活

      1)磁盘:半年不扩容

         数仓分层:

          日志:

            ods:6G(压缩后)

            dwd:6G(压缩后)

            dws + dwt:30G,压缩后3G

            ads:忽略

            6 + 6 + 3 = 15G,给个20G

            20G * 3 副本 * 180天 / 0.7 ≈ 15T,给20T

          业务:

            2G * 3副本 * 180天 / 0.7 = 2T

        kafka:之前给1T

        20T + 2T + 1T = 23T

        23T / 8T = 3台

      2)内存:

        7台 * 128G = 896G

        1台服务器的NodeManager给100G -->100G * 7 = 700G

        离线:128M数据 --> 1G内存(占比约1:8),同时跑70G的数据,大约需要600G内存左右

        实时:10 + 几个Job,1个Job10多G,大约需要200G内存左右

        通过计算,7台不太够,建议:9~15台

      3)CPU

        单台20核40线程

        40 * 7 = 280(200给集群 ,80给其他)

        实时:1个Job,6个并行度 --> 6线程,  6 * 10多个 约等于 90线程

        离线:100+ 可用

        通过计算,7台不太够,建议9~15台

    十、数仓分层

    10.1 建模第一步做什么?

      理清业务逻辑,求出业务表

    10.2 ods

      1)使用分区表,避免全表扫描

      2)压缩,减少磁盘空间

      3)保持数据原貌,起到备份的作用

    10.3 dwd + dim

      1)清洗工具

        hql、spark、flink、python、kettle

      2)清洗原则

        解析数据

        去重

        核心字段不能为空

        超期数据(爬虫)

        脱敏:md5

      3)清洗比例:万分之一

        若清洗比例较高,找前端和Java开发人员沟通

      4)分区

      5)压缩

      6)列式存储

      7)维度退化

        基于维度建模的星型模型理论

        降维:将某个维度的所有表合并成一张表,以后关联某个维度时,只需要join一次

        sku表、spu表、三级、二级、一级分类、品牌、商品平台属性表、商品销售属性表 -->商品维度表

        省份表、地区表 --> 地区维度表

        活动信息表、活动规则表 --> 活动维度表

      8)维度建模

        (1)选择业务过程,选择需要的业务表

          小公司,30来张,全都要

          大公司,上千张,选择需要的业务模块:下单模块、支付模块、物流模块...

        (2)声明粒度

          什么是粒度?一行数据代表什么行为

          比如订单表的一行数据,代表了一次下单行为

          声明最小粒度:只要不做聚合操作,就已经是能达到的最小粒度

        (3)确定维度:描述某个业务事实的角度

          何时、何地、何人对何物做了何事(时间、地区、用户、商品、下单或支付)

        (4)确定事实

          关注事实的度量值:个数、件数、金额、次数等可统计的量词

          使用业务总线矩阵来计算

    10.4 dws:一天的汇总

      1)有哪些宽表:主要参考维度表,有多少维度,就有多少宽表

          地区、用户(会员)、访客(设备)、商品、活动、优惠券

      2)宽表有哪些字段:站在维度的角度,关注事实的度量值

    10.5 dwt:一段时间的累计

      目的: 避免重复计算

      1)有哪些宽表:主要参考维度表 ,有多少维度表,就有多少宽表

          地区、用户(会员)、访客(设备)、商品、活动、优惠券

      2)宽表有哪些字段:站在维度的角度,关注事实的 开始时间、结束时间、这段时间度量值的累积、最近一段时间度量值的累积

    10.6 ads:

        指标:

        手写:实现思路

        比较难的指标:

    十一、数仓业务

    11.1 埋点格式

      页面日志、启动日志、曝光日志、事件日志、错误日志

      1)启动日志

    {
        "common":{},
        "start":{}
        "err":{},
        "ts":xxxxxx
    }

      2)其他

    {
        "common":{},
        "actions":[{},{},...],
        "display":[{},{},.....],
        "page":{},
        "err":{},
        "ts":xxxx
    }

    11.2 同步策略

      业务数据MySQL --> Sqoop --> HDFS

      全量数据:数据量小

        sqoop的query  "select * from 表名 where 1=1"

      新增数据:数据量大,历史数据不会变化

        sqoop的query  "select * from 表名 where 创建时间=昨天"

      新增及变化:数据量大,历史数据会变化(后续dim层,使用拉链表)

        sqoop的query  "select * from 表名 where 创建时间 = 昨天 or 操作时间 = 昨天"

      特殊数据:全量导入

    11.3 建模理论

      关系建模:业务库MySQL,基于三范式理论的第三范式

        减少数据冗余,取哪个维度就要跟哪个维度join一次

      维度建模:星型模型、雪花模型、星座模型

        降维,取一个维度,只需要join一次,需要数据冗余,不灵活(字段变更)

        星型模型:一张事实表周围围绕着多个一级维度表

        雪花模型:一张事实表周围围绕着多个多级维度表

        星座模型:多个事实表周围围绕着多个一级维度表

    11.4 业务库的表发送变化怎么办?

      1)新字段,历史数据需不需要补全

        需要:一点点改,重新跑任务

        不需要:从新增开始,有数据就行,改数仓脚本就行,加上字段

      2)减字段

        改数仓脚本,减去字段

    11.5 数仓有几张表

      ods:日志1张,业务27张

      dwd:日志5张,9张事实表,6张维度表

      dws:宽表6张

      dwt:宽表6张

      ads:约30张

      我们公司100张左右

    11.6 数仓哪张表最大?

      50G / 5张日志表 = 平均10G

      用户行为宽表:10G * 3 = 每天30多G

    11.7 实时资源

      Flink:JobManager,128M~2G

        TaskManager,1)并行度:2的n次方  8

              2)内存:4G

              3)每个TaskManager的slot数:4

        平均一个job至少要10G内存

    11.8 平均每张表每天多大?

      日志: 每天每张平均10G
      业务: 每天每张平均 34m左右,大的表 5倍 =》 170M左右,
                    小的表 5M左右

    11.9 数据治理

      元数据管理:hive表的元数据

      数据质量监控:数据量的监控、重复数据监控、空值监控

        底层实现:SQL

            底层:shell脚本

      权限管理:ranger

    11.10 数据中台

    11.11 数据湖

  • 相关阅读:
    (转)移动端实现垂直居中的几种方法
    FloatingActionButton 完全解析
    android 开源编辑器
    如何使用PullToRefresh
    Android 使用代码主动去调用控件的点击事件(模拟人手去触摸控件)
    Gradle 下载
    android studio 中移除module和恢复module
    android studio 使用jar包,arr包和怎么使用githup开源项目中的aar包或module
    DrawerLayout 和 NavigationView 的使用
    android studio 集成微信登录
  • 原文地址:https://www.cnblogs.com/LzMingYueShanPao/p/15158844.html
Copyright © 2011-2022 走看看