大数据项目之电商数仓(业务数据仓库)

 

第1章 电商业务与数据结构简介

1.1 电商业务流程

1.2 电商表结构

电商业务流程

1.2.1 电商常识(SKU、SPU)

 SKU=Stock Keeping Unit(库存量单位)。即库存进出计量的基本单元,可以是以件,盒,托盘等为单位。SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法。现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。

 SPU(Standard Product Unit):标准化产品单元。是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。

首先通过检索搜索出来的商品列表中,每个商品都是一个SKU。每个SKU都有自己独立的库存数。也就是说每一个商品详情展示都是一个SKU。

比如,咱们购买一台iPhoneX手机,iPhoneX手机就是一个SPU,但是你购买的时候,不可能是以iPhoneX手机为单位买的,商家也不可能以iPhoneX为单位记录库存。必须要以什么颜色什么版本的iPhoneX为单位。比如,你购买的是一台银色、128G内存的、支持联通网络的iPhoneX ,商家也会以这个单位来记录库存数。那这个更细致的单位就叫库存单元(SKU)。

那spu又是干什么的呢?

如上图,一般的电商系统你点击进去以后,都能看到这个商品关联了其他好几个类似的商品,而且这些商品很多的信息都是共用的,比如商品图片,海报、销售属性等。

1.2.2 订单表(order_info)

标签

含义

id

订单编号

total_amount

订单金额

order_status

订单状态

user_id

用户id

payment_way

支付方式

out_trade_no

支付流水号

create_time

创建时间

operate_time

操作时间

1.2.3 订单详情表(order_detail)

标签

含义

id

订单编号

order_id

订单号

user_id

用户id

sku_id

商品id

sku_name

商品名称

order_price

下单价格

sku_num

商品数量

create_time

创建时间

1.2.4 商品表

标签

含义

id

skuId

spu_id

spuid

price

价格

sku_name

商品名称

sku_desc

商品描述

weight

重量

tm_id

品牌id

category3_id

品类id

create_time

创建时间

1.2.5 用户表

标签

含义

id

用户id

name

姓名

birthday

生日

gender

性别

email

邮箱

user_level

用户等级

create_time

创建时间

1.2.6 商品一级分类表

标签

含义

id

id

name

名称

1.2.7 商品二级分类表

标签

含义

id

id

name

名称

category1_id

一级品类id

1.2.8 商品三级分类表

标签

含义

id

id

name

名称

Category2_id

二级品类id

1.2.9 支付流水表

标签

含义

id

编号

out_trade_no

对外业务编号

order_id

订单编号

user_id

用户编号

alipay_trade_no

支付宝交易流水编号

total_amount

支付金额

subject

交易内容

payment_type

支付类型

payment_time

支付时间

第2章 数仓理论

2.1 表的分类

2.1.1 实体表

  • 定义

实体表,一般是指一个现实存在的业务对象,比如用户,商品,商家,销售员等等。

用户表:

用户id

姓名

生日

性别

邮箱

用户等级

创建时间

1

张三

2011-11-11

[email protected]

2

2018-11-11

2

李四

2011-11-11

[email protected]

3

2018-11-11

3

王五

2011-11-11

中性

[email protected]

1

2018-11-11

2.1.2 维度表

  • 定义

维度表,一般是指对应一些业务状态,代码的解释表。也可以称之为码表。

比如地区表,订单状态,支付方式,审批状态,商品分类等等。

订单状态表:

订单状态编号

订单状态名称

1

未支付

2

支付

3

发货中

4

已发货

5

已完成

商品分类表:

商品分类编号

分类名称

1

少儿

2

文艺

3

生活

4

科技

2.1.3 事务型事实表

  • 定义

事务型事实表,一般指随着业务发生不断产生的数据。特点是一旦发生不会再变化。

一般比如,交易流水,操作日志,出库入库记录等等。

交易流水表:

编号

对外业务编号

订单编号

用户编号

支付宝交易流水编号

支付金额

交易内容

支付类型

支付时间

1

7577697945

1

111

QEyF-63000323

223.00

海狗人参丸1

alipay

2019-02-10 00:50:02

2

0170099522

2

222

qdwV-25111279

589.00

海狗人参丸2

wechatpay

2019-02-10 00:50:02

3

1840931679

3

666

hSUS-65716585

485.00

海狗人参丸3

unionpay

2019-02-10 00:50:02

。。。

。。。

。。。

。。。

。。。

。。。

。。。

。。。

。。。

2.1.4 周期型事实表

  • 定义

周期型事实表,一般指随着业务发生不断产生的数据。

与事务型不同的是,数据会随着业务周期性的推进而变化。

 比如订单,其中订单状态会周期性变化。再比如,请假、贷款申请,随着批复状态在周期性变化。

订单表:

订单编号

订单金额

订单状态

用户id

支付方式

支付流水号

创建时间

操作时间

1

223.00

2

111

alipay

QEyF-63000323

2019-02-10 00:01:29

2019-02-10 00:01:29

2

589.00

2

222

wechatpay

qdwV-25111279

2019-02-10 00:05:02

2019-02-10 00:05:02

3

485.00

1

666

unionpay

hSUS-65716585

2019-02-10 00:50:02

2019-02-10 00:50:02

。。。

。。。

。。。

。。。

。。。

。。。

。。。

。。。

2.2 同步策略

数据同步策略的类型包括:全量表、增量表、新增及变化表、拉链表

全量表:存储完整的数据。

增量表:存储新增加的数据。

新增及变化表:存储新增加的数据和变化的数据。

拉链表:对新增及变化表做定期合并。

2.2.1 实体表同步策略

实体表:比如用户,商品,商家,销售员等

实体表数据量比较小:通常可以做每日全量,就是每天存一份完整数据。即每日全量。

2.2.2 维度表同步策略

维度表:比如订单状态,审批状态,商品分类

维度表数据量比较小:通常可以做每日全量,就是每天存一份完整数据。即每日全量。

说明:

1)针对可能会有变化的状态数据可以存储每日全量

2)没变化的客观世界的维度(比如性别,地区,民族,政治成分,鞋子尺码)可以就存一份固定值。

2.2.3 事务型事实表同步策略

事务型事实表:比如,交易流水,操作日志,出库入库记录等。

因为数据不会变化,而且数据量巨大,所以每天只同步新增数据即可,所以可以做成每日增量表,即每日创建一个分区存储。

2.2.4 周期型事实表同步策略

周期型事实表:比如,订单、请假、贷款申请等

这类表从数据量的角度,存每日全量的话,数据量太大,冗余也太大。如果用每日增量的话无法反应数据变化。

 每日新增及变化量可以用,包括了当日的新增和修改。一般来说这个表,足够计算大部分当日数据的。但是这种依然无法解决能够得到某一个历史时间点(时间切片)的切片数据。 

 所以要用利用每日新增和变化表,制作一张拉链表,以方便的取到某个时间切片的快照数据。所以我们需要得到每日新增及变化量。

拉链表:

name姓名

start新名字创建时间

end名字更改时间

张三

1990/1/1

2018/12/31

张三三

2019/1/1

9999-99-99

。。。

。。。

。。。

select * from user where start =<’2020-1-1’ and end>=’2020-1-1’

2.3 范式理论

2.3.1 范式概念

关系型数据库设计时,遵照一定的规范要求,目的在于降低数据的冗余性,目前业界范式有:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF)。

范式的标准定义是:符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度。通俗地讲,范式可以理解为一张数据表的表结构,所符合的某种设计标准的级别。

 使用范式的根本目的是:

  1)减少数据冗余,尽量让每个数据只出现一次。

  2)保证数据一致性

 缺点是获取数据时,需要通过join拼接出最后的数据。

2.3.2 函数依赖

2.3.3 三范式区分

第一范式
第二范式
第三范式

2.4 关系建模与维度建模

  • 关系模型

关系模型主要应用与OLTP系统中,为了保证数据的一致性以及避免冗余,所以大部分业务系统的表都是遵循第三范式的。

  • 维度模型

维度模型主要应用于OLAP系统中,因为关系模型虽然冗余少,但是在大规模数据,跨表分析统计查询过程中会造成多表关联,这会大大降低执行效率

所以把相关各种表整理成两种:事实表和维度表两种。所有维度表围绕着事实表进行解释。

2.5 雪花模型、星型模型和星座模型

在维度建模的基础上又分为三种模型:星型模型、雪花模型、星座模型。

第3章 数仓搭建

3.1 业务数据生成

3.1.1 建表语句

1)通过SQLyog创建数据库gmall

2)设置数据库编码

3)导入建表语句(1建表脚本)

选择->1建表脚本.sql

 
 
 CREATE TABLE `order_info` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `consignee` VARCHAR(100) DEFAULT NULL COMMENT '收货人',
  `consignee_tel` VARCHAR(20) DEFAULT NULL COMMENT '收件人电话',
  `total_amount` DECIMAL(10,2) DEFAULT NULL COMMENT '总金额',
  `order_status` VARCHAR(20) DEFAULT NULL COMMENT '订单状态',
  `user_id` BIGINT(20) DEFAULT NULL COMMENT '用户id',
  `payment_way` VARCHAR(20) DEFAULT NULL COMMENT '付款方式',
  `delivery_address` VARCHAR(1000) DEFAULT NULL COMMENT '送货地址',
  `order_comment` VARCHAR(200) DEFAULT NULL COMMENT '订单备注',
  `out_trade_no` VARCHAR(50) DEFAULT NULL COMMENT '订单交易编号(第三方支付用)',
  `trade_body` VARCHAR(200) DEFAULT NULL COMMENT '订单描述(第三方支付用)',
  `create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
  `operate_time` DATETIME DEFAULT NULL COMMENT '操作时间',
  `expire_time` DATETIME DEFAULT NULL COMMENT '失效时间',
  `tracking_no` VARCHAR(100) DEFAULT NULL COMMENT '物流单编号',
  `parent_order_id` BIGINT(20) DEFAULT NULL COMMENT '父订单编号',
  `img_url` VARCHAR(200) DEFAULT NULL COMMENT '图片路径',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='订单表 订单表';

 

 DROP TABLE IF EXISTS sku_info;

CREATE TABLE `sku_info` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '库存id(itemID)',
  `spu_id` BIGINT(20) DEFAULT NULL COMMENT '商品id',
  `price` DECIMAL(10,0) DEFAULT NULL COMMENT '价格',
  `sku_name` VARCHAR(200) DEFAULT NULL COMMENT 'sku名称',
  `sku_desc` VARCHAR(2000) DEFAULT NULL COMMENT '商品规格描述',
  `weight` DECIMAL(10,2) DEFAULT NULL COMMENT '重量',
  `tm_id` BIGINT(20) DEFAULT NULL COMMENT '品牌(冗余)', 
  `category3_id` BIGINT(20) DEFAULT NULL COMMENT '三级分类id(冗余)',
  `sku_default_img` VARCHAR(200) DEFAULT NULL COMMENT '默认显示图片(冗余)',
  `create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8 COMMENT='库存单元表';


