在本练习中,您将学习如何使用 Amazon EMR(Spark)和 AWS Glue(ETL)构建批量数据分析处理程序。为了使本实验的练习更加贴近实际的业务场景,我们模拟了完整的从数据产生(模拟历史数据和流数据)、数据存储、数据处理、到数据分析和数据可视化的完整过程(数据可视化在 Lab3/Lab4 中完成)。
具体可参考如下架构图:
![image-20210319163459801](https://i-blog.csdnimg.cn/blog_migrate/cdb4c6570546b970dfb10d3401313f04.png)
组件说明如下:
• RDS 作为 Lab2 次实验的历史数据源,RMDBS 格式,包含人员信息表 tbl_customer、产品信息表 tbl_product、地址信息表 tbl_address、交易历史流水表 tbl_transaction,等 4 张表,参与批处理计算;
• Lab1 实验中 Kinesis 的输出(存放在 Lab1 指定的 S3 文件夹中,Json 格式),为近实时当日交易流水,也可以作为 Lab2 批处理的输入,参与批处理计算(注意:学员可以考虑使用 Lab1 的输出数据或者使用我们提前准备好的数据);
• S3 桶作为数据湖的存储基础,包含 input 文件夹(用于 EMR Spark 批处理的输入),存放通过 Glue ETL 加载进来的 RDS 历史数据源和 Kinesis 当日近实时数据,以 Parquet 格式存放。output 文件夹,存放 EMR Spark 批处理的结果数据(Parquet 格式);
详细的数据流步骤说明如下:
![image-20210319163529102](https://i-blog.csdnimg.cn/blog_migrate/6b7bbbe5435e9c5710cea9bb6461c27d.png)
具体说明如下:
1.1 通过 Glue Crawler 功能爬取 RDS 库中 4 张表的元数据和 Kinesis 输出的数据的元数据;
1.2 Glue Crawler 将爬取 RDS和 Kinesis 的元数据,存入到 Glue 的 Data Catalog 数据库;
1.3 Glue ETL 通过 Data Catalog 识别 RDS 表元数据和 Kinesis 元数据,以便 ETL 作业引用;
1.4 Glue ETL 加载 4 张表数据和 Kinesis 输出的数据,到指定的 S3 存储桶的 input 文件夹中,作为 Spark 批处理的数据源输入;
1.5 通过 Glue Crawler 功能爬取 S3 桶中 input 文件夹中数据的元数据;
1.6 Glue Crawler 将爬取 input 文件夹中数据的元数据,存入 Glue 的 Data Catalog 数据库;
1.7 EMR Spark 环境通过 Data Catalog 获取 input 文件夹的元数据,进而开展批处理作业;
1.8 将 EMR Spark 批处理作业的结果输出至指定的 S3 存储桶的 output 文件夹中;
1.9 通过 Glue Crawler 功能爬取 S3 桶中 output 文件夹中数据的元数据;
2.0 Glue Crawler 将爬取 output 文件夹中数据的元数据,存入 Glue 的 Data Catalog 数据库;
2.1 利用 Athena 服务,查询 input、output 数据;
其中步骤 1.9/2.0/2.1 和 Lab3 有重叠,所以在此处不做演示或说明。
数据处理(ETL)
本实验演示数据处理的过程(ETL过程,此处我们使用AWS Glue服务),数据分析在下个章节。
连接到RDS
登录并打开AWS Glue控制台,选择添加数据库连接:
![image-20210319164543410](https://i-blog.csdnimg.cn/blog_migrate/6d1f80a96d9e7e83e1ccc6601d1e69f3.png)
设置连接名称(Lab2-Glue-RDS-connection
)和类型
![image-20210319164629186](https://i-blog.csdnimg.cn/blog_migrate/d60e1e5269a420923217bda01ad2769f.png)
选择对应配置(请输入之前部署 rds 时admin
的密码,此处为wzlinux2021
)
![image-20210319164725742](https://i-blog.csdnimg.cn/blog_migrate/162297d27e1f65430b168365b3c096b2.png)
当连接中使用的安全组入站规则中没有添加自引用规则会生成错误"unable to find suitable security group error"。为了解决该问题,您需要添加一个自引用规则,以允许 AWS Glue 组件进行通信。具体来讲,添加或确认有一条类型为 All TCP 的规则,协议为 TCP,端口范围包括所有端口,其源具有与组 ID相同的安全组名。
- 从RDS控制台中选择要从 AWS Glue 访问的 Amazon RDS Engine (引擎) 和 DB Instance (数据库实例) 名称。
- 选择查看详细信息。在 Details (详细信息) 选项卡上,查找要从 AWS Glue 访问的 Security Groups (安全组) 名称。记录下该安全组的名称以供将来参考。
- 选择安全组以打开 Amazon EC2 控制台。
- 确认已选择来自 Amazon RDS 的 Group ID (组 ID),然后选择 Inbound (入站) 选项卡。
- 添加一个自引用规则,以允许 AWS Glue 组件进行通信。具体来讲,添加或确认有一条类型为 All TCP 的规则,协议为 TCP,端口范围包括所有端口,其源具有与组 ID相同的安全组名。
![image-20210319165407328](https://i-blog.csdnimg.cn/blog_migrate/eee78404612583c9e9c84461cb5df1b0.png)
这时候告警就消失了,我们可以进行连接了
![image-20210319165438766](https://i-blog.csdnimg.cn/blog_migrate/7fdbcd529dcfcdd5b9999ce12c795c19.png)
审核并完成,然后开始连接测试,测试时需要使用第一步创建的 role(这是在准备阶段创建的 IAM 角色 glue-role
)
![image-20210319165716435](https://i-blog.csdnimg.cn/blog_migrate/d47cdd88b666de8599e8d5ccceab50ee.png)
需要1-2分钟的时间,略微等待即可
![image-20210319170543451](https://i-blog.csdnimg.cn/blog_migrate/2b2ab27ff2504253978a046867762f22.png)
爬取RDS元数据
创建名为my-lab2-crawler-rds
的爬网程序,设置爬网程序名称
![image-20210319170644332](https://i-blog.csdnimg.cn/blog_migrate/a098e8493ae991058fc04b9355e4b2a2.png)
配置对应参数(包含路径那里输入:bdd/%
)
![image-20210319170754291](https://i-blog.csdnimg.cn/blog_migrate/3e67a1b62a8954e574922e079ac5e905.png)
选择对应的 role
![image-20210319170837648](https://i-blog.csdnimg.cn/blog_migrate/cfdbfa21b05d1636c9b66237e4ed8b6d.png)
配置输出(点击添加数据库,名字为default
即可)
![image-20210319170942505](https://i-blog.csdnimg.cn/blog_migrate/02c1b666d9766c66a42fe3af7c825ba4.png)
完成后,运行爬网程序,爬取成功后,元数据目录中会出现 4 张 RDS 元数据表
![image-20210319171610101](https://i-blog.csdnimg.cn/blog_migrate/73c3f2ac768ce2dda99336c8cc17f6e5.png)
爬取kinesis输出的元数据
创建名为my-lab2-crawler-kinesis
的爬网程序
![image-20210319171122126](https://i-blog.csdnimg.cn/blog_migrate/8379b4f35b28b1e2562ac3efd6f08b6f.png)
添加数据存储(此处选择Lab1的输出)
![image-20210319171257478](https://i-blog.csdnimg.cn/blog_migrate/14e730cb0e8b0e3eba51f8e3ff28f7e8.png)
选择对应的role
![image-20210319171328496](https://i-blog.csdnimg.cn/blog_migrate/0a61b0b21ce74794c65d38e31a5d0bb0.png)
配置输出
![image-20210319171358996](https://i-blog.csdnimg.cn/blog_migrate/f30fca742e1637ceae789aa91aece5e9.png)
完成后,运行爬网程序,元数据目录中会出现 1 张 Kinesis 元数据表
![image-20210319171647871](https://i-blog.csdnimg.cn/blog_migrate/78adbff13631ccaca138ef717b0355bf.png)
合并rds和kinesis的数据输出到s3
此处需要一个作业处理脚本
https://imgs.wzlinux.com/aws/glue-to-s3.glue
把这个脚本上传到 S3 桶内,例如
![image-20210319172053683](https://i-blog.csdnimg.cn/blog_migrate/ac13a6078fc2d793b96eeb4f498514d9.png)
创建 ETL 作业
![image-20210319172136368](https://i-blog.csdnimg.cn/blog_migrate/25175c056474c1a482ab659e84208ed6.png)
配置作业属性
![image-20210319172333296](https://i-blog.csdnimg.cn/blog_migrate/1bb6783f9639b48febc4dd2405c2c62f.png)
选择对应连接,然后选择“保存作业并编辑脚本”
![image-20210319172418799](https://i-blog.csdnimg.cn/blog_migrate/94ca0a3a89fdb93498300862f06037f1.png)
确认表名和输出位置的桶名是否正确,参考下图(一定要确认爬虫爬取出来的表名和S3桶名字的正确性)
![image-20210319172637313](https://i-blog.csdnimg.cn/blog_migrate/59d4fa865bae3c06592e9c9696a916b6.png)
作业运行中(根据数据量不同,所需时间略有不同),考虑到 Kinesis Data Streams 在不停的打进来数据,所以每次跑 EMR 任务之前,这个都需要运行一次,否则数据就不是最新的,可以考虑按某个时间间隔(例如天)运行一次
![image-20210319172751573](https://i-blog.csdnimg.cn/blog_migrate/2d00593ba3171f0c0a52c8e3f2a244de.png)
作业运行完成后,可检查s3://lab-921283538843-wzlinux-com/spark/input/
目录下的"tbl_customer、tbl_product、tbl_address、tbl_transaction"文件夹中,是否产生对应的parquet格式的数据,以验证 ETL 作业是否执行成功。
![image-20210319172939635](https://i-blog.csdnimg.cn/blog_migrate/9aaa1868636beebd7f5f2fe8514f07fa.png)
爬取合并在S3上的输出的元数据
创建名为my-lab2-crawler-s3
的爬网程序
![image-20210319173028841](https://i-blog.csdnimg.cn/blog_migrate/faaf35d5e0c302ed5b8be9fff1c282e7.png)
配置存储的包含路径为前一个任务的输出地(此处为:s3://lab-921283538843-wzlinux-com/spark/input
)
![image-20210319173144618](https://i-blog.csdnimg.cn/blog_migrate/60e30c9b9a97d63a5adb54b9221b8554.png)
配置 IAM 角色
![image-20210319173217061](https://i-blog.csdnimg.cn/blog_migrate/55152a605ac524464cf83a01f491245b.png)
配置输出
![image-20210319173243236](https://i-blog.csdnimg.cn/blog_migrate/184573fd25de8fb7f33d0f7c37acdbc0.png)
审核并确认完成。然后运行爬网程序,元数据目录中会出现 4 张 input 文件夹中数据的元数据表
![image-20210319173452812](https://i-blog.csdnimg.cn/blog_migrate/12b87e3ed6f74e938c2ec951b92d61b7.png)
现在我们合并了历史数据,有了不断输入的流数据(如果需要实时的流数据结果,需要运行一遍上面的作业),接下来就可以开始下一步的分析数据了。
数据分析(EMR)
本实验演示数据分析的过程(Spark),数据处理(ETL)在上个章节。
登录EMR Master
如果按照实验准备的环节部署的 EMR 集群,是可以直接远程登录 Master 节点的,不过需要放开 Master 节点的 22 端口。
打开控制台关于安全组的页面(可以从VPC控制台或者EC2控制台进入),修改Master相关的安全组(此处为:sg-0b1fb24e11bcf2c16 - ElasticMapReduce-master
),编辑它的入站规则,添加22端口许可,然后保存即可(其他的不要动)
![image-20210319174940214](https://i-blog.csdnimg.cn/blog_migrate/11f446384755aecbb5e3b1018759586c.png)
确认EMR集群状态时绿色状态,点击“Connect to the Master Node Using SSH”
![image-20210319175037273](https://i-blog.csdnimg.cn/blog_migrate/f39d821f5b72a5951839e848618bce8f.png)
登录后如下图所示
![image-20210319175152350](https://i-blog.csdnimg.cn/blog_migrate/2824d0209cd41aee809f8cf86eacf344.png)
提交任务
提交任务的方式有两种,一种是 spark-shell 的方式,一种是 spark-submit 的方式。
用 spark-shell 提交
登录 Master 节点后,输入 spark-shell 命令,启动 spark-shell 环境,使用如下代码生成聚合数据集(注意检查表名称必须一致,且复制的时候别出现换行的问题–这个在 windows 下的记事本最容易出现)
val result = spark.sql("SELECT tt.tno tno, tt.tdate tdate, tt.uno uno, tt.pno pno, tt.tnum tnum, tc.uname uname, tc.umobile umobile, ta.ano ano, ta.acity acity, ta.aname aname, tp.pclass pclass, tp.pname pname, tp.pprice price FROM s3_tbl_transaction tt, s3_tbl_customer tc, s3_tbl_address ta, s3_tbl_product tp WHERE tp.pno = tt.pno and tt.uno = tc.uno and tc.ano = ta.ano ORDER BY tt.tuptime desc");
然后查询 schema 是否符合我们预期
result.printSchema();
![image-20210319181406570](https://i-blog.csdnimg.cn/blog_migrate/7c4cb5dab5b4c55f55140f403e853313.png)
接下来把结果输出到S3即可(注意S3桶的名称)
result.write.format("parquet").mode("append").save("s3://lab-921283538843-wzlinux-com/spark/output");
去对应S3目录(s3://lab-921283538843-wzlinux-com/spark/output
)查看是否正常输出结果(这些结果会在Lab3里面用到)。
![image-20210319181646262](https://i-blog.csdnimg.cn/blog_migrate/f492cb20bde1365c3405269219932f0a.png)
用spark-submit提交(可选)
我们已经准备好java实验代码,可以从这里下载并上传到S3上(例如上传保存在s3://921283538843-wzlinux-com/code/spark/
)
https://imgs.wzlinux.com/aws/original-emr-0.0.1-SNAPSHOT.jar
登录Master节点后,输入spark-submit 提价任务(注意,为了不和上面 spark-shell 提交的任务冲突,我们把这个任务的结果保存到 output2 目录下了,如果哪个同学还处于上一步的spark-shell
环境中,记得退出到 shell 环境中)
spark-submit --master yarn --deploy-mode client --class com.demo.emr.spark.Lab2 s3://lab-921283538843-wzlinux-com/code/spark/original-emr-0.0.1-SNAPSHOT.jar s3://lab-921283538843-wzlinux-com/spark/output2
如果在此期间没有去重复执行 glue 的合并数据的作业的话,这个输出结果跟上面的结果是一致的
![image-20210319182307048](https://i-blog.csdnimg.cn/blog_migrate/985b93fe337ee72b157f471a94b7b29c.png)
至此,批量处理数据的实验我们也已经完成了。
欢迎大家扫码关注,获取更多信息
![AWS 大数据实战 Lab2 - 批量数据处理(三)](https://i-blog.csdnimg.cn/blog_migrate/4a4647e164dfb226f4d0b286ecf430c4.jpeg)