前言
读者你好,很高兴你能看到这篇文章,这是一份关于大数据电商项目的深度学习。学习之前请花费几分钟看一下下面关于我的自述。
我纠结写这个已经很久了,我24岁毕业,本科计算机,现在26了,考研失败于是在第一年(2018)年底找工作,第一份工作是少儿编程讲师,个人认为自己适合当老师,所以还是挺喜欢这份工作,但是奈何在不知道几线的小城市里拿着不到3k的工资,实在难以活下去,尤其对于我这种单亲,又是务农的家庭,可想而知生活确实很苦。
于是我一个人带着行李借着钱来到北京培训IT,很坑,要价很贵,这段经历就不说了,过程很痛苦,当然最后我找到了一份过万的工作,不是码农的活,是一个业务实施,不用敲代码,但是长期出差,只要沟通没问题,学历符合就能入职,门槛很低,于是我入职了,然后转正了,但是万万没想到最后我被辞了。
先不说这份工作前途如何渺茫,这公司的人就很无语,尤其和我出差共事的一个经理,那简直刷新了我对工作的认知。拿一件小事来说,我晚上买奶茶放在桌子上,第二天总管来了,某经理指着桌上的奶茶说“我知道您要来,连夜给您买的。”就这么一件小事,你应该知道他是怎么当上经理的了,基本一路靠抢功,甩锅,吹牛逼上位的。他在总部也是臭名远扬,可想而知我在职期间有多痛苦,就这种人装的逼就让人受不了,往往爱吹牛逼的人都没有什么本事,这道理在他身上体现的淋漓尽致。
最后各种原因,主要原因也是被陷害,在一脸蒙B的情况下我被辞职了,在这个公司呆了有半年,最后我还是锤了这个下三滥,我永远记得那种爽快。最后公司缺人,总管又要求我回去,我回绝了。
这大概是我做过人生中最对的决定,虽然裸辞很迷茫。接下来我重整旗鼓,开始学习大数据,没有什么开发经验的我也是厚着脸皮要求培训机构再让我培训大数据一遍,于是掏了500元我又培训了,当然,这期间我自己也开始学习大数据相关的材料,因为培训机构的大数据部分很垃圾,根本支撑不了找到工作,但是就业资源很好,而且可以给在迷茫的我一点动力和规划。
就这样我花了三个月时间找到了一份大数据工作的薪资,过万,但是不及我上份工作,但是我觉得值,因为上份工作没有任何技术含量,基本是个人都可以快速上手,离职率极高。
从上份工作辞职开始到这份工作接受,这期间似乎感觉自己重生了一般。心里变得似乎更加强大,也变的更加警惕认真,也不容易妥协,也变得自私起来。从小白变老手的一个过程我只用了半年,废话说的有点多了,不过这些都是交代了一下自己的经历,下面说一下关于找大数据工作的一些事情。
行业说明
不管是大数据行业小白,还是转行,首先找工作的前提是你需要会这门技术,你必须要有开发经验,当然,大数据你需要知道大数据生态中的各个组件的原理及使用方法,不知道的还是请先自学一下,也用不了多久,理解不了就背下来。
其次是项目,像样的项目必须要有,尚硅谷的大数据算是我见过比较好的了,确实不错,从整体架构到最后的展示算是业内良心,在B站上也将开源的课程视频公布,但是,我认为90%以上的人听一遍是不会懂的,最多代码复制上,跑通一遍就开始找工作了,虽然我多多少少也这么干过,因为我比较着急。
目前我是在职等待项目需求,暂时没什么事干,又觉得自己大脑空白,想着以后自己的发展,以及手头仅有的练习项目,也只有好好领悟这个尚硅谷的电商项目了,所以我想在CSDN上连载关于我学习的一些感悟,这个项目保守估计我大概看了有4遍以上,但是我自己做还是存在难度,想要吃透还是有一定难度。
这个栏目我不知道自己会更多久,多久会断掉,但是我会抓紧时间将步骤细节更新,将一些感悟夹杂其中,更好去理解ETL,也希望帮助转行或者想从事相关行业的你,不要害怕这个行业不收你,你自己技术不行等等等因素,你只要记住一点:努力在这个时代不会成功,但是拼命可以。烂命一条赔了就赔了(这句开玩笑的,狗命要紧,狗命要紧~)。
言归正传,剑指offer
第一章 数据的生成与传输
注:所有的工具我会在提到的地方放上百度云连接,自取。本文适用于看过一遍视频的项目
尚硅谷的电商大数据项目,在这里不介绍了,简单来说,就是将电商的业务数据以及用户的行为数据进行ETL,最后清洗出来有用的数据进行展示。
这个项目中的数据都是仿造出来的,真正生产线上的数据也是通过埋点得到相应规则的数据,不过省略了这一步,现在靠做好的jar包生产数据就可以了。
刚才也说了,该项目有两部分数据,一部分叫做业务数据,一部分叫做用户行为数据。
电商项目架构图(熟记)
业务数据
所谓业务数据就是电商内的业务,由一些订单,优惠券,商品信息,评价等等业务组成,这些数据是以日志的格式打印出来,通过数据流保存到HDFS上进行备份,同时通过Hive处理。
用户行为数据
用户行为数据,这部分数据是存在数据库中的,以表的形式存储进来,因为用户都是存库存表的,规律性很强,新增用户及商品增加,还有一些订单等信息,都是存在数据库中的,大公司一般会存在Oracle中,但是现在Oracle国内都在替换它,做迁徙方案,因为有一些国际因素,都在替换成MySQL的集群,我们目前使用的也是MySQL,但是现在只需要使用jar包生辰就可以了。
数据的生成
-业务数据的生成及传输
这里不多说,没有什么难点,就是生成数据,涉及到传输的地方需要重点理解强调一下。这一块我写过,业务数据的传输,点这里,采用的LZO传输,CDH版本,一般客户都会采用CDH,CDH和自己搭建大数据环境差不多,没条件的同学也不用着急,用自己搭建的环境即可。最后形成的效果如下:
-用户行为数据的生成及传输
这一块数据是存放在MySQL中的,可以通过jar包生成数据,
下载jar包及配置文件,提取码:c8as
第一步:导入sql表,打开如下文件导入到MySQL中,导入失败的直接打开sql文件进行复制 执行。
第二步:在地址栏中输入cmd,代开命令行,输入java -jar gmall-mock-db-2020-03-16-SNAPSHOT.jar
生成数据,这个jar包是springboot项目,可采用修改配置文件的方式修改生成数据的内容。
第三步:修改配置文件application.properties
,可以更改你想要的日期
logging.level.root=info
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://hadoop103:3306/gmall?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
logging.pattern.console=%m%n
mybatis-plus.global-config.db-config.field-strategy=not_null
#业务日期
mock.date=2020-11-19
#是否重置 传入0是追加 1是重置
mock.clear=1
#是否生成新用户
mock.user.count=1000
#男性比例
mock.user.male-rate=20
#收藏取消比例
mock.favor.cancel-rate=10
#收藏数量
mock.favor.count=100
#加购表插入的记录数量
mock.cart.count=20
#一个购物车中单个商品的最多个数
mock.cart.sku-maxcount-per-cart=3
#用户下单比例
mock.order.user-rate=80
#用户从购物中购买商品比例
mock.order.sku-rate=70
#是否参加活动
mock.order.join-activity=1
#是否使用购物券
mock.order.use-coupon=1
#购物券领取人数
mock.coupon.user-count=10
#支付比例
mock.payment.rate=70
#支付方式 支付宝:微信 :银联
mock.payment.payment-type=30:60:10
#评价比例 好:中:差:自动
mock.comment.appraise-rate=30:10:10:50
#退款原因比例:质量问题 商品描述与实际描述不一致 缺货 号码不合适 拍错 不想买了 其他
mock.refund.reason-rate=30:10:20:5:15:5:5
用户行为的传输过程
看到以上的架构图,可以得知通过sqoop进行用户行为数据的传输,脚本都在上面的连接中,注意看注释,脚本如下:
#! /bin/bash
##这个是sqoop的路径,date的日期
sqoop=/opt/module/sqoop/bin/sqoop
do_date=`date -d '-1 day' +%F`
if [ -n "$2" ]; then
do_date=$2
fi
##这是其中的一个函数,通过该函数可以进行sqoop的传输
##注意第一 $1 不是传入的参数,而是传入该函数的sql语句,$2 是传入数据库表名
##最后的hadoop是传入的lzo压缩格式
import_data(){
##如果是CDH环境,请把上面的路径注释掉,然后改为 sqoop import \
#sqoop import \
$sqoop import \
--connect jdbc:mysql://hadoop103:3306/gmall \
--username root \
--password 123456 \
--target-dir /origin_data_cdh/gmall/db/$1/$do_date \
--delete-target-dir \
--query "$2 and \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec lzop \
--null-string '\\N' \
--null-non-string '\\N'
hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data_cdh/gmall/db/$1/$do_date
}
## 函数中也分增量和全量表,看到where 1=1 的都是全量表,带有日期的都是增量表
import_order_info(){
import_data order_info "select
id,
final_total_amount,
order_status,
user_id,
out_trade_no,
create_time,
operate_time,
province_id,
benefit_reduce_amount,
original_total_amount,
feight_fee
from order_info
where (date_format(create_time,'%Y-%m-%d')='$do_date'
or date_format(operate_time,'%Y-%m-%d')='$do_date')"
}
import_coupon_use(){
import_data coupon_use "select
id,
coupon_id,
user_id,
order_id,
coupon_status,
get_time,
using_time,
used_time
from coupon_use
where (date_format(get_time,'%Y-%m-%d')='$do_date'
or date_format(using_time,'%Y-%m-%d')='$do_date'
or date_format(used_time,'$Y-%m-%d')='$do_date')"
}
import_order_status_log(){
import_data order_status_log "select
id,
order_id,
order_status,
operate_time
from order_status_log
where date_format(operate_time,'%Y-%m-%d')='$do_date'"
}
import_activity_order(){
import_data activity_order "select
id,
activity_id,
order_id,
create_time
from activity_order
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
import_user_info(){
import_data "user_info" "select
id,
name,
birthday,
gender,
email,
user_level,
create_time,
operate_time
from user_info
where (DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date'
or DATE_FORMAT(operate_time,'%Y-%m-%d')='$do_date')"
}
import_order_detail(){
import_data order_detail "select
od.id,
order_id,
user_id,
sku_id,
sku_name,
order_price,
sku_num,
od.create_time
from order_detail od
join order_info oi
on od.order_id=oi.id
where DATE_FORMAT(od.create_time,'%Y-%m-%d')='$do_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')='$do_date'"
}
import_comment_info(){
import_data comment_info "select
id,
user_id,
sku_id,
spu_id,
order_id,
appraise,
comment_txt,
create_time
from comment_info
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
import_order_refund_info(){
import_data order_refund_info "select
id,
user_id,
order_id,
sku_id,
refund_type,
refund_num,
refund_amount,
refund_reason_type,
create_time
from order_refund_info
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
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_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_base_province(){
import_data base_province "select
id,
name,
region_id,
area_code,
iso_code
from base_province
where 1=1"
}
import_base_region(){
import_data base_region "select
id,
region_name
from base_region
where 1=1"
}
import_base_trademark(){
import_data base_trademark "select
tm_id,
tm_name
from base_trademark
where 1=1"
}
import_spu_info(){
import_data spu_info "select
id,
spu_name,
category3_id,
tm_id
from spu_info
where 1=1"
}
import_favor_info(){
import_data favor_info "select
id,
user_id,
sku_id,
spu_id,
is_cancel,
create_time,
cancel_time
from favor_info
where 1=1"
}
import_cart_info(){
import_data cart_info "select
id,
user_id,
sku_id,
cart_price,
sku_num,
sku_name,
create_time,
operate_time,
is_ordered,
order_time
from cart_info
where 1=1"
}
import_coupon_info(){
import_data coupon_info "select
id,
coupon_name,
coupon_type,
condition_amount,
condition_num,
activity_id,
benefit_amount,
benefit_discount,
create_time,
range_type,
spu_id,
tm_id,
category3_id,
limit_num,
operate_time,
expire_time
from coupon_info
where 1=1"
}
import_activity_info(){
import_data activity_info "select
id,
activity_name,
activity_type,
start_time,
end_time,
create_time
from activity_info
where 1=1"
}
import_activity_rule(){
import_data activity_rule "select
id,
activity_id,
condition_amount,
condition_num,
benefit_amount,
benefit_discount,
benefit_level
from activity_rule
where 1=1"
}
import_base_dic(){
import_data base_dic "select
dic_code,
dic_name,
parent_code,
create_time,
operate_time
from base_dic
where 1=1"
}
##进行参数调用
case $1 in
"order_info")
import_order_info
;;
"base_category1")
import_base_category1
;;
"base_category2")
import_base_category2
;;
"base_category3")
import_base_category3
;;
"order_detail")
import_order_detail
;;
"sku_info")
import_sku_info
;;
"user_info")
import_user_info
;;
"payment_info")
import_payment_info
;;
"base_province")
import_base_province
;;
"base_region")
import_base_region
;;
"base_trademark")
import_base_trademark
;;
"activity_info")
import_activity_info
;;
"activity_order")
import_activity_order
;;
"cart_info")
import_cart_info
;;
"comment_info")
import_comment_info
;;
"coupon_info")
import_coupon_info
;;
"coupon_use")
import_coupon_use
;;
"favor_info")
import_favor_info
;;
"order_refund_info")
import_order_refund_info
;;
"order_status_log")
import_order_status_log
;;
"spu_info")
import_spu_info
;;
"activity_rule")
import_activity_rule
;;
"base_dic")
import_base_dic
;;
"first")
import_base_category1
import_base_category2
import_base_category3
import_order_info
import_order_detail
import_sku_info
import_user_info
import_payment_info
import_base_province
import_base_region
import_base_trademark
import_activity_info
import_activity_order
import_cart_info
import_comment_info
import_coupon_use
import_coupon_info
import_favor_info
import_order_refund_info
import_order_status_log
import_spu_info
import_activity_rule
import_base_dic
;;
"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
import_base_trademark
import_activity_info
import_activity_order
import_cart_info
import_comment_info
import_coupon_use
import_coupon_info
import_favor_info
import_order_refund_info
import_order_status_log
import_spu_info
import_activity_rule
import_base_dic
;;
esac
关于sqoop的知识点,重要的是如何从数据库中拿表,通过Hive到HDFS,如何让HDFS上的数据入库到数据库中,这些都是需要掌握的。知识点在这里不赘述了,提供几篇写的不错博客供参考。
sqoop快速如门
CDH中Sqoop的使用心得
面试提问
Sqoop方面
1、你们公司采用什么方式同步数据库中的数据到HDFS的?
2、你知道Sqoop1和Sqoop2的区别吗?
3、说说看Sqoop的运行机制?
4、你使用Sqoop是如何处理全量表和增量表的?具体实现可以详细说明一下吗?
5、同步你说的这些数据量用了大概多久时间?
Flume及Kafka方面
- 你这个项目如何传输日志文件的?
- 分别说一下你的两层传输。
- 为什么使用kafka?目的是什么?
- 你们的数据量是多少,kafka处理这些数据需要多久?
- 说说处理LZO你还知道哪些压缩格式。
- Flume中你为什么采用memory channel?考虑过其它的channel吗?
- 数据存入到HDFS下是怎样的一种状态,你要用这些数据做什么?
- 可能会问Flume和Kafka的原理,说一下Flume和Kafka的原理?Flume的扇形模式(多sink或者多channel模式),Kafka的patitiaon,topic,officeset等等,这些都需要了解,如果传输到一半,突然失败了,再传输时kafka会怎么做,从头来还是接着上次来,为什么会这样?kafka如何落盘的?
下章节传送门~~~~~~