From 6ae4bc2a82b6275689523e2d169d5a583e85879c Mon Sep 17 00:00:00 2001 From: garyelephant Date: Tue, 2 Apr 2019 17:44:46 +0800 Subject: [PATCH 1/5] added case study for structured streaming --- docs/zh-cn/case_study/4.md | 3 +- docs/zh-cn/case_study/5.md | 282 ++++++++++++++++++++++++++++++ docs/zh-cn/case_study/_sidebar.md | 1 + 3 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 docs/zh-cn/case_study/5.md diff --git a/docs/zh-cn/case_study/4.md b/docs/zh-cn/case_study/4.md index 6637ec7e21f..bcb5ee24634 100644 --- a/docs/zh-cn/case_study/4.md +++ b/docs/zh-cn/case_study/4.md @@ -253,4 +253,5 @@ RickyHuo 微信: chodomatte1994 --- Power by [InterestingLab](https://github.com/InterestingLab) \ No newline at end of file +-- Power by [InterestingLab](https://github.com/InterestingLab) + diff --git a/docs/zh-cn/case_study/5.md b/docs/zh-cn/case_study/5.md new file mode 100644 index 00000000000..2098f30906e --- /dev/null +++ b/docs/zh-cn/case_study/5.md @@ -0,0 +1,282 @@ +## Waterdrop最近支持的StructuredStreaming怎么用? + +### 前言 + +StructuredStreaming是Spark 2.0以后新开放的一个模块,相比SparkStreaming,它有一些比较突出的优点:
  一、它能做到更低的延迟;
+  二、可以做实时的聚合,例如实时计算每天每个商品的销售总额;
+  三、可以做流与流之间的关联,例如计算广告的点击率,需要将广告的曝光记录和点击记录关联。
+以上几点如果使用SparkStreaming来实现可能会比较麻烦或者说是很难实现,但是使用StructuredStreaming实现起来会比较轻松。 +### 如何使用StructuredStreaming +可能你没有详细研究过StructuredStreaming,但是发现StructuredStreaming能很好的解决你的需求,如何快速利用StructuredStreaming来解决你的需求?目前社区有一款工具**Waterdrop**,项目地址:https://github.com/InterestingLab/waterdrop , +可以高效低成本的帮助你利用StructuredStreaming来完成你的需求。 + +### waterdrop + +Waterdrop是一个非常易用,高性能,能够应对海量数据的实时数据处理产品,它构建在Spark之上。Waterdrop拥有着非常丰富的插件,支持从Kafka、HDFS、Kudu中读取数据,进行各种各样的数据处理,并将结果写入ClickHouse、Elasticsearch或者Kafka中 + +### 准备工作 + +首先我们需要安装Waterdrop,安装十分简单,无需配置系统环境变量 + +1. 准备Spark环境 +2. 安装Waterdrop +3. 配置Waterdrop +以下是简易步骤,具体安装可以参照[Quick Start](https://interestinglab.github.io/waterdrop/#/zh-cn/quick-start) + +``` +cd /usr/local +wget https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz +tar -xvf https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz +wget https://github.com/InterestingLab/waterdrop/releases/download/v1.3.0/waterdrop-1.3.0.zip +unzip waterdrop-1.3.0.zip +cd waterdrop-1.3.0 + +vim config/waterdrop-env.sh +# 指定Spark安装路径 +SPARK_HOME=${SPARK_HOME:-/usr/local/spark-2.2.0-bin-hadoop2.7} +``` + +### Waterdrop Pipeline + +我们仅需要编写一个Waterdrop Pipeline的配置文件即可完成数据的导入。 + +配置文件包括四个部分,分别是Spark、Input、filter和Output。 + +#### Spark + +这一部分是Spark的相关配置,主要配置Spark执行时所需的资源大小。 + +``` +spark { + spark.app.name = "Waterdrop" + spark.executor.instances = 2 + spark.executor.cores = 1 + spark.executor.memory = "1g" +} +``` + +#### Input + +下面是一个从kafka读取数据的例子 + +``` +kafkaStream { + topics = "waterdrop" + consumer.bootstrap.servers = "localhost:9092" + schema = "{\"name\":\"string\",\"age\":\"integer\",\"addrs\":{\"country\":\"string\",\"city\":\"string\"}}" +} +``` + +通过上面的配置就可以读取kafka里的数据了 ,topics是要订阅的kafka的topic,同时订阅多个topic可以以逗号隔开,consumer.bootstrap.servers就是Kafka的服务器列表,schema是可选项,因为StructuredStreaming从kafka读取到的值(官方固定字段value)是binary类型的,详见http://spark.apache.org/docs/latest/structured-streaming-kafka-integration.html +但是如果你确定你kafka里的数据是json字符串的话,你可以指定schema,input插件将按照你指定的schema解析 + +#### Filter + +下面是一个简单的filter例子 + +``` +filter{ + sql{ + table_name = "student" + sql = "select name,age from student" + } +} +``` +`table_name`是注册成的临时表名,以便于在下面的sql使用 + +#### Output + +处理好的数据往外输出,假设我们的输出也是kafka + +``` +output{ + kafka { + topic = "waterdrop" + producer.bootstrap.servers = "localhost:9092" + streaming_output_mode = "update" + checkpointLocation = "/your/path" + } +} +``` + +`topic` 是你要输出的topic,` producer.bootstrap.servers`是kafka集群列表,`streaming_output_mode`是StructuredStreaming的一个输出模式参数,有三种类型`append|update|complete`,具体使用参见文档http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#output-modes + +`checkpointLocation`是StructuredStreaming的checkpoint路径,如果配置了的话,这个目录会存储程序的运行信息,比如程序退出再启动的话会接着上次的offset进行消费。 + +### 场景分析 + +以上就是一个简单的例子,接下来我们就来介绍的稍微复杂一些的业务场景 + +#### 场景一:实时聚合场景 + +假设现在有一个商城,上面有10种商品,现在需要实时求每天每种商品的销售额,甚至是求每种商品的购买人数(不要求十分精确)。 +这么做的巨大的优势就是海量数据可以在实时处理的时候,完成聚合,再也不需要先将数据写入数据仓库,再跑离线的定时任务进行聚合, +操作起来还是很方便的。 + +kafka的数据如下 + +``` +{"good_id":"abc","price":300,"user_id":123456,"time":1553216320} +``` + +那我们该怎么利用waterdrop来完成这个需求呢,当然还是只需要配置就好了。 + +``` +#spark里的配置根据业务需求配置 +spark { + spark.app.name = "Waterdrop" + spark.executor.instances = 2 + spark.executor.cores = 1 + spark.executor.memory = "1g" +} + +#配置input +input { + kafkaStream { + topics = "good_topic" + consumer.bootstrap.servers = "localhost:9092" + schema = "{\"good_id\":\"string\",\"price\":\"integer\",\"user_id\":\"Long\",\"time\":\"Long\"}" + } +} + +#配置filter +filter { + #如果需要设置watermark的话需要保证watermark的字段类型为timestamp + #这里之所以要把ts对其到天是因为求每天的销售额,如果是求每小时的销售额可以对其到小时 + sql { + table_name = "good_table" + sql = "select good_id,price,user_id,cast(from_unixtime(time,'yyyy-MM-dd') as timestamp) as ts from good_table" + } + + #这里表示使用ts字段设置watermark,界限为1天 + #设置watermark的作用是,在程序做聚合的时候,内部会去存储程序从启动开始的聚合状态,久而久之会导致OOM,如果设置了watermark,程序自动的会去清理watermark之外的状态 + Watermark { + event_time = "ts" + delay_threshold = "1 day" + } + + #之所以要group by ts是要让watermark生效,approx_count_distinct是一个估值,并不是精确的count_distinct + sql { + table_name = "good_table_2" + sql = "select good_id,sum(price) total, approx_count_distinct(user_id) person from good_table_2 group by ts,good_id" + } +} + +#接下来我们选择将结果实时输出到Kafka +output{ + kafka { + topic = "waterdrop" + producer.bootstrap.servers = "localhost:9092" + streaming_output_mode = "update" + checkpointLocation = "/your/path" + } +} + +``` +如上配置完成,启动waterdrop,就可以获取你想要的结果了。 + +#### 场景二:多个流关联场景 + +假设你在某个平台投放了广告,现在要实时计算出每个广告的CTR(点击率),数据分别来自两个topic,一个是广告曝光日志,一个是广告点击日志, +此时我们就需要把两个流数据关联到一起做计算,而Waterdrop 最近也支持了此功能,让我们一起看一下该怎么做: + + +点击topic数据格式 + +``` +{"ad_id":"abc","click_time":1553216320,"user_id":12345} + +``` + +曝光topic数据格式 + +``` +{"ad_id":"abc","show_time":1553216220,"user_id":12345} + +``` + +``` +#spark里的配置根据业务需求配置 +spark { + spark.app.name = "Waterdrop" + spark.executor.instances = 2 + spark.executor.cores = 1 + spark.executor.memory = "1g" +} + +#配置input +input { + #把要设置watermark的数据源放在第一个 + #左关联右表必须设置watermark + #右关左右表必须设置watermark + #http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#inner-joins-with-optional-watermarking + kafkaStream { + topics = "click_topic" + consumer.bootstrap.servers = "localhost:9092" + schema = "{\"ad_id\":\"string\",\"user_id\":\"Long\",\"click_time\":\"Long\"}" + table_name = "" + } + + kafkaStream { + topics = "show_topic" + consumer.bootstrap.servers = "localhost:9092" + schema = "{\"ad_id\":\"string\",\"user_id\":\"Long\",\"show_time\":\"Long\"}" + table_name = "show_table" + } +} + +filter { + + sql { + table_name = "click_table_2" + sql = "select ad_id,user_id,cast(from_unixtime(time) as timestamp) as ts from click_table_2" + } + + + Watermark { + event_time = "ts" + delay_threshold = "2 hour" + } + + #这样有一个弊端,就是左表的数据一直会被缓存在内存中,因为左表没有watermark + sql { + table_name = "click_table_3" + sql = "select a.ad_id,count(b.user_id)/count(a.user_id) ctr from show_table as a left join click_table_3 as b on a.ad_id = b.ad_id and a.user_id = b.user_id" + } + + #如果左表本来就有和数据时间戳统一的timestamp类型的时间字段,就可以使用如下的方式,避免以上的弊端 + #假设show_table也有一个字段为ts,并且是timestamp类型,如下可以使左表也就是show_table的watermark为1 hour + sql { + table_name = "click_table_3" + sql = "select a.ad_id,count(b.user_id)/count(a.user_id) ctr from show_table as a left join click_table_3 as b on a.ad_id = b.ad_id and a.user_id = b.user_id and b.ts >= b.ts and b.ts<= a.ts + interval 1 hour" + } + +} + +#接下来我们选择将结果实时输出到Kafka +output { + kafka { + topic = "waterdrop" + producer.bootstrap.servers = "localhost:9092" + streaming_output_mode = "update" + checkpointLocation = "/your/path" + } +} +``` + +通过配置,到这里流关联的案例也完成了。 + +### 结语 +通过配置能很快的利用StructuredStreaming做实时数据处理,但是还是需要对StructuredStreaming的一些概念了解,比如其中的watermark机制,还有程序的输出模式。 + +最后,waterdrop当然还支持spark streaming和spark 批处理。 +如果你对这两个也感兴趣的话,可以阅读我们以前发布的文章《[如何快速地将Hive中的数据导入ClickHouse](https://interestinglab.github.io/waterdrop/#/zh-cn/case_study/2)》、 +《[优秀的数据工程师,怎么用Spark在TiDB上做OLAP分析](https://interestinglab.github.io/waterdrop/#/zh-cn/case_study/4)》、 +《[如何使用Spark快速将数据写入Elasticsearch](https://interestinglab.github.io/waterdrop/#/zh-cn/case_study/3)》 + +希望了解 Waterdrop 和 HBase, ClickHouse、Elasticsearch、Kafka、MySQL 等数据源结合使用的更多功能和案例,可以直接进入项目主页 [https://github.com/InterestingLab/waterdrop](https://github.com/InterestingLab/waterdrop)或者联系项目负责人: + +> Garyelephan 微信: garyelephant + +> kid-xiong 微信: why20131019 + diff --git a/docs/zh-cn/case_study/_sidebar.md b/docs/zh-cn/case_study/_sidebar.md index a51a2e2f80f..3e2e599eaf3 100644 --- a/docs/zh-cn/case_study/_sidebar.md +++ b/docs/zh-cn/case_study/_sidebar.md @@ -9,6 +9,7 @@ - [如何快速地将Hive中的数据导入ClickHouse](/zh-cn/case_study/2.md) - [如何使用Spark快速将数据写入Elasticsearch](/zh-cn/case_study/3.md) - [优秀的数据工程师,怎么用Spark在TiDB上做OLAP分析](/zh-cn/case_study/4.md) + - [新功能StructuredStreaming怎么用?](/zh-cn/case_study/5.md) - [配置](/zh-cn/configuration/base) From 09327053993937dbf4f727c081b59b186adfbf28 Mon Sep 17 00:00:00 2001 From: garyelephant Date: Tue, 2 Apr 2019 18:03:24 +0800 Subject: [PATCH 2/5] added wechat qrcode --- docs/zh-cn/case_study/5.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/zh-cn/case_study/5.md b/docs/zh-cn/case_study/5.md index 2098f30906e..b98c66925ae 100644 --- a/docs/zh-cn/case_study/5.md +++ b/docs/zh-cn/case_study/5.md @@ -280,3 +280,9 @@ output { > kid-xiong 微信: why20131019 +> 扫微信二维码添加项目负责人为好友,拉你入Waterdrop 开发者/用户交流群: + + + + +
From 8385f28eca6cd7f822f16ffab0cfc5df04ec15ac Mon Sep 17 00:00:00 2001 From: garyelephant Date: Tue, 2 Apr 2019 18:04:48 +0800 Subject: [PATCH 3/5] added wechat qrcode --- docs/images/wechat-qrcode/garyelephant.jpeg | Bin 0 -> 22927 bytes docs/images/wechat-qrcode/kid-xiong.jpeg | Bin 0 -> 41114 bytes docs/images/wechat-qrcode/rickyhuo.jpeg | Bin 0 -> 39562 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/wechat-qrcode/garyelephant.jpeg create mode 100644 docs/images/wechat-qrcode/kid-xiong.jpeg create mode 100644 docs/images/wechat-qrcode/rickyhuo.jpeg diff --git a/docs/images/wechat-qrcode/garyelephant.jpeg b/docs/images/wechat-qrcode/garyelephant.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5facf042606c33401777bfdc27dc702d6b9bdf9d GIT binary patch literal 22927 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 fR*wIiFZJ?B_+%rNDEve&WHX1s}xRa literal 0 HcmV?d00001 diff --git a/docs/images/wechat-qrcode/rickyhuo.jpeg b/docs/images/wechat-qrcode/rickyhuo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..b2129ff6721f2ae915e9a6926b13a29af4cec493 GIT binary patch literal 39562 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 C--z%4 literal 0 HcmV?d00001 From bf917eb8c17f5bfe690aeaa050a2d589fe1bf163 Mon Sep 17 00:00:00 2001 From: kid-xiong Date: Wed, 10 Apr 2019 23:29:32 +0800 Subject: [PATCH 4/5] fix case 5 --- docs/zh-cn/case_study/5.md | 56 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/docs/zh-cn/case_study/5.md b/docs/zh-cn/case_study/5.md index b98c66925ae..33ecbb7f275 100644 --- a/docs/zh-cn/case_study/5.md +++ b/docs/zh-cn/case_study/5.md @@ -141,18 +141,16 @@ input { #配置filter filter { - #如果需要设置watermark的话需要保证watermark的字段类型为timestamp - #这里之所以要把ts对其到天是因为求每天的销售额,如果是求每小时的销售额可以对其到小时 - sql { - table_name = "good_table" - sql = "select good_id,price,user_id,cast(from_unixtime(time,'yyyy-MM-dd') as timestamp) as ts from good_table" - } + #在程序做聚合的时候,内部会去存储程序从启动开始的聚合状态,久而久之会导致OOM,如果设置了watermark,程序自动的会去清理watermark之外的状态 #这里表示使用ts字段设置watermark,界限为1天 - #设置watermark的作用是,在程序做聚合的时候,内部会去存储程序从启动开始的聚合状态,久而久之会导致OOM,如果设置了watermark,程序自动的会去清理watermark之外的状态 + Watermark { - event_time = "ts" + time_field = "time" + time_type = "UNIX" #UNIX表示时间字段为10为的时间戳,还有其他的类型详细可以查看插件文档 + time_pattern = "yyyy-MM-dd" #这里之所以要把ts对其到天是因为求每天的销售额,如果是求每小时的销售额可以对其到小时`yyyy-MM-dd HH` delay_threshold = "1 day" + watermark_field = "ts" #设置watermark之后会新增一个字段,`ts`就是这个字段的名字 } #之所以要group by ts是要让watermark生效,approx_count_distinct是一个估值,并不是精确的count_distinct @@ -206,15 +204,12 @@ spark { #配置input input { - #把要设置watermark的数据源放在第一个 - #左关联右表必须设置watermark - #右关左右表必须设置watermark - #http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#inner-joins-with-optional-watermarking + kafkaStream { topics = "click_topic" consumer.bootstrap.servers = "localhost:9092" schema = "{\"ad_id\":\"string\",\"user_id\":\"Long\",\"click_time\":\"Long\"}" - table_name = "" + table_name = "click_table" } kafkaStream { @@ -227,28 +222,31 @@ input { filter { - sql { - table_name = "click_table_2" - sql = "select ad_id,user_id,cast(from_unixtime(time) as timestamp) as ts from click_table_2" + #左关联右表必须设置watermark + #右关左右表必须设置watermark + #http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#inner-joins-with-optional-watermarking + Watermark { + source_table_name = "click_table" #这里可以指定为某个临时表添加watermark,不指定的话就是为input中的第一个 + time_field = "time" + time_type = "UNIX" + delay_threshold = "3 hours" + watermark_field = "ts" + result_table_name = "click_table_watermark" #添加完watermark之后可以注册成临时表,方便后续在sql中使用 } - Watermark { - event_time = "ts" - delay_threshold = "2 hour" - } + source_table_name = "show_table" + time_field = "time" + time_type = "UNIX" + delay_threshold = "2 hours" + watermark_field = "ts" + result_table_name = "show_table_watermark" + } - #这样有一个弊端,就是左表的数据一直会被缓存在内存中,因为左表没有watermark - sql { - table_name = "click_table_3" - sql = "select a.ad_id,count(b.user_id)/count(a.user_id) ctr from show_table as a left join click_table_3 as b on a.ad_id = b.ad_id and a.user_id = b.user_id" - } - #如果左表本来就有和数据时间戳统一的timestamp类型的时间字段,就可以使用如下的方式,避免以上的弊端 - #假设show_table也有一个字段为ts,并且是timestamp类型,如下可以使左表也就是show_table的watermark为1 hour sql { - table_name = "click_table_3" - sql = "select a.ad_id,count(b.user_id)/count(a.user_id) ctr from show_table as a left join click_table_3 as b on a.ad_id = b.ad_id and a.user_id = b.user_id and b.ts >= b.ts and b.ts<= a.ts + interval 1 hour" + table_name = "show_table_watermark" + sql = "select a.ad_id,count(b.user_id)/count(a.user_id) ctr from show_table_watermark as a left join click_table_watermark as b on a.ad_id = b.ad_id and a.user_id = b.user_id " } } From 9420a070313046f24b25268ac2d6a59778f2f7aa Mon Sep 17 00:00:00 2001 From: kid-xiong Date: Wed, 10 Apr 2019 23:30:12 +0800 Subject: [PATCH 5/5] fix case 5 --- docs/zh-cn/case_study/5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-cn/case_study/5.md b/docs/zh-cn/case_study/5.md index 33ecbb7f275..e3586877e89 100644 --- a/docs/zh-cn/case_study/5.md +++ b/docs/zh-cn/case_study/5.md @@ -256,7 +256,7 @@ output { kafka { topic = "waterdrop" producer.bootstrap.servers = "localhost:9092" - streaming_output_mode = "update" + streaming_output_mode = "append" #流关联只支持append模式 checkpointLocation = "/your/path" } }