文章目录
0 结果展示
scala上的运行结果:
在hadoop上查到文件:
在scala中查询HDFS中的结果:
1 连接kafak
在spatk上启动scala Shell:
其中比较重要的是kafaka包(spark-sql-kafka-0-10_2.11:2.4.8
)和Hudi包(org.apache.hudi:hudi-spark-bundle_2.11:0.8.0
)
常见的由于kafka包引起的错误:
创建Structured Streaming(用到了配置文件中config/kafka-source.properties
信息):
参数解析:
- startingOffsets:开始读取kafka中的offset的起始位置;
- endingOffsets:开始读取kafka中的offset的结束位置;
- latest:最新的offset位置;
- earliest:最早的offset位置;
- maxOffsetsPerTrigger:最大处理条数;
- failOnDataLoss:在流处理时,当数据丢失时(比如topic被删除了,offset在指定的范围之外),查询是否报错,默认为true
- includeTimestamp:是否添加时间戳
如果查询kafka中的所有结果,可以使用:
如果是要查询多个kafka主题,则传入的kafka的topic应该是"主题1,主题2,主题3",例如:val topic = "spjk21.test_hudi.test17.output,spjk21.test_hudi.test16,spjk21.test_hudi.test15,spjk21.test_hudi.test14"
注意⚠️:本文写入到hudi中用到的kafka主题中的内容是经过了数据处理后的kafaka数据。
原始的kafka数据:
转换后的kafka数据:
2 拆分kafka中json格式value为Dataframe
续前面的文件,使用schama拆分Dataframe的json为新的Dataframe(相当于用到了前面的Schame.avsc):
参数解析:
- Schema中用到的基本数据类型:
三个复合类型:
3 写入数据到Hudi
真正的获取kafak中数据,只有在运行writeStream时才会去查询数据。
参数解析:
- persist():spark对同一个RDD执行多次算法的默认原理为,每次对一个RDD执行一个算子操作时,都会重新从源头处计算一遍。如果某一部分的数据在程序中需要反复使用,这样会增加时间的消耗。为了改善这个问题,spark提供了一个数据持久化的操作,我们可通过persist()或cache()将需要反复使用的数据加载在内存或硬盘当中,以备后用。如果需要添加,则使用unpersist()方法。
- foreachBatch(…):允许指定一个函数,该函数对流式查询的每个微批次的输出数据执行。
- checkpointLocaion(必须拥有):设置一个checkpointLocaion,Structured Streaming就是在这个目录下来管理offset。如果程序中断之后再重启,虽然在读入流的时候设置的是某一个offset,但是在写入流的时候,如果已经存在了checkpointLocation,那么流会从之前中断的地方继续处理,即读入流对offset的设置只是针对checkpointLocation第一次初始化的时候有效。
- query.awaitTermination():执行后会等待任务的结束,如果结束会返回 True,如果过程中出现异常会抛出,可以设置 timeout 时长,设置后如果限定时长内没有等到任务结束,就返回 False。
4 完整代码
5 继续学习网站
- structured-streaming-programming-guide
- structured-streaming-kafka-integration
- hudi/hudi-utilities/src/main/java/org/apache/hudi/utilities/deltastreamer/HoodieDeltaStreamer.java