CREATE TABLE `user_info` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `login_name` VARCHAR(200) DEFAULT NULL COMMENT '用户名称',
  `nick_name` VARCHAR(200) DEFAULT NULL COMMENT '用户昵称',
  `passwd` VARCHAR(200) DEFAULT NULL COMMENT '用户密码',
  `name` VARCHAR(200) DEFAULT NULL COMMENT '用户姓名',
  `phone_num` VARCHAR(200) DEFAULT NULL COMMENT '手机号',
  `email` VARCHAR(200) DEFAULT NULL COMMENT '邮箱',
  `head_img` VARCHAR(200) DEFAULT NULL COMMENT '头像',
  `user_level` VARCHAR(200) DEFAULT NULL COMMENT '用户级别',
  `birthday` DATE DEFAULT NULL COMMENT '用户生日',
  `gender` VARCHAR(1) DEFAULT NULL COMMENT '性别 M男,F女',
  `create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=9501 DEFAULT CHARSET=utf8 COMMENT='用户表';



 

CREATE TABLE `order_detail` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `order_id` BIGINT(20) DEFAULT NULL COMMENT '订单编号',
  `sku_id` BIGINT(20) DEFAULT NULL COMMENT 'sku_id',
  `sku_name` VARCHAR(200) DEFAULT NULL COMMENT 'sku名称(冗余)',
  `img_url` VARCHAR(200) DEFAULT NULL COMMENT '图片名称(冗余)',
  `order_price` DECIMAL(10,2) DEFAULT NULL COMMENT '购买价格(下单时sku价格)',
  `sku_num` VARCHAR(200) DEFAULT NULL COMMENT '购买个数',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=55750 DEFAULT CHARSET=utf8 COMMENT='订单明细表';




DROP TABLE  IF EXISTS `payment_info`;
CREATE   TABLE  `payment_info`
(
       `id`            BIGINT NOT NULL AUTO_INCREMENT COMMENT '编号',
       `out_trade_no`   VARCHAR(20) COMMENT '对外业务编号',
       `order_id`         VARCHAR(20)  COMMENT '订单编号',
       `user_id`          VARCHAR(20) COMMENT '用户编号',
       `alipay_trade_no`  VARCHAR(20)  COMMENT '支付宝交易流水编号',
       `total_amount`    DECIMAL(16,2) COMMENT '支付金额',
       `subject`          VARCHAR(20)  COMMENT '交易内容',
       `payment_type`          VARCHAR(20)  COMMENT '支付方式',
       `payment_time`    VARCHAR(20) COMMENT '支付时间',
        PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=55750 DEFAULT CHARSET=utf8 COMMENT='支付流水表';


 

CREATE TABLE  `base_category1`
(
       `id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',
       `name`            VARCHAR(10) NOT NULL COMMENT '分类名称'
);
ALTER TABLE `base_category1` COMMENT= '一级分类表';




CREATE TABLE  `base_category2`
(
       `id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',
       `name`            VARCHAR(200) NOT NULL COMMENT '二级分类名称',
       `category1_id`     BIGINT COMMENT '一级分类编号'
);
ALTER TABLE `base_category2` COMMENT= '二级分类表';



 CREATE TABLE  `base_category3`
(
       `id`              BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL COMMENT '编号',
       `name`            VARCHAR(200) NOT NULL COMMENT '三级分类名称',
       `category2_id`     BIGINT COMMENT '二级分类编号'
);
ALTER TABLE `base_category3` COMMENT= '三级分类表';
#####

4)重复步骤3的导入方式,依次导入:2商品分类数据插入脚本、3函数脚本、4存储过程脚本。

3.1.2 生成业务数据

1)生成业务数据函数说明

       init_data ( do_date_string VARCHAR(20) , order_incr_num INT, user_incr_num INT , sku_num INT , if_truncate BOOLEAN  ):

       参数一:do_date_string生成数据日期

       参数二:order_incr_num订单id个数

       参数三:user_incr_num用户id个数

       参数四:sku_num商品sku个数

       参数五:if_truncate是否参数数据

2)案例测试:

(1)需求:生成日期2019年2月10日数据、订单1000个、用户200个、商品sku300个、不删除数据。



DELIMITER $$


DROP PROCEDURE IF EXISTS `insert_sku`$$
##新增max_num个sku
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_sku`( create_time_string VARCHAR(200),max_num INT  )
BEGIN  
 DECLARE v_create_time DATETIME DEFAULT NULL;
 DECLARE i INT DEFAULT 0;
 SET autocommit = 0;    
 REPEAT  
 SET i = i + 1;  
 SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(1,3600*24) SECOND); 
 INSERT INTO sku_info (spu_id,price,sku_name,sku_desc,weight,tm_id,category3_id,sku_default_img,create_time  ) 
 VALUES (rand_num(1,1000) ,rand_num(10,5000) , rand_string(20), rand_string(30),CAST(rand_num(50,500) AS DECIMAL(10,2))/100.0  ,rand_num(1,100),  rand_num(1,5000),CONCAT('http://',rand_string(40)), v_create_time    ); 
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END$$

DELIMITER ;




DELIMITER $$

 

DROP PROCEDURE IF EXISTS `insert_user`$$
#随机产生max_num个用户
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_user`( create_time_string VARCHAR(200),max_num INT  )
BEGIN  
 DECLARE v_create_time DATETIME DEFAULT NULL;
 DECLARE i INT DEFAULT 0;
 DECLARE v_birthday DATE DEFAULT 0;
 DECLARE v_gender VARCHAR(1) DEFAULT NULL;
 SET autocommit = 0;    
 REPEAT  
   SET i  = i + 1;  
   SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(1,3600*24) SECOND); 
   SET v_birthday=DATE_ADD(DATE_FORMAT('1950-01-01','%Y-%m-%d') ,INTERVAL rand_num(1,365*50) DAY); 
   SET v_gender=IF(rand_num(0,1)=0,'M','F');
 INSERT INTO user_info (login_name,nick_name,passwd,NAME,phone_num,email,head_img,user_level,birthday,gender,create_time  ) 
 VALUES (rand_string(20) ,rand_string(20) , CONCAT('pwd',rand_string(20)), rand_string(30), CONCAT('13',rand_nums(0,9,9,''))    ,CONCAT(rand_string(8),'@',rand_string(3),'.com') ,  CONCAT('http://',rand_string(40)), rand_num(1,5),v_birthday,v_gender,v_create_time    ); 
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END$$

DELIMITER ;



DELIMITER $$

  

DROP PROCEDURE IF EXISTS `insert_order`$$

##生成订单 
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_order`( create_time_string VARCHAR(200),max_num INT,user_num INT ,sku_num INT  )
BEGIN  
 DECLARE v_create_time DATETIME DEFAULT NULL;
  DECLARE i INT DEFAULT 0;
 DECLARE v_order_status INT DEFAULT 0;  
  DECLARE v_operate_time DATETIME DEFAULT NULL; 
    DECLARE v_order_id INT DEFAULT NULL; 
     DECLARE v_order_detail_num INT DEFAULT NULL; 
      DECLARE j INT DEFAULT 0;
 SET autocommit = 0;    
 REPEAT  
 SET i = i + 1;  
 SET v_create_time=DATE_ADD(DATE_FORMAT(create_time_string,'%Y-%m-%d') ,INTERVAL rand_num(30,3600*23) SECOND);
 SET v_order_status=rand_num(1,2); ## 
  IF v_order_status>1 THEN 
     SET v_operate_time= DATE_ADD(v_create_time ,INTERVAL rand_num(30,3600) SECOND);
   ELSE 
     SET v_operate_time=NULL  ;
   END IF ;
 INSERT INTO order_info (consignee, consignee_tel,total_amount ,order_status ,user_id,payment_way,delivery_address,order_comment,out_trade_no,trade_body,create_time,operate_time,expire_time, tracking_no,parent_order_id ,img_url) 
 VALUES (rand_string(6) , CONCAT('13',rand_nums(0,9,9,'')),CAST(rand_num(50,1000) AS DECIMAL(10,2)) ,v_order_status ,rand_num(1,user_num), rand_num(1,2),rand_string(20),rand_string(20),rand_nums(0,9,10,''),'',v_create_time, v_operate_time,NULL,NULL,NULL,NULL ); 
  SELECT  LAST_INSERT_ID() INTO v_order_id ;
     SET v_order_detail_num=rand_num(1,5); 
    WHILE j<v_order_detail_num DO
       SET j=j+1;
    INSERT INTO  order_detail  (order_id , sku_id,sku_name ,img_url ,order_price,sku_num ) 
    VALUES (v_order_id , rand_num(1,sku_num),rand_string(10),CONCAT('http://',rand_string(40)) ,CAST(rand_num(20,5000) AS DECIMAL(10,2)), rand_num(1,5)  ); 
    END WHILE;
    SET j=0;
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END$$

DELIMITER ;


DELIMITER $$
 
DROP PROCEDURE IF EXISTS `update_order`$$
## 随机让订单状态小于5的订单 发生状态改变
CREATE DEFINER=`root`@`localhost` PROCEDURE `update_order`(operate_time_string VARCHAR(20))
BEGIN 
  DECLARE v_operate_time DATETIME DEFAULT NULL; 
 SET v_operate_time=DATE_FORMAT(operate_time_string,'%Y-%m-%d');
UPDATE order_info o SET   o.`order_status`=o.`order_status`+rand_num_seed(0,1,o.id) ,operate_time= IF( rand_num_seed(0,1,o.id) >0 , DATE_ADD(v_operate_time ,INTERVAL rand_num(30,20*3600) SECOND),operate_time)
WHERE o.`order_status`<5;
END$$

DELIMITER ;


DELIMITER$$
 DROP PROCEDURE IF EXISTS `insert_payment`$$
 ## 只要订单状态更新为2 ,给当天插入一条支付信息 
 CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_payment`( do_date_str VARCHAR(200)   )
BEGIN      
 INSERT INTO payment_info (out_trade_no,order_id,user_id,alipay_trade_no,total_amount,`subject`,payment_type,payment_time  ) 
  SELECT o.out_trade_no,o.id,user_id,
   CONCAT( rand_string(4),'-',rand_nums(0,9,8,'')) alipay_trade_no,
   o.total_amount,
   rand_string(8) `subject`,
  ( CASE rand_num(1,3) WHEN 1 THEN  'wechatpay' WHEN 2 THEN 'alipay' WHEN 3 THEN 'unionpay' END) payment_type , 
  IF(o.operate_time IS NULL,o.create_time,o.operate_time) payment_time
  FROM order_info  o 
  WHERE (DATE_FORMAT(o.create_time,'%Y-%m-%d')= do_date_str OR DATE_FORMAT(o.operate_time,'%Y-%m-%d')= do_date_str ) AND o.order_status='2';
  COMMIT;
 END$$

DELIMITER ;


DELIMITER $$
 
DROP PROCEDURE IF EXISTS `init_data`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `init_data`( do_date_string VARCHAR(20) ,order_incr_num INT,user_incr_num INT ,sku_num INT ,if_truncate BOOLEAN  )
BEGIN  
     DECLARE user_count INT DEFAULT 0; 
     DECLARE sku_count INT DEFAULT 0; 
     DECLARE do_date VARCHAR(20) DEFAULT do_date_string;
     IF if_truncate  THEN 
        TRUNCATE TABLE order_info ;
        TRUNCATE TABLE order_detail ;
        TRUNCATE TABLE sku_info ;
        TRUNCATE TABLE user_info ;
     END IF ;     
     CALL insert_sku(do_date,sku_num );
     SELECT COUNT(*) INTO sku_count FROM  sku_info;
     CALL insert_user(do_date,user_incr_num );
     SELECT COUNT(*) INTO user_count FROM  user_info;
     CALL update_order(do_date);
     CALL insert_order(do_date,order_incr_num,user_count,sku_count);
     CALL insert_payment(do_date);
 END$$

DELIMITER ;


CALL init_data('2019-02-10',1000,200,300,FALSE);

(2)查询生成数据结果

SELECT * from base_category1;
SELECT * from base_category2;
SELECT * FROM base_category3;

SELECT * FROM order_info;
SELECT * from order_detail;

SELECT * from sku_info;
SELECT * from user_info;

SELECT * FROM payment_info;

(3)生成2019年2月11日数据

CALL init_data('2019-02-11',1000,200,300,FALSE);

3.2 业务数据导入数仓

Flume消费

3.2.1 Sqoop安装

=================================== Begin ===========================

第3章 Sqoop安装 

安装Sqoop的前提是已经具备Java和Hadoop的环境。

3.1 下载并解压

1) 下载地址:http://mirrors.hust.edu.cn/apache/sqoop/1.4.6/

2) 上传安装包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz到虚拟机中

3) 解压sqoop安装包到指定目录,如:

$ tar -zxf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/

3.2 修改配置文件

Sqoop的配置文件与大多数大数据框架类似,在sqoop根目录下的conf目录中。

1) 重命名配置文件

$ mv sqoop-env-template.sh sqoop-env.sh

2) 修改配置文件

sqoop-env.sh

export HADOOP_COMMON_HOME=/opt/module/hadoop-2.7.2
export HADOOP_MAPRED_HOME=/opt/module/hadoop-2.7.2
export HIVE_HOME=/opt/module/hive
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10
export ZOOCFGDIR=/opt/module/zookeeper-3.4.10
export HBASE_HOME=/opt/module/hbase

3.3 拷贝JDBC驱动

拷贝jdbc驱动到sqoop的lib目录下,如:

$ cp mysql-connector-java-5.1.27-bin.jar /opt/module/sqoop-1.4.6.bin__hadoop-2.0.4-alpha/lib/

3.4 验证Sqoop

我们可以通过某一个command来验证sqoop配置是否正确:

$ bin/sqoop help

出现一些Warning警告(警告信息已省略),并伴随着帮助命令的输出:

Available commands:
  codegen            Generate code to interact with database records
  create-hive-table     Import a table definition into Hive
  eval               Evaluate a SQL statement and display the results
  export             Export an HDFS directory to a database table
  help               List available commands
  import             Import a table from a database to HDFS
  import-all-tables     Import tables from a database to HDFS
  import-mainframe    Import datasets from a mainframe server to HDFS
  job                Work with saved jobs
  list-databases        List available databases on a server
  list-tables           List available tables in a database
  merge              Merge results of incremental imports
  metastore           Run a standalone Sqoop metastore
  version            Display version information

3.5 测试Sqoop是否能够成功连接数据库

$ bin/sqoop list-databases --connect jdbc:mysql://hadoop102:3306/ --username root --password 000000

出现如下输出:

information_schema
metastore
mysql
oozie
performance_schema

第4章 Sqoop的简单使用案例

4.1 导入数据

在Sqoop中,“导入”概念指:从非大数据集群(RDBMS)向大数据集群(HDFS,HIVE,HBASE)中传输数据,叫做:导入,即使用import关键字。

4.1.1 RDBMS到HDFS

1) 确定Mysql服务开启正常

2) 在Mysql中新建一张表并插入一些数据

$ mysql -uroot -p000000
mysql> create database company;
mysql> create table company.staff(id int(4) primary key not null auto_increment, name varchar(255), sex varchar(255));
mysql> insert into company.staff(name, sex) values('Thomas', 'Male');
mysql> insert into company.staff(name, sex) values('Catalina', 'FeMale');

3) 导入数据

       (1)全部导入

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"

       (2)查询导入

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select name,sex from staff where id <=1 and $CONDITIONS;'

提示:must contain '$CONDITIONS' in WHERE clause.

如果query后使用的是双引号,则$CONDITIONS前必须加转移符,防止shell识别为自己的变量。

       (3)导入指定列

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,sex \
--table staff

提示:columns中如果涉及到多列,用逗号分隔,分隔时不要添加空格

       (4)使用sqoop关键字筛选查询导入数据

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table staff \
--where "id=1"

4.1.2 RDBMS到Hive

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table staff_hive

提示:该过程分为两步,第一步将数据导入到HDFS,第二步将导入到HDFS的数据迁移到Hive仓库,第一步默认的临时目录是/user/newbies/表名

4.1.3 RDBMS到Hbase

$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table company \
--columns "id,name,sex" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_company" \
--num-mappers 1 \
--split-by id

提示:sqoop1.4.6只支持HBase1.0.1之前的版本的自动创建HBase表的功能

解决方案:手动创建HBase表

hbase> create 'hbase_company,'info'

(5) 在HBase中scan这张表得到如下内容

hbase> scan ‘hbase_company’

4.2、导出数据

在Sqoop中,“导出”概念指:从大数据集群(HDFS,HIVE,HBASE)向非大数据集群(RDBMS)中传输数据,叫做:导出,即使用export关键字。

4.2.1 HIVE/HDFS到RDBMS

$ bin/sqoop export \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--num-mappers 1 \
--export-dir /user/hive/warehouse/staff_hive \
--input-fields-terminated-by "\t"

提示:Mysql中如果表不存在,不会自动创建

4.3 脚本打包

使用opt格式的文件打包sqoop命令,然后执行

1) 创建一个.opt文件

$ mkdir opt
$ touch opt/job_HDFS2RDBMS.opt

2) 编写sqoop脚本

$ vi opt/job_HDFS2RDBMS.opt

export
--connect
jdbc:mysql://hadoop102:3306/company
--username
root
--password
000000
--table
staff
--num-mappers
1
--export-dir
/user/hive/warehouse/staff_hive
--input-fields-terminated-by
"\t"

3) 执行该脚本

$ bin/sqoop --options-file opt/job_HDFS2RDBMS.opt

=========================== End ==============================================

3.2.2 Sqoop导入命令

/opt/module/sqoop/bin/sqoop import \
--connect  \
--username  \
--password  \
--target-dir  \
--delete-target-dir \
--num-mappers   \
--fields-terminated-by   \
--query   "$2"' and  $CONDITIONS;'

3.2.3 分析表

分析表的同步策略

3.2.4 Sqoop定时导入脚本

1)在/home/newbies/bin目录下创建脚本sqoop_import.sh

[newbies@hadoop102 bin]$ vim sqoop_import.sh

       在脚本中填写如下内容

#!/bin/bash

db_date=$2
echo $db_date
db_name=gmall

import_data() {
/opt/module/sqoop/bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/$db_name \
--username root \
--password 000000 \
--target-dir  /origin_data/$db_name/db/$1/$db_date \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query   "$2"' and  $CONDITIONS;'
}

import_sku_info(){
  import_data  "sku_info"  "select 
id, spu_id, price, sku_name, sku_desc, weight, tm_id,
category3_id, create_time 
  from sku_info  where 1=1"
}

import_user_info(){
  import_data "user_info" "select 
id, name, birthday, gender, email, user_level, 
create_time 
from user_info where 1=1"
}

import_base_category1(){
  import_data "base_category1" "select 
id, name from base_category1 where 1=1"
}

import_base_category2(){
  import_data "base_category2" "select 
id, name, category1_id from base_category2 where 1=1"
}

import_base_category3(){
  import_data "base_category3" "select id, name, category2_id from base_category3 where 1=1"
}

import_order_detail(){
  import_data   "order_detail"   "select 
    od.id, 
    order_id, 
    user_id, 
    sku_id, 
    sku_name, 
    order_price, 
    sku_num, 
    o.create_time  
  from order_info o , order_detail od 
  where o.id=od.order_id 
  and DATE_FORMAT(create_time,'%Y-%m-%d')='$db_date'"
}

import_payment_info(){
  import_data  "payment_info"   "select 
    id,  
    out_trade_no, 
    order_id, 
    user_id, 
    alipay_trade_no, 
    total_amount,  
    subject , 
    payment_type, 
    payment_time 
  from payment_info 
  where DATE_FORMAT(payment_time,'%Y-%m-%d')='$db_date'"
}

import_order_info(){
  import_data   "order_info"   "select 
    id, 
    total_amount, 
    order_status, 
    user_id, 
    payment_way, 
    out_trade_no, 
    create_time, 
    operate_time  
  from order_info 
  where  (DATE_FORMAT(create_time,'%Y-%m-%d')='$db_date' or DATE_FORMAT(operate_time,'%Y-%m-%d')='$db_date')"
}

case $1 in
  "base_category1")
     import_base_category1
;;
  "base_category2")
     import_base_category2
;;
  "base_category3")
     import_base_category3
;;
  "order_info")
     import_order_info
;;
  "order_detail")
     import_order_detail
;;
  "sku_info")
     import_sku_info
;;
  "user_info")
     import_user_info
;;
  "payment_info")
     import_payment_info
;;
   "all")
   import_base_category1
   import_base_category2
   import_base_category3
   import_order_info
   import_order_detail
   import_sku_info
   import_user_info
   import_payment_info
;;
esac

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 sqoop_import.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ sqoop_import.sh all 2019-02-10
[newbies@hadoop102 bin]$ sqoop_import.sh all 2019-02-11

3.3 ODS层

完全仿照业务数据库中的表字段,一模一样的创建ODS层对应表。

3.3.1 创建订单表

hive (gmall)>
drop table if exists ods_order_info;
create table ods_order_info ( 
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额', 
    `order_status` string COMMENT '订单状态', 
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',  
    `out_trade_no` string COMMENT '支付流水号',  
    `create_time` string COMMENT '创建时间',  
    `operate_time` string COMMENT '操作时间' 
) COMMENT '订单表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_order_info/'
tblproperties ("parquet.compression"="snappy")
;

3.3.2 创建订单详情表

hive (gmall)>
drop table if exists ods_order_detail;
create table ods_order_detail( 
    `id` string COMMENT '订单编号',
    `order_id` string  COMMENT '订单号', 
    `user_id` string COMMENT '用户id' ,
    `sku_id` string COMMENT '商品id',  
    `sku_name` string COMMENT '商品名称',  
    `order_price` string COMMENT '下单价格',  
    `sku_num` string COMMENT '商品数量',  
    `create_time` string COMMENT '创建时间'
) COMMENT '订单明细表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_order_detail/'
tblproperties ("parquet.compression"="snappy")
;

 3.3.3 创建商品表

hive (gmall)>
drop table if exists ods_sku_info;
create table ods_sku_info( 
    `id` string COMMENT 'skuId',
    `spu_id` string   COMMENT 'spuid', 
    `price` decimal(10,2) COMMENT '价格' ,
    `sku_name` string COMMENT '商品名称',  
    `sku_desc` string COMMENT '商品描述',  
    `weight` string COMMENT '重量',  
    `tm_id` string COMMENT '品牌id',  
    `category3_id` string COMMENT '品类id',  
    `create_time` string COMMENT '创建时间'
) COMMENT '商品表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_sku_info/'
tblproperties ("parquet.compression"="snappy")
;

3.3.4 创建用户表

hive (gmall)>
drop table if exists ods_user_info;
create table ods_user_info( 
    `id` string COMMENT '用户id',
    `name`  string COMMENT '姓名', 
    `birthday` string COMMENT '生日' ,
    `gender` string COMMENT '性别',  
    `email` string COMMENT '邮箱',  
    `user_level` string COMMENT '用户等级',  
    `create_time` string COMMENT '创建时间'
) COMMENT '用户信息'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_user_info/'
tblproperties ("parquet.compression"="snappy")
;

3.3.5 创建商品一级分类表

hive (gmall)>
drop table if exists ods_base_category1;
create table ods_base_category1( 
    `id` string COMMENT 'id',
    `name`  string COMMENT '名称'
) COMMENT '商品一级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_base_category1/'
tblproperties ("parquet.compression"="snappy")
;

3.3.6 创建商品二级分类表

hive (gmall)>
drop table if exists ods_base_category2;
create external table ods_base_category2( 
    `id` string COMMENT ' id',
    `name`  string COMMENT '名称',
    category1_id string COMMENT '一级品类id'
) COMMENT '商品二级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_base_category2/'
tblproperties ("parquet.compression"="snappy")
;

3.3.7 创建商品三级分类表

hive (gmall)>
drop table if exists ods_base_category3;
create table ods_base_category3( 
    `id` string COMMENT ' id',
    `name`  string COMMENT '名称',
    category2_id string COMMENT '二级品类id'
) COMMENT '商品三级分类'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_base_category3/'
tblproperties ("parquet.compression"="snappy")
;

3.3.8 创建支付流水表

hive (gmall)>
drop table if exists `ods_payment_info`;
create table  `ods_payment_info`(
    `id`   bigint COMMENT '编号',
    `out_trade_no`    string COMMENT '对外业务编号',
    `order_id`        string COMMENT '订单编号',
    `user_id`         string COMMENT '用户编号',
    `alipay_trade_no` string COMMENT '支付宝交易流水编号',
    `total_amount`    decimal(16,2) COMMENT '支付金额',
    `subject`         string COMMENT '交易内容',
    `payment_type` string COMMENT '支付类型',
    `payment_time`   string COMMENT '支付时间'
   )  COMMENT '支付流水表'
PARTITIONED BY ( `dt` string)
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ods/ods_payment_info/'
tblproperties ("parquet.compression"="snappy")
;

3.3.9 ODS层数据导入脚本

1)在/home/newbies/bin目录下创建脚本ods_db.sh

[newbies@hadoop102 bin]$ vim ods_db.sh

       在脚本中填写如下内容

#!/bin/bash

   do_date=$1
   APP=gmall
   hive=/opt/module/hive/bin/hive

sql=" 
load data inpath '/origin_data/$APP/db/order_info/$do_date'  OVERWRITE into table $APP"".ods_order_info partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/order_detail/$do_date'  OVERWRITE into table $APP"".ods_order_detail partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/sku_info/$do_date'  OVERWRITE into table $APP"".ods_sku_info partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/user_info/$do_date' OVERWRITE into table $APP"".ods_user_info partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/payment_info/$do_date' OVERWRITE into table $APP"".ods_payment_info partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/base_category1/$do_date' OVERWRITE into table $APP"".ods_base_category1 partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/base_category2/$do_date' OVERWRITE into table $APP"".ods_base_category2 partition(dt='$do_date');

load data inpath '/origin_data/$APP/db/base_category3/$do_date' OVERWRITE into table $APP"".ods_base_category3 partition(dt='$do_date'); 
"
$hive -e "$sql"

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 ods_db.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ ods_db.sh 2019-02-10
[newbies@hadoop102 bin]$ ods_db.sh 2019-02-11

4)查询导入数据

hive (gmall)> 
select * from ods_order_info where dt='2019-02-10' limit 1;
select * from ods_order_info where dt='2019-02-11' limit 1;

3.4 DWD层

积压ODS层对数据进行判空过滤。对商品分类表进行维度退化(降维)。

3.4.1 创建订单表

hive (gmall)>
drop table if exists dwd_order_info;
create external table dwd_order_info ( 
    `id` string COMMENT '',
    `total_amount` decimal(10,2) COMMENT '', 
    `order_status` string COMMENT ' 1 2  3  4  5', 
    `user_id` string COMMENT 'id' ,
    `payment_way` string COMMENT '',  
    `out_trade_no` string COMMENT '',  
    `create_time` string COMMENT '',  
    `operate_time` string COMMENT '' 
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_info/'
tblproperties ("parquet.compression"="snappy")
;

3.4.2 创建订单详情表

hive (gmall)>
drop table if exists dwd_order_detail;
create external table dwd_order_detail( 
    `id` string COMMENT '',
    `order_id` decimal(10,2) COMMENT '', 
    `user_id` string COMMENT 'id' ,
    `sku_id` string COMMENT 'id',  
    `sku_name` string COMMENT '',  
    `order_price` string COMMENT '',  
    `sku_num` string COMMENT '', 
    `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_detail/'
tblproperties ("parquet.compression"="snappy")
;

3.4.3 创建用户表

hive (gmall)>
drop table if exists dwd_user_info;
create external table dwd_user_info( 
    `id` string COMMENT 'id',
    `name`  string COMMENT '', 
    `birthday` string COMMENT '' ,
    `gender` string COMMENT '',  
    `email` string COMMENT '',  
    `user_level` string COMMENT '',  
    `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_user_info/'
tblproperties ("parquet.compression"="snappy")
;

3.4.4 创建支付流水表

hive (gmall)>
drop table if exists `dwd_payment_info`;
create external  table  `dwd_payment_info`(
    `id`   bigint COMMENT '',
    `out_trade_no`   string COMMENT '',
    `order_id`        string COMMENT '',
    `user_id`         string COMMENT '',
    `alipay_trade_no` string COMMENT '',
    `total_amount`    decimal(16,2) COMMENT '',
    `subject`         string COMMENT '',
    `payment_type` string COMMENT '',
    `payment_time`   string COMMENT ''
   )  COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_payment_info/'
tblproperties ("parquet.compression"="snappy")
;

3.4.5 创建商品表(增加分类)

创建商品表
hive (gmall)>
drop table if exists dwd_sku_info;
create external table dwd_sku_info( 
    `id` string COMMENT 'skuId',
    `spu_id` string COMMENT 'spuid', 
    `price` decimal(10,2) COMMENT '' ,
    `sku_name` string COMMENT '',  
    `sku_desc` string COMMENT '',  
    `weight` string COMMENT '',  
    `tm_id` string COMMENT 'id',  
    `category3_id` string COMMENT '1id',  
    `category2_id` string COMMENT '2id',  
    `category1_id` string COMMENT '3id',  
    `category3_name` string COMMENT '3',  
    `category2_name` string COMMENT '2',  
    `category1_name` string COMMENT '1',  
    `create_time` string COMMENT ''
) COMMENT ''
PARTITIONED BY ( `dt` string)
stored as  parquet
location '/warehouse/gmall/dwd/dwd_sku_info/'
tblproperties ("parquet.compression"="snappy")
;

3.4.6 DWD层数据导入脚本

1)在/home/newbies/bin目录下创建脚本dwd_db.sh

[newbies@hadoop102 bin]$ vim dwd_db.sh

在脚本中填写如下内容

#!/bin/bash

# 定义变量方便修改
APP=gmall
hive=/opt/module/hive/bin/hive

# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;then
	log_date=$1
else 
	log_date=`date  -d "-1 day"  +%F`  
fi 

sql="

set hive.exec.dynamic.partition.mode=nonstrict;

insert  overwrite table   "$APP".dwd_order_info partition(dt)
select  * from "$APP".ods_order_info 
where dt='$log_date'  and id is not null;
 
insert  overwrite table   "$APP".dwd_order_detail partition(dt)
select  * from "$APP".ods_order_detail 
where dt='$log_date'   and id is not null;

insert  overwrite table   "$APP".dwd_user_info partition(dt)
select  * from "$APP".ods_user_info
where dt='$log_date'   and id is not null;
 
insert  overwrite table   "$APP".dwd_payment_info partition(dt)
select  * from "$APP".ods_payment_info
where dt='$log_date'  and id is not null;

insert  overwrite table   "$APP".dwd_sku_info partition(dt)
select  
    sku.id,
    sku.spu_id, 
    sku.price,
    sku.sku_name,  
    sku.sku_desc,  
    sku.weight,  
    sku.tm_id,  
    sku.category3_id,  
    c2.id category2_id ,  
    c1.id category1_id,  
    c3.name category3_name,  
    c2.name category2_name,  
    c1.name category1_name,  
    sku.create_time,
    sku.dt
from
    "$APP".ods_sku_info sku 
join "$APP".ods_base_category3 c3 on sku.category3_id=c3.id 
    join "$APP".ods_base_category2 c2 on c3.category2_id=c2.id 
    join "$APP".ods_base_category1 c1 on c2.category1_id=c1.id 
where sku.dt='$log_date'  and c2.dt='$log_date'  
and  c3.dt='$log_date' and  c1.dt='$log_date' 
and sku.id is not null;

"
$hive -e "$sql"

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 dwd_db.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ dwd_db.sh 2019-02-10
[newbies@hadoop102 bin]$ dwd_db.sh 2019-02-11

4)查看导入数据

hive (gmall)>
select * from dwd_sku_info where dt='2019-02-10' limit 2;
select * from dwd_sku_info where dt='2019-02-11' limit 2;

3.4.3 小结

思考:

1)维度退化要付出什么代价?或者说会造成什么样的需求处理不了?

      如果被退化的维度,还有其他业务表使用,退化后处理起来就麻烦些。

2)想想在实际业务中还有那些维度表可以退化

3.5 DWS层之用户行为宽表

1)为什么要建宽表

需求目标,把每个用户单日的行为聚合起来组成一张多列宽表,以便之后关联用户维度信息后进行,不同角度的统计分析。

用户行为宽表

3.5.1 创建用户行为宽表

hive (gmall)>
drop table if exists dws_user_action;
create  external table dws_user_action 
(   
    user_id         string      comment '用户 id',
    order_count     bigint      comment '下单次数 ',
    order_amount    decimal(16,2)  comment '下单金额 ',
    payment_count   bigint      comment '支付次数',
    payment_amount  decimal(16,2) comment '支付金额 ',
    comment_count   bigint      comment '评论次数' 
) COMMENT '每日用户行为宽表'
PARTITIONED BY ( `dt` string)
stored as  parquet 
location '/warehouse/gmall/dws/dws_user_action/'
tblproperties ("parquet.compression"="snappy");

3.5.2 向用户行为宽表导入数据

1)导入数据

hive (gmall)>
with  
tmp_order as
(
    select 
        user_id, 
        sum(oc.total_amount) order_amount, 
        count(*)  order_count
    from dwd_order_info  oc
    where date_format(oc.create_time,'yyyy-MM-dd')='2019-02-10'
    group by user_id
)  ,
tmp_payment as
(
    select 
        user_id, 
        sum(pi.total_amount) payment_amount, 
        count(*) payment_count 
    from dwd_payment_info pi 
    where date_format(pi.payment_time,'yyyy-MM-dd')='2019-02-10'
    group by user_id
),
tmp_comment as
(  
    select  
        user_id, 
        count(*) comment_count
    from dwd_comment_log c
    where date_format(c.dt,'yyyy-MM-dd')='2019-02-10'
    group by user_id 
)

insert overwrite table dws_user_action partition(dt='2019-02-10')
select 
    user_actions.user_id, 
    sum(user_actions.order_count), 
    sum(user_actions.order_amount),
    sum(user_actions.payment_count), 
    sum(user_actions.payment_amount),
    sum(user_actions.comment_count) 
from 
(
    select 
        user_id, 
        order_count,
        order_amount ,
        0 payment_count , 
        0 payment_amount, 
        0 comment_count 
    from tmp_order 

    union all
    select 
        user_id, 
        0,
        0, 
        payment_count, 
        payment_amount,
        0  
    from tmp_payment

    union all
    select 
        user_id, 
        0,
        0,
        0,
        0,
        comment_count 
    from tmp_comment
 ) user_actions
group by user_id;

2)查询导入结果

hive (gmall)> select * from dws_user_action ;

3.5.3 DWS层用户行为数据宽边导入脚本

1)在/home/newbies/bin目录下创建脚本dws_db_wide.sh

[newbies@hadoop102 bin]$ vim dws_db_wide.sh

       在脚本中填写如下内容

#!/bin/bash

# 定义变量方便修改
APP=gmall
hive=/opt/module/hive/bin/hive

# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;then
	log_date=$1
else 
	log_date=`date  -d "-1 day"  +%F`  
fi 

sql="

with  
tmp_order as
(
    select 
      user_id, 
      sum(oc.total_amount) order_amount, 
      count(*)  order_count
    from "$APP".dwd_order_info  oc
    where date_format(oc.create_time,'yyyy-MM-dd')='$log_date'
    group by user_id
)  ,
tmp_payment as
(
    select 
      user_id, 
      sum(pi.total_amount) payment_amount, 
      count(*) payment_count 
    from "$APP".dwd_payment_info pi 
    where date_format(pi.payment_time,'yyyy-MM-dd')='$log_date'
    group by user_id
),
tmp_comment as
(  
    select  
      user_id, 
      count(*) comment_count
    from "$APP".dwd_comment_log c
    where date_format(c.dt,'yyyy-MM-dd')='$log_date'
    group by user_id 
)

insert  overwrite table "$APP".dws_user_action partition(dt='$log_date')
select 
    user_actions.user_id, 
    sum(user_actions.order_count), 
    sum(user_actions.order_amount),
    sum(user_actions.payment_count), 
    sum(user_actions.payment_amount),
    sum(user_actions.comment_count) 
from 
(
    select 
      user_id, 
      order_count,
      order_amount ,
      0 payment_count , 
      0 payment_amount, 
      0 comment_count 
    from tmp_order 

    union all
    select 
      user_id, 
      0,
      0, 
      payment_count, 
      payment_amount,
      0  
    from tmp_payment

    union all
    select 
      user_id, 
      0,
      0,
      0,
      0,
      comment_count 
    from tmp_comment
 ) user_actions
group by user_id;

"

$hive -e "$sql"

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 dws_db_wide.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ dws_db_wide.sh 2019-02-11

4)查看导入数据

hive (gmall)> 
select * from dws_user_action where dt='2019-02-11' limit 2;

 第4章 需求四:GMV成交总额

4.1 ADS层

4.1.1 什么是GMV

4.1.2 建表语句

hive (gmall)>
drop table if exists ads_gmv_sum_day;
create table ads_gmv_sum_day( 
    `dt` string COMMENT '统计日期',
    `gmv_count`  bigint COMMENT '当日gmv订单个数',
    `gmv_amount`  decimal(16,2) COMMENT '当日gmv订单总金额',
    `gmv_payment`  decimal(16,2) COMMENT '当日支付金额' 
) COMMENT '每日活跃用户数量'
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ads/ads_gmv_sum_day/'
;
GMV分析

4.1.3 数据导入

1)数据导入

hive (gmall)>
insert into table ads_gmv_sum_day 
select 
'2019-02-10' dt ,
    sum(order_count)  gmv_count ,
    sum(order_amount) gmv_amount ,
    sum(payment_amount) payment_amount 
from dws_user_action 
where dt ='2019-02-10'
group by dt
;

2)查询导入数据

hive (gmall)> select * from ads_gmv_sum_day;

 第5章 需求五:转化率

5.1 什么是转化率

5.2 ADS层之新增用户占日活跃用户比率

新增用户占日活跃用户比率

5.2.1 建表语句

hive (gmall)>
drop table if exists ads_user_convert_day;
create   table ads_user_convert_day( 
    `dt` string COMMENT '统计日期',
    `uv_m_count`  bigint COMMENT '当日活跃设备',
    `new_m_count`  bigint COMMENT '当日新增设备',
    `new_m_ratio`   decimal(10,2) COMMENT '当日新增占日活的比率'
) COMMENT '每日活跃用户数量'
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ads/ads_user_convert_day/'
;

5.2.2 数据导入

1)数据导入

hive (gmall)>
insert into table ads_user_convert_day 
select 
    '2019-02-10',
    sum( uc.dc) sum_dc,
    sum( uc.nmc) sum_nmc,
    cast(sum( uc.nmc)/sum( uc.dc)*100 as decimal(10,2))  new_m_ratio
from 
(
    select 
        day_count dc,
        0 nmc
    from ads_uv_count
where  dt='2019-02-10' 

    union all
    select  
        0 dc,
        new_mid_count nmc
    from ads_new_mid_count  
    where create_date='2019-02-10' 
)uc;

2)查看导入数据

hive (gmall)>
select * from ads_user_convert_day;

5.3 ADS层之用户行为漏斗分析

用户行为漏斗分析

5.3.1 建表语句

hive (gmall)>
drop table if exists ads_user_action_convert_day;
create   table ads_user_action_convert_day( 
    `dt` string COMMENT '统计日期',
    `total_visitor_m_count`  bigint COMMENT '总访问人数',
    `order_u_count` bigint     COMMENT '下单人数', 
    `visitor2order_convert_ratio`  decimal(10,2) COMMENT '访问到下单转化率', 
    `payment_u_count` bigint     COMMENT '支付人数',
    `order2payment_convert_ratio` decimal(10,2) COMMENT '下单到支付的转化率' 
 ) COMMENT '每日用户行为转化率统计'
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ads/ads_user_convert_day/'
;

5.3.2 数据导入

1)数据导入

hive (gmall)>
insert into table ads_user_action_convert_day
select 
    '2019-02-10',
    uv.day_count,
    ua.order_count,
    cast(ua.order_count/uv.day_count*100 as  decimal(10,2)) visitor2order_convert_ratio, 
    ua.payment_count,
    cast(ua.payment_count/ua.order_count*100 as  decimal(10,2)) order2payment_convert_ratio
from  
(
    select 
        sum(if(order_count>0,1,0)) order_count,
        sum(if(payment_count>0,1,0)) payment_count
    from dws_user_action  
    where  dt='2019-02-10' 
)ua, ads_uv_count  uv 
where  uv.dt='2019-02-10' 
;

2)查询导入数据

hive (gmall)> select * from ads_user_action_convert_day;

第6章 需求六:品牌复购率

需求:以月为单位统计,购买2次以上商品的用户

6.1 复购率计算分析

6.2 DWS层

6.2.1 用户购买商品明细表(宽表)

hive (gmall)>
drop table if exists  dws_sale_detail_daycount;
create external table  dws_sale_detail_daycount
(   user_id   string  comment '用户 id',
    sku_id    string comment '商品 Id',
    user_gender  string comment '用户性别',
    user_age string  comment '用户年龄',
    user_level string comment '用户等级',
    order_price decimal(10,2) comment '订单价格',
    sku_name string   comment '商品名称',
    sku_tm_id string   comment '品牌id',
    sku_category3_id string comment '商品三级品类id',
    sku_category2_id string comment '商品二级品类id',
    sku_category1_id string comment '商品一级品类id',
    sku_category3_name string comment '商品三级品类名称',
    sku_category2_name string comment '商品二级品类名称',
    sku_category1_name string comment '商品一级品类名称',
    spu_id  string comment '商品 spu',
    sku_num  int comment '购买个数',
    order_count string comment '当日下单单数',
    order_amount string comment '当日下单金额'
) COMMENT '用户购买商品明细表'
PARTITIONED BY ( `dt` string)
stored as  parquet 
location '/warehouse/gmall/dws/dws_user_sale_detail_daycount/'
tblproperties ("parquet.compression"="snappy");

6.2.2 数据导入

hive (gmall)>
with
tmp_detail as
(
    select 
        user_id,
        sku_id, 
        sum(sku_num) sku_num ,   
        count(*) order_count , 
        sum(od.order_price*sku_num)  order_amount 
    from ods_order_detail od
    where od.dt='2019-02-10' and user_id is not null
    group by user_id, sku_id
)  
insert overwrite table  dws_sale_detail_daycount partition(dt='2019-02-10')
select 
    tmp_detail.user_id,
    tmp_detail.sku_id,
    u.gender,
    months_between('2019-02-10', u.birthday)/12  age, 
    u.user_level,
    price,
    sku_name,
    tm_id,
    category3_id ,  
    category2_id ,  
    category1_id ,  
    category3_name ,  
    category2_name ,  
    category1_name ,  
    spu_id,
    tmp_detail.sku_num,
    tmp_detail.order_count,
    tmp_detail.order_amount 
from tmp_detail 
left join dwd_user_info u on u.id=tmp_detail.user_id  and u.dt='2019-02-10'
left join dwd_sku_info s on tmp_detail.sku_id =s.id  and s.dt='2019-02-10'
;

6.2.3 数据导入脚本

1)在/home/newbies/bin目录下创建脚本dws_sale.sh

[newbies@hadoop102 bin]$ vim dws_sale.sh

在脚本中填写如下内容

#!/bin/bash

# 定义变量方便修改
APP=gmall
hive=/opt/module/hive/bin/hive

# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;then
	log_date=$1
else 
	log_date=`date  -d "-1 day"  +%F`  
fi 

sql="

set hive.exec.dynamic.partition.mode=nonstrict;

with
tmp_detail as
(
    select 
        user_id,
        sku_id, 
        sum(sku_num) sku_num ,   
        count(*) order_count , 
        sum(od.order_price*sku_num)  order_amount 
    from "$APP".ods_order_detail od
    where od.dt='$log_date' and user_id is not null
    group by user_id, sku_id
)  
insert overwrite table  "$APP".dws_sale_detail_daycount partition(dt='$log_date')
select 
    tmp_detail.user_id,
    tmp_detail.sku_id,
    u.gender,
    months_between('$log_date', u.birthday)/12  age, 
    u.user_level,
    price,
    sku_name,
    tm_id,
    category3_id ,  
    category2_id ,  
    category1_id ,  
    category3_name ,  
    category2_name ,  
    category1_name ,  
    spu_id,
    tmp_detail.sku_num,
    tmp_detail.order_count,
    tmp_detail.order_amount 
from tmp_detail 
left join "$APP".dwd_user_info u 
on u.id=tmp_detail.user_id  and u.dt='$log_date'
left join "$APP".dwd_sku_info s on tmp_detail.sku_id =s.id  and s.dt='$log_date';

"
$hive -e "$sql"

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 dws_sale.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ dws_sale.sh 2019-02-11

4)查看导入数据

hive (gmall)>
select * from dws_sale_detail_daycount where dt='2019-02-11' limit 2;

6.3 ADS层

6.3.1 建表语句

hive (gmall)>
drop  table ads_sale_tm_category1_stat_mn;
create  table ads_sale_tm_category1_stat_mn
(   
    tm_id string comment '品牌id ' ,
    category1_id string comment '1级品类id ',
    category1_name string comment '1级品类名称 ',
    buycount   bigint comment  '购买人数',
    buy_twice_last bigint  comment '两次以上购买人数',
    buy_twice_last_ratio decimal(10,2)  comment  '单次复购率', 
    buy_3times_last   bigint comment   '三次以上购买人数',
    buy_3times_last_ratio decimal(10,2)  comment  '多次复购率' ,
    stat_mn string comment '统计月份',
    stat_date string comment '统计日期' 
)   COMMENT '复购率统计'
row format delimited  fields terminated by '\t' 
location '/warehouse/gmall/ads/ads_sale_tm_category1_stat_mn/'
;

6.3.2 数据导入

1)数据导入

hive (gmall)>
insert into table ads_sale_tm_category1_stat_mn
select   
    mn.sku_tm_id,
    mn.sku_category1_id,
    mn.sku_category1_name,
    sum(if(mn.order_count>=1,1,0)) buycount,
    sum(if(mn.order_count>=2,1,0)) buyTwiceLast,
    sum(if(mn.order_count>=2,1,0))/sum( if(mn.order_count>=1,1,0)) buyTwiceLastRatio,
    sum(if(mn.order_count>3,1,0))  buy3timeLast  ,
    sum(if(mn.order_count>=3,1,0))/sum( if(mn.order_count>=1,1,0)) buy3timeLastRatio ,
    date_format('2019-02-10' ,'yyyy-MM') stat_mn,
    '2019-02-10' stat_date
from 
(     
    select od.sku_tm_id, 
        od.sku_category1_id,
        od.sku_category1_name,  
        user_id , 
        sum(order_count) order_count
    from  dws_sale_detail_daycount  od 
    where 
        date_format(dt,'yyyy-MM')<=date_format('2019-02-10' ,'yyyy-MM')
    group by 
        od.sku_tm_id, od.sku_category1_id, user_id, od.sku_category1_name
) mn
group by mn.sku_tm_id, mn.sku_category1_id, mn.sku_category1_name
;

2)查询导入数据

hive (gmall)> select * from ads_sale_tm_category1_stat_mn;

6.3.3 数据导入脚本

1)在/home/newbies/bin目录下创建脚本ads_sale.sh

[newbies@hadoop102 bin]$ vim ads_sale.sh

在脚本中填写如下内容

#!/bin/bash

# 定义变量方便修改
APP=gmall
hive=/opt/module/hive/bin/hive

# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n $1 ] ;then
	log_date=$1
else 
	log_date=`date  -d "-1 day"  +%F`  
fi 

sql="

set hive.exec.dynamic.partition.mode=nonstrict;

insert into table "$APP".ads_sale_tm_category1_stat_mn
select   
    mn.sku_tm_id,
    mn.sku_category1_id,
    mn.sku_category1_name,
    sum(if(mn.order_count>=1,1,0)) buycount,
    sum(if(mn.order_count>=2,1,0)) buyTwiceLast,
    sum(if(mn.order_count>=2,1,0))/sum( if(mn.order_count>=1,1,0)) buyTwiceLastRatio,
    sum(if(mn.order_count>3,1,0))  buy3timeLast  ,
    sum(if(mn.order_count>=3,1,0))/sum( if(mn.order_count>=1,1,0)) buy3timeLastRatio ,
    date_format('$log_date' ,'yyyy-MM') stat_mn,
    '$log_date' stat_date
from 
(     
    select od.sku_tm_id, 
        od.sku_category1_id,
        od.sku_category1_name,  
        user_id , 
        sum(order_count) order_count
    from  "$APP".dws_sale_detail_daycount  od 
    where date_format(dt,'yyyy-MM')<=date_format('$log_date' ,'yyyy-MM')
    group by od.sku_tm_id, od.sku_category1_id, user_id, od.sku_category1_name
) mn
group by mn.sku_tm_id, mn.sku_category1_id, mn.sku_category1_name;

"
$hive -e "$sql"

2)增加脚本执行权限

[newbies@hadoop102 bin]$ chmod 777 ads_sale.sh

3)执行脚本导入数据

[newbies@hadoop102 bin]$ ads_sale.sh 2019-02-11

4)查看导入数据

hive (gmall)>
select * from ads_sale_tm_category1_stat_mn limit 2;

6.4 品牌复购率结果输出到MySQL

1)在MySQL中创建ads_sale_tm_category1_stat_mn

create  table ads_sale_tm_category1_stat_mn
(   
    tm_id varchar(200) comment '品牌id ' ,
    category1_id varchar(200) comment '1级品类id ',
    category1_name varchar(200) comment '1级品类名称 ',
    buycount   varchar(200) comment  '购买人数',
    buy_twice_last varchar(200) comment '两次以上购买人数',
    buy_twice_last_ratio varchar(200) comment  '单次复购率', 
    buy_3times_last   varchar(200) comment   '三次以上购买人数',
    buy_3times_last_ratio varchar(200)  comment  '多次复购率' ,
    stat_mn varchar(200) comment '统计月份',
    stat_date varchar(200) comment '统计日期' 
)  

2)编写Sqoop导出脚本

在/home/newbies/bin目录下创建脚本sqoop_export.sh

[newbies@hadoop102 bin]$ vim sqoop_export.sh

       在脚本中填写如下内容

#!/bin/bash

db_name=gmall

export_data() {
/opt/module/sqoop/bin/sqoop export \
--connect "jdbc:mysql://hadoop102:3306/${db_name}?useUnicode=true&characterEncoding=utf-8"  \
--username root \
--password 000000 \
--table $1 \
--num-mappers 1 \
--export-dir /warehouse/$db_name/ads/$1 \
--input-fields-terminated-by "\t"  \
--update-key "tm_id,category1_id,stat_mn,stat_date" \
--update-mode allowinsert \
--input-null-string '\\N'    \
--input-null-non-string '\\N'  
}

case $1 in
  "ads_sale_tm_category1_stat_mn")
     export_data "ads_sale_tm_category1_stat_mn"
;;
   "all")
     export_data "ads_sale_tm_category1_stat_mn"
;;
esac

关于导出update还是insert的问题

--update-mode

参数 :

updateonly   只更新,无法插入新数据

        allowinsert   允许新增 

--update-key  

允许更新的情况下,指定哪些字段匹配视为同一条数据,进行更新而不增加。多个字段用逗号分隔。

3)执行Sqoop导出脚本

[newbies@hadoop102 bin]$ chmod 777 sqoop_export.sh
[newbies@hadoop102 bin]$ sqoop_export.sh all

4)在MySQL中查看结果

SELECT * FROM ads_sale_tm_category1_stat_mn;

6.5 练习:求每个等级的用户对应的复购率前十的商品排行

1)每个等级,每种商品,买一次的用户数,买两次的用户数=》得出复购率

2)利用开窗函数,取每个等级的前十

3)形成脚本

第7章 Azkaban调度器

7.1 Azkaban安装

================================ Begin =========================

二 Azkaban安装部署

2.1 安装前准备
1)    将Azkaban Web服务器、Azkaban执行服务器、Azkaban的sql执行脚本及MySQL安装包拷贝到hadoop102虚拟机/opt/software目录下
a)    azkaban-web-server-2.5.0.tar.gz
b)    azkaban-executor-server-2.5.0.tar.gz
c)    azkaban-sql-script-2.5.0.tar.gz
d)    mysql-libs.zip

2)    选择Mysql作为Azkaban数据库,因为Azkaban建立了一些Mysql连接增强功能,以方便Azkaban设置,并增强服务可靠性。(参见hive文档2.4)
2.2 安装Azkaban
1)    在/opt/module/目录下创建azkaban目录
 

[newbies@hadoop102 module]$ mkdir azkaban

2)    解压azkaban-web-server-2.5.0.tar.gz、azkaban-executor-server-2.5.0.tar.gz、azkaban-sql-script-2.5.0.tar.gz到/opt/module/azkaban目录下

[newbies@hadoop102 software]$ tar -zxvf azkaban-web-server-2.5.0.tar.gz -C /opt/module/azkaban/
[newbies@hadoop102 software]$ tar -zxvf azkaban-executor-server-2.5.0.tar.gz -C /opt/module/azkaban/
[newbies@hadoop102 software]$ tar -zxvf azkaban-sql-script-2.5.0.tar.gz -C /opt/module/azkaban/

3)    对解压后的文件重新命名

[newbies@hadoop102 azkaban]$ mv azkaban-web-2.5.0/ server
[newbies@hadoop102 azkaban]$ mv azkaban-executor-2.5.0/ executor

4)    azkaban脚本导入
    进入mysql,创建azkaban数据库,并将解压的脚本导入到azkaban数据库。
 

[newbies@hadoop102 azkaban]$ mysql -uroot -p000000
mysql> create database azkaban;
mysql> use azkaban;
mysql> source /opt/module/azkaban/azkaban-2.5.0/create-all-sql-2.5.0.sql

注:source后跟.sql文件,用于批量处理.sql文件中的sql语句。

2.3 生成密钥库

Keytool是java数据证书的管理工具,使用户能够管理自己的公/私钥对及相关证书。

-keystore    指定密钥库的名称及位置(产生的各类信息将不在.keystore文件中)

-genkey      在用户主目录中创建一个默认文件".keystore"

-alias  对我们生成的.keystore 进行指认别名;如果没有默认是mykey

-keyalg  指定密钥的算法 RSA/DSA 默认是DSA

1)生成 keystore的密码及相应信息的密钥库

[newbies@hadoop102 azkaban]$ keytool -keystore keystore -alias jetty -genkey -keyalg RSA
输入密钥库口令:  
再次输入新口令: 
您的名字与姓氏是什么?
  [Unknown]:  
您的组织单位名称是什么?
  [Unknown]:  
您的组织名称是什么?
  [Unknown]:  
您所在的城市或区域名称是什么?
  [Unknown]:  
您所在的省/市/自治区名称是什么?
  [Unknown]:  
该单位的双字母国家/地区代码是什么?
  [Unknown]:  
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
  [否]:  y

输入 <jetty> 的密钥口令
        (如果和密钥库口令相同, 按回车):  
再次输入新口令:

注意:

密钥库的密码至少必须6个字符,可以是纯数字或者字母或者数字和字母的组合等等

密钥库的密码最好和<jetty> 的密钥相同,方便记忆

2)将keystore 拷贝到 azkaban web服务器根目录中

[newbies@hadoop102 azkaban]$ mv keystore /opt/module/azkaban/server/

2.4 时间同步配置

先配置好服务器节点上的时区

  1. 如果在/usr/share/zoneinfo/这个目录下不存在时区配置文件Asia/Shanghai,就要用 tzselect 生成。
[newbies@hadoop102 azkaban]$ tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
 1) Africa
 2) Americas
 3) Antarctica
 4) Arctic Ocean
 5) Asia
 6) Atlantic Ocean
 7) Australia
 8) Europe
 9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5
Please select a country.
 1) Afghanistan           18) Israel                35) Palestine
 2) Armenia               19) Japan                 36) Philippines
 3) Azerbaijan            20) Jordan                37) Qatar
 4) Bahrain               21) Kazakhstan            38) Russia
 5) Bangladesh            22) Korea (North)         39) Saudi Arabia
 6) Bhutan                23) Korea (South)         40) Singapore
 7) Brunei                24) Kuwait                41) Sri Lanka
 8) Cambodia              25) Kyrgyzstan            42) Syria
 9) China                 26) Laos                  43) Taiwan
10) Cyprus                27) Lebanon               44) Tajikistan
11) East Timor            28) Macau                 45) Thailand
12) Georgia               29) Malaysia              46) Turkmenistan
13) Hong Kong             30) Mongolia              47) United Arab Emirates
14) India                 31) Myanmar (Burma)       48) Uzbekistan
15) Indonesia             32) Nepal                 49) Vietnam
16) Iran                  33) Oman                  50) Yemen
17) Iraq                  34) Pakistan
#? 9
Please select one of the following time zone regions.
1) Beijing Time
2) Xinjiang Time
#? 1

The following information has been given:

        China
        Beijing Time

Therefore TZ='Asia/Shanghai' will be used.
Local time is now:      Thu Oct 18 16:24:23 CST 2018.
Universal Time is now:  Thu Oct 18 08:24:23 UTC 2018.
Is the above information OK?
1) Yes
2) No
#? 1

You can make this change permanent for yourself by appending the line
        TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.

Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai

2)拷贝该时区文件,覆盖系统本地时区配置

[newbies@hadoop102 azkaban]$ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  

3)集群时间同步(同时发给三个窗口)

[newbies@hadoop102 azkaban]$ sudo date -s '2018-10-18 16:39:30'

2.5 配置文件

2.5.1 Web服务器配置

1)进入azkaban web服务器安装目录 conf目录,打开azkaban.properties文件

[newbies@hadoop102 conf]$ pwd
/opt/module/azkaban/server/conf
[newbies@hadoop102 conf]$ vim azkaban.properties

2)按照如下配置修改azkaban.properties文件。

#Azkaban Personalization Settings
#服务器UI名称,用于服务器上方显示的名字
azkaban.name=Test
#描述
azkaban.label=My Local Azkaban
#UI颜色
azkaban.color=#FF3601
azkaban.default.servlet.path=/index
#默认web server存放web文件的目录
web.resource.dir=/opt/module/azkaban/server/web/
#默认时区,已改为亚洲/上海 默认为美国
default.timezone.id=Asia/Shanghai

#Azkaban UserManager class
user.manager.class=azkaban.user.XmlUserManager
#用户权限管理默认类(绝对路径)
user.manager.xml.file=/opt/module/azkaban/server/conf/azkaban-users.xml

#Loader for projects
#global配置文件所在位置(绝对路径)
executor.global.properties=/opt/module/azkaban/executor/conf/global.properties
azkaban.project.dir=projects

#数据库类型
database.type=mysql
#端口号
mysql.port=3306
#数据库连接IP
mysql.host=hadoop102
#数据库实例名
mysql.database=azkaban
#数据库用户名
mysql.user=root
#数据库密码
mysql.password=000000
#最大连接数
mysql.numconnections=100

# Velocity dev mode
velocity.dev.mode=false

# Azkaban Jetty server properties.
# Jetty服务器属性.
#最大线程数
jetty.maxThreads=25
#Jetty SSL端口
jetty.ssl.port=8443
#Jetty端口
jetty.port=8081
#SSL文件名(绝对路径)
jetty.keystore=/opt/module/azkaban/server/keystore
#SSL文件密码
jetty.password=000000
#Jetty主密码与keystore文件相同
jetty.keypassword=000000
#SSL文件名(绝对路径)
jetty.truststore=/opt/module/azkaban/server/keystore
#SSL文件密码
jetty.trustpassword=000000

# Azkaban Executor settings
executor.port=12321

# mail settings
mail.sender=
mail.host=
job.failure.email=
job.success.email=

lockdown.create.projects=false

cache.directory=cache

 3)web服务器用户配置

在azkaban web服务器安装目录 conf目录,按照如下配置修改azkaban-users.xml 文件,增加管理员用户。

[newbies@hadoop102 conf]$ vim azkaban-users.xml
<azkaban-users>
	<user username="azkaban" password="azkaban" roles="admin" groups="azkaban" />
	<user username="metrics" password="metrics" roles="metrics"/>
	<user username="admin" password="admin" roles="admin,metrics" />
	<role name="admin" permissions="ADMIN" />
	<role name="metrics" permissions="METRICS"/>
</azkaban-users>

2.5.2 执行服务器配置

1)进入执行服务器安装目录conf,打开azkaban.properties

[newbies@hadoop102 conf]$ pwd
/opt/module/azkaban/executor/conf
[newbies@hadoop102 conf]$ vim azkaban.properties

 2)按照如下配置修改azkaban.properties文件。

#Azkaban
#时区
default.timezone.id=Asia/Shanghai

# Azkaban JobTypes Plugins
#jobtype 插件所在位置
azkaban.jobtype.plugin.dir=plugins/jobtypes

#Loader for projects
executor.global.properties=/opt/module/azkaban/executor/conf/global.properties
azkaban.project.dir=projects

database.type=mysql
mysql.port=3306
mysql.host=hadoop102
mysql.database=azkaban
mysql.user=root
mysql.password=000000
mysql.numconnections=100

# Azkaban Executor settings
#最大线程数
executor.maxThreads=50
#端口号(如修改,请与web服务中一致)
executor.port=12321
#线程数
executor.flow.threads=30

2.6 启动executor服务器

executor服务器目录下执行启动命令

[newbies@hadoop102 executor]$ pwd
/opt/module/azkaban/executor
[newbies@hadoop102 executor]$ bin/azkaban-executor-start.sh

2.7 启动web服务器

在azkaban web服务器目录下执行启动命令

[newbies@hadoop102 server]$ pwd
/opt/module/azkaban/server
[newbies@hadoop102 server]$ bin/azkaban-web-start.sh

注意:

先执行executor,再执行web,避免Web Server会因为找不到执行器启动失败。

jps查看进程

[newbies@hadoop102 server]$ jps
3601 AzkabanExecutorServer
5880 Jps
3661 AzkabanWebServer

启动完成后,在浏览器(建议使用谷歌浏览器)中输入https://服务器IP地址:8443,即可访问azkaban服务了。

在登录中输入刚才在azkaban-users.xml文件中新添加的户用名及密码,点击 login。

三 Azkaban实战

Azkaba内置的任务类型支持command、java

3.1单一job案例

1)创建job描述文件

[newbies@hadoop102 jobs]$ vim first.job
#first.job
type=command
command=echo 'this is my first job'

2) 将job资源文件打包成zip文件

[newbies@hadoop102 jobs]$ zip first.zip first.job 
  adding: first.job (deflated 15%)
[newbies@hadoop102 jobs]$ ll
总用量 8
-rw-rw-r--. 1 newbies newbies  60 10月 18 17:42 first.job
-rw-rw-r--. 1 newbies newbies 219 10月 18 17:43 first.zip

注意:

目前,Azkaban上传的工作流文件只支持xxx.zip文件。zip应包含xxx.job运行作业所需的文件和任何文件(文件名后缀必须以.job结尾,否则无法识别)。作业名称在项目中必须是唯一的。

3)通过azkaban的web管理平台创建project并上传job的zip包

首先创建project

上传zip包

4)启动执行该job

点击执行工作流

点击继续

5)Job执行成功

6)点击查看job日志

3.2多job工作流案例

1)创建有依赖关系的多个job描述

第一个job:start.job

[newbies@hadoop102 jobs]$ vim start.job
#start.job
type=command
command=touch /opt/module/kangkang.txt

第二个job:step1.job依赖start.job

[newbies@hadoop102 jobs]$ vim step1.job
#step1.job
type=command
dependencies=start
command=echo "this is step1 job"

第三个job:step2.job依赖start.job

[newbies@hadoop102 jobs]$ vim step2.job
#step2.job
type=command
dependencies=start
command=echo "this is step2 job"

第四个job:finish.job依赖step1.job和step2.job

[newbies@hadoop102 jobs]$ vim finish.job
#finish.job
type=command
dependencies=step1,step2
command=echo "this is finish job"

2)将所有job资源文件打到一个zip包中

[newbies@hadoop102 jobs]$ zip jobs.zip start.job step1.job step2.job finish.job
updating: start.job (deflated 16%)
  adding: step1.job (deflated 12%)
  adding: step2.job (deflated 12%)
  adding: finish.job (deflated 14%) 

3)在azkaban的web管理界面创建工程并上传zip包

4)启动工作流flow

6)查看结果

思考:

将student.txt文件上传到hdfs,根据所传文件创建外部表,再将表中查询到的结果写入到本地文件

3.3 java操作任务

使用Azkaban调度java程序

1)编写java程序

import java.io.IOException;

public class AzkabanTest {
	public void run() throws IOException {
        // 根据需求编写具体代码
		FileOutputStream fos = new FileOutputStream("/opt/module/azkaban/output.txt");
		fos.write("this is a java progress".getBytes());
		fos.close();
    }

	public static void main(String[] args) throws IOException {
		AzkabanTest azkabanTest = new AzkabanTest();
		azkabanTest.run();
	}
}

2)将java程序打成jar包,创建lib目录,将jar放入lib内

[newbies@hadoop102 azkaban]$ mkdir lib
[newbies@hadoop102 azkaban]$ cd lib/
[newbies@hadoop102 lib]$ ll
总用量 4
-rw-rw-r--. 1 newbies newbies 3355 10月 18 20:55 azkaban-0.0.1-SNAPSHOT.jar

3)编写job文件

[newbies@hadoop102 jobs]$ vim azkabanJava.job
#azkabanJava.job
type=javaprocess
java.class=com.newbies.azkaban.AzkabanTest
classpath=/opt/module/azkaban/lib/*

4)将job文件打成zip包

[newbies@hadoop102 jobs]$ zip azkabanJava.zip azkabanJava.job 
  adding: azkabanJava.job (deflated 19%)

5)通过azkaban的web管理平台创建project并上传job压缩包,启动执行该job

[newbies@hadoop102 azkaban]$ pwd
/opt/module/azkaban
[newbies@hadoop102 azkaban]$ ll
总用量 24
drwxrwxr-x.  2 newbies newbies 4096 10月 17 17:14 azkaban-2.5.0
drwxrwxr-x. 10 newbies newbies 4096 10月 18 17:17 executor
drwxrwxr-x.  2 newbies newbies 4096 10月 18 20:35 jobs
drwxrwxr-x.  2 newbies newbies 4096 10月 18 20:54 lib
-rw-rw-r--.  1 newbies newbies   23 10月 18 20:55 output
drwxrwxr-x.  9 newbies newbies 4096 10月 18 17:17 server
[newbies@hadoop102 azkaban]$ cat output 
this is a java progress

3.3 HDFS操作任务

1)创建job描述文件

[newbies@hadoop102 jobs]$ vim fs.job
#hdfs job
type=command
command=/opt/module/hadoop-2.7.2/bin/hadoop fs -mkdir /azkaban

2)将job资源文件打包成zip文件

[newbies@hadoop102 jobs]$ zip fs.zip fs.job 
  adding: fs.job (deflated 12%)

3)通过azkaban的web管理平台创建project并上传job压缩包

4)启动执行该job

5)查看结果

3.4 mapreduce任务

mapreduce任务依然可以使用azkaban进行调度

 1)创建job描述文件,及mr程序jar包

[newbies@hadoop102 jobs]$ vim mapreduce.job
#mapreduce job
type=command
command=/opt/module/hadoop-2.7.2/bin/hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /wordcount/input /wordcount/output

2)    将所有job资源文件打到一个zip包中

[newbies@hadoop102 jobs]$ zip mapreduce.zip mapreduce.job 
  adding: mapreduce.job (deflated 43%)

3)在azkaban的web管理界面创建工程并上传zip包
4)启动job
5)查看结果

3.5 Hive脚本任务

1)创建job描述文件和hive脚本

(1)Hive脚本:student.sql

[newbies@hadoop102 jobs]$ vim student.sql
use default;
drop table student;
create table student(id int, name string)
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/datas/student.txt' into table student;
insert overwrite local directory '/opt/module/datas/student'
row format delimited fields terminated by '\t'
select * from student;

(2)Job描述文件:hive.job

[newbies@hadoop102 jobs]$ vim hive.job
#hive job
type=command
command=/opt/module/hive/bin/hive -f /opt/module/azkaban/jobs/student.sql

2)    将所有job资源文件打到一个zip包中

[newbies@hadoop102 jobs]$ zip hive.zip hive.job 
  adding: hive.job (deflated 21%)

3)在azkaban的web管理界面创建工程并上传zip包
4)启动job
5)查看结果

[newbies@hadoop102 student]$ cat /opt/module/datas/student/000000_0 
1001    yangyang
1002    bobo
1003    banzhang
1004    pengpeng

7.2 复购率指标的产生的全调度流程

1)生成数据

CALL init_data('2019-02-12',300,200,300,FALSE);

2)编写Azkaban程序运行job.

       (1)import文件

type=command
do_date=${dt}
command=/home/newbies/bin/sqoop_import.sh all ${do_date}

(2)ods文件

type=command
do_date=${dt}

dependencies=import
command=/home/newbies/bin/ods_db.sh ${do_date}

(3)dwd文件

type=command
do_date=${dt}
dependencies=ods
command=/home/newbies/bin/dwd_db.sh ${do_date}

       (4)dws文件

type=command
do_date=${dt}
dependencies=dwd
command=/home/newbies/bin/dws_sale.sh ${do_date}

       (5)ads文件

type=command
do_date=${dt}
dependencies=dws
command=/home/newbies/bin/ads_sale.sh ${do_date}

       (6)export文件

type=command
do_date=${dt}
dependencies=ads
command=/home/newbies/bin/sqoop_export.sh all ${do_date}

       (7)将以上6个文件压缩成gmall-job.zip文件

3)创建Azkaban工程,并上传gmall-job.zip文件。

 第8章 订单表拉链表

8.1 什么是拉链表

8.2 为什么要做拉链表

8.3 拉链表形成过程

如何使用拉链表

8.4 拉链表制作过程图

8.5 拉链表制作过程

8.5.1 步骤0:初始化拉链表,首次独立执行

初始化拉链表

1)生成10条原始订单数据

CALL init_data('2019-02-13',10,5,10,TRUE);

[newbies@hadoop102 bin]$ sqoop_import.sh all 2019-02-13

[newbies@hadoop102 bin]$ ods_db.sh 2019-02-13

[newbies@hadoop102 bin]$ dwd_db.sh 2019-02-13

2)建立拉链表

hive (gmall)>
drop table if exists dwd_order_info_his;
create table dwd_order_info_his( 
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额', 
    `order_status` string COMMENT '订单状态', 
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',  
    `out_trade_no` string COMMENT '支付流水号',  
    `create_time` string COMMENT '创建时间',  
    `operate_time` string COMMENT '操作时间' ,
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链表'
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_info_his/'
tblproperties ("parquet.compression"="snappy");

3)初始化拉链表

hive (gmall)>
insert overwrite table dwd_order_info_his  
select 
    id,
    total_amount,
    order_status,
    user_id,
    payment_way,
    out_trade_no,
    create_time,
    operate_time,
    '2019-02-13',
    '9999-99-99'
from ods_order_info oi 
where oi.dt='2019-02-13';

4)查询拉链表中数据

hive (gmall)> select * from dwd_order_info_his limit 2;

8.5.2 步骤1:先制作当日变动(包括新增,修改)每日执行

1)如何获得每日变动表

1)最好表内有创建时间和变动时间(Lucky!

(2)如果没有,可以利用第三方工具监控比如canal,监控MySQL的实时变化进行记录(麻烦)。

(3)逐行对比前后两天的数据, 检查md5(concat(全部有可能变化的字段))是否相同(low)

(4)要求业务数据库提供变动流水(人品,颜值)

2)因为dwd_order_info本身导入过来就是新增变动明细的表,所以不用处理

(1)2019-02-14日新增2条订单数据

CALL init_data('2019-02-14',2,5,10,TRUE);

(2)通过Sqoop把2019-02-14日所有数据导入

sqoop_import.sh all 2019-02-14

(3)ODS层数据导入

ods_db.sh 2019-02-14

(4)DWD层数据导入

dwd_db.sh 2019-02-14

8.5.3 步骤2:先合并变动信息,再追加新增信息 插入到临时表中

1)建立临时表

hive (gmall)>
drop table if exists dwd_order_info_his_tmp;
create external table dwd_order_info_his_tmp( 
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额', 
    `order_status` string COMMENT '订单状态', 
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',  
    `out_trade_no` string COMMENT '支付流水号',  
    `create_time` string COMMENT '创建时间',  
    `operate_time` string COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'
stored as  parquet
location '/warehouse/gmall/dwd/dwd_order_info_his_tmp/'
tblproperties ("parquet.compression"="snappy");

2)导入脚本

拉链表
hive (gmall)>
insert overwrite table dwd_order_info_his_tmp
select * from 
(
select 
id,
    total_amount   , 
    order_status , 
    user_id  ,
    payment_way  ,  
    out_trade_no,  
    create_time ,  
    operate_time ,
    '2019-02-14' start_date,
    '9999-99-99' end_date
from dwd_order_info where dt='2019-02-14'

union all 
select oh.id,
    oh.total_amount   , 
    oh.order_status , 
    oh.user_id  ,
    oh.payment_way  ,  
    oh.out_trade_no,  
    oh.create_time ,  
    oh.operate_time ,
    oh.start_date,
    if(oi.id is null ,oh.end_date, date_add(oi.dt,-1)) end_date
from dwd_order_info_his oh left join 
     (
select 
* 
from dwd_order_info   
where  dt='2019-02-14'
) oi
     on oh.id=oi.id and oh.end_date='9999-99-99'  
)his 
order by his.id, start_date;

8.5.4 步骤3:把临时表覆盖给拉链表

1)导入数据

hive (gmall)>
insert overwrite table  dwd_order_info_his 
select * from  dwd_order_info_his_tmp;

2)查询导入数据

hive (gmall)> select * from dwd_order_info_his ;

8.5.5 整理为每日脚本

 

第9章 OLAP分析工具之Presto

9.1 Presto Server安装

1)下载地址

https://repo1.maven.org/maven2/com/facebook/presto/presto-server/0.196/presto-server-0.196.tar.gz

2)将presto-server-0.196.tar.gz导入hadoop102的/opt/software目录下,并解压到/opt/module目录

[newbies@hadoop102 software]$ tar -zxvf presto-server-0.196.tar.gz -C /opt/module/

3)修改名称为presto

[newbies@hadoop102 module]$ mv presto-server-0.196/ presto

4)进入到/opt/module/presto目录,并创建存储数据文件夹

[newbies@hadoop102 presto]$ mkdir data

5)进入到/opt/module/presto目录,并创建存储配置文件文件夹

[newbies@hadoop102 presto]$ mkdir etc

6)配置在/opt/module/presto/etc目录下添加jvm.config配置文件

[newbies@hadoop102 etc]$ vim jvm.config

添加如下内容

-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError

7)Presto可以支持多个数据源,在Presto里面叫catalog,这里我们配置支持Hive的数据源,配置一个Hive的catalog

[newbies@hadoop102 etc]$ mkdir catalog
[newbies@hadoop102 catalog]$ vim hive.properties 

添加如下内容

connector.name=hive-hadoop2
hive.metastore.uri=thrift://hadoop102:9083

8)将hadoop102上的presto分发到hadoop103、hadoop104

[newbies@hadoop102 module]$ xsync presto

9)解压之后,分别进入hadoop102、hadoop103、hadoop104三台主机的/opt/module/presto/etc的路径。配置node属性,node id每个节点都不一样。

[newbies@hadoop102 etc]$vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/opt/module/presto/data

[newbies@hadoop103 etc]$vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-fffffffffffe
node.data-dir=/opt/module/presto/data

[newbies@hadoop104 etc]$vim node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-fffffffffffd
node.data-dir=/opt/module/presto/data

10)Presto是由一个coordinator节点和多个worker节点组成。在hadoop102上配置成coordinator,在hadoop103、hadoop104上配置为worker。

(1)hadoop102上配置coordinator节点

[newbies@hadoop102 etc]$ vim config.properties

添加内容如下

coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8881
query.max-memory=50GB
discovery-server.enabled=true
discovery.uri=http://hadoop102:8881

(2)hadoop103、hadoop104上配置worker节点

[newbies@hadoop103 etc]$ vim config.properties

添加内容如下

coordinator=false
http-server.http.port=8881
query.max-memory=50GB
discovery.uri=http://hadoop102:8881
[newbies@hadoop104 etc]$ vim config.properties

添加内容如下

coordinator=false
http-server.http.port=8881
query.max-memory=50GB
discovery.uri=http://hadoop102:8881

11)在/opt/module/hive目录下,启动Hive Metastore,用newbies角色

nohup bin/hive --service metastore >/dev/null 2>&1 &

12)分别在hadoop102、hadoop103、hadoop104上启动presto server

(1)前台启动presto,控制台显示日志

[newbies@hadoop102 presto]$ bin/launcher run
[newbies@hadoop103 presto]$ bin/launcher run
[newbies@hadoop104 presto]$ bin/launcher run

(2)后台启动presto

[newbies@hadoop102 presto]$ bin/launcher start
[newbies@hadoop103 presto]$ bin/launcher start
[newbies@hadoop104 presto]$ bin/launcher start

13)日志查看路径/opt/module/presto/data/var/log

9.2 Presto命令行Client安装

1)下载Presto的客户端

https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/0.196/presto-cli-0.196-executable.jar

2)将presto-cli-0.196-executable.jar上传到hadoop102的/opt/module/presto文件夹下

3)修改文件名称

[newbies@hadoop102 presto]$ mv presto-cli-0.196-executable.jar  prestocli

4)增加执行权限

[newbies@hadoop102 presto]$ chmod +x prestocli

5)启动prestocli

[newbies@hadoop102 presto]$ ./prestocli --server hadoop102:8881 --catalog hive --schema default

6)Presto命令行操作

Presto的命令行操作,相当于hive命令行操作,不过没有use命令。每个表必须要加上schema。

例如:

select * from schema.table limit 100

9.3 Presto可视化Client安装

1)将yanagishima-18.0.zip上传到hadoop102的/opt/module目录

2)解压缩yanagishima

[newbies@hadoop102 module]$ unzip yanagishima-18.0.zip
cd yanagishima-18.0

3)进入到/opt/module/yanagishima-18.0/conf文件夹,编写yanagishima.properties配置

[newbies@hadoop102 conf]$ vim yanagishima.properties

       添加如下内容

jetty.port=7080
presto.datasources=atiguigu-presto
presto.coordinator.server.atiguigu-presto=http://hadoop102:8881
catalog.atiguigu-presto=hive
schema.atiguigu-presto=default
sql.query.engines=presto

4)在/opt/module/yanagishima-18.0路径下启动yanagishima

[newbies@hadoop102 yanagishima-18.0]$
nohup bin/yanagishima-start.sh >y.log 2>&1 &

5)启动web页面

http://hadoop102:7080

看到界面,进行查询了。

9.4 Presto可视化操作

查看表结构

这里有个tree view,可以查看所有表的结构,包括schema、表、字段等。

比如执行 select * from hive.dw_weather.tmp_news_click limit 10,这个句子里hive这个词可以删掉,是上面配置的catalog

 

每个表后面都有个复制键,点一下会复制完整的表名,然后再上面框里面输入sql语句,ctrl+enter键执行显示结果

发布了318 篇原创文章 · 获赞 46 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_31784189/article/details/105125636
今日推荐