云计算与大数据期末项目 电商大数据离线计算

简介: 云计算与大数据期末项目 电商大数据离线计算

一、项目介绍

       电子商务中会产生海量的数据,蕴含着不可估量的数据价值,可通过数据分析来挖掘这些潜在价值,以提升平台的销量。本次实践项目利用 Hadoop 的分布式计算框架 MapReduce 来分析用户行为数据,计算得出商品点击排行、商品分类占比等统计指标,使得更加熟练掌握 MapReduce 程序的设计。

       相关理论知识有,Map 和 Reduce 流程图如下:输入数据(INPUT)首先分割(SPLIT)成若干份,然后每份分别进行 MAP 过程;中间再经过 COMBINE 任务(可选)和 PARTTION 对 MAP 所得的结果进行聚合——把同 key 的结果放到同一组,最后再进行 REDUCE 过程。

二、项目内容

电商大数据离线计算,主要有六个部分,分别为:

第1部分:统计用户流失情况;

第2部分:统计所有商品点击量排行;

第3部分:统计各个商品类别中点击量最高的商品;

第4部分:统计五种商品类别占比;

第5部分:统计各类商品种类的购买次数;

第6部分:统计五类商品中各自点击量最高的商品的购买次数。

三、功能模块

四、功能分析

统计用户流失情况:就是统计出用户4种不同用户行为的数量,即点击浏览(pv)的数量,购买(buy)的数量等。

统计所有商品点击量排行:即统计出每个商品id中用户行为是pv(点击浏览)的数量,reduce的输出最后是按点击量的大小从大到小排序

统计各个商品类别中点击量最高的商品:根据用户行为数据,编写 MapReduce 程序来统计各个商品类别中点击量最高的商品。

统计五种商品类别占比:根据用户行为数据,编写 MapReduce 程序来统计出五种商品分类占比数据。

统计出各个商品类别的数量,在把一个商品类别的数量除以所有商品类别的数量即可得到该商品类别的占比。

统计各类商品种类的购买次数:根据用户行为数据,编写 MapReduce 程序来统计出各类商品种类的购买次数。

统计五类商品中各自点击量最高的商品的购买次数:根据用户行为数据,编写 MapReduce 程序来统计出五类商品中各自点击量最高的商品的购买次数。

五、项目步骤

(一)统计用户流失情况

1、项目需求分析及任务

任务:就是统计出用户4种不同用户行为的数量,即点击浏览(pv)的数量,购买(buy)的数量等。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式

buy,总数

cart,总数

fav,总数

pv,总数

2、技术方法

这是编程中用到的电商数据数据,为 CSV 格式,文件名user_behavior.csv,大小9948行,每一行数据(4列)分别表示: 用户id, 商品id, 商品类别, 用户行为;商品类别有 手机、平板电脑、笔记本、智能手表、耳机,总共5大类别;用户行为中pv代表点击浏览,cart代表加入购物车,fav代表添加到喜欢,buy代表购买。

用户流失情况就是统计出用户4种不同用户行为的数量,即点击浏览(pv)的数量,购买(buy)的数量等。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, IntWritable> {
2. 2. 
3. 3.         //私有变量1,可重复使用
4. 4.         private static IntWritable one = new IntWritable(1);
5. 5. 
6. 6.         @Override
7. 7.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
8. 8. 
9. 9.             /*** 在这编写map内容 ****/
10. 10.             /********** Begin **********/
11. 11.             //分割每行数据
12. 12.             String[] atts = value.toString().split(",");
13. 13.             //得到行为属性
14. 14.             String behavior = atts[3];
15. 15.             //行为属性作key,1作value的map输出
16. 16.             context.write(new Text(behavior), one);
17. 17. 
18. 18.             /********** End **********/
19. 19.         }
20. 20.     }
21. 21. 
22. 22.     public static class ThisReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
23. 23. 
24. 24.         @Override
25. 25.         protected void reduce(Text key, Iterable<IntWritable> values, Context context)
26. 26.                 throws IOException, InterruptedException {
27. 27. 
28. 28.             /*** 在这编写reduce内容 ****/
29. 29.             /********** Begin **********/
30. 30.             //统计同key的values总数
31. 31.             int sum = 0;
32. 32.             for(IntWritable one : values){
33. 33.                 sum += one.get();
34. 34.             }
35. 35.             //写入到reduce输出
36. 36.             context.write(key, new IntWritable(sum));
37. 37. 
38. 38.             /********** End **********/
39. 39.         }
40. 40.     }

(二)统计所有商品点击量排行

1、项目需求分析及任务

任务:即统计出每个商品id中用户行为是pv(点击浏览)的数量,reduce的输出最后是按点击量的大小从大到小排序。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式(按点击量从大到小):

商品id,点击量

商品id,点击量

···

2、技术方法

cleanup()方法

编程中可能会用到 cleanup() 方法,cleanup 方法是 mapper/reduce 对象执行完所有的 map/reduce 方法之后最后执行的方法,可用于清理资源释放或清理工作;默认继承的父类方法为空。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, IntWritable> {
2. 2. 
3. 3.         private static IntWritable one = new IntWritable(1);
4. 4. 
5. 5.         @Override
6. 6.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
7. 7. 
8. 8.             /*** 在这编写map内容 ****/
9. 9.             /********** Begin **********/
10. 10.             //1. 分割每行数据
11. 11.             String[] atts = value.toString().split(",");
12. 12.             //2. 得到商品id
13. 13.             String item = atts[1];
14. 14.             //3. 得到行为属性
15. 15.             String behavior = atts[3];
16. 16.             //4. 如果行为属性是 'pv',则写入到map输出
17. 17.             if (behavior.equals("pv")) {
18. 18.                 context.write(new Text(item), one);
19. 19.             }
20. 20. 
21. 21.             /********** End **********/
22. 22. 
23. 23.         }
24. 24.     }
25. 25. 
26. 26.     public static class ThisReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
27. 27. 
28. 28.         //对象实例,用来保存reduce方法中处理的数据
29. 29.         List<Object[]> list = new LinkedList<>();
30. 30. 
31. 31.         @Override
32. 32.         protected void reduce(Text key, Iterable<IntWritable> values, Context context)
33. 33.                 throws IOException, InterruptedException {
34. 34.             /*** 在这编写reduce内容 ****/
35. 35.             /********** Begin **********/
36. 36.             // 统计同key总数, 把key和sum写入到list中
37. 37.             int sum = 0;
38. 38.             for (IntWritable one : values) {
39. 39.                 sum += one.get();
40. 40.             }
41. 41.             list.add(new Object[] { key.toString(), Integer.valueOf(sum) });
42. 42. 
43. 43.             /********** End **********/
44. 44.         }
45. 45. 
46. 46. 
47. 47. 
48. 48.         //cleanup方法,即reduce对象执行完所有的reduce方法后最后执行的方法
49. 49.         @Override
50. 50.         protected void cleanup(Reducer<Text, IntWritable, Text, IntWritable>.Context context)
51. 51.                 throws IOException, InterruptedException {
52. 52. 
53. 53.             // 按照sum的大小对list进行排序,得到的结果是从小到大
54. 54.             list = list.stream().sorted((o1, o2) -> { return ((int)o1[1] - (int)o2[1]);}).collect(Collectors.toList());
55. 55.             // 从后向前遍历,即从大到小
56. 56.             for(int i=list.size()-1; i>=0; i--){
57. 57.                 Object[] o = list.get(i);
58. 58.                 //写入到reduce输出
59. 59.                 context.write(new Text((String) o[0]), new IntWritable((int) o[1]));
60. 60.             }
61. 61.         }
62. 62.     }

(三)统计各个商品类别中点击量最高的商品

1、项目需求分析及任务

任务:根据用户行为数据,编写 MapReduce 程序来统计各个商品类别中点击量最高的商品。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式

商品类型,点击量最高的商品id

商品类型,点击量最高的商品id

2、技术方法

这是编程中用到的电商数据数据,为 CSV 格式,文件名user_behavior.csv,大小9948行,每一行数据(4列)分别表示: 用户id, 商品id, 商品类别, 用户行为;商品类别有 手机、平板电脑、笔记本、智能手表、耳机,总共5大类别;用户行为中pv代表点击浏览,cart代表加入购物车,fav代表添加到喜欢,buy代表购买。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, Text> {
2. 2. 
3. 3.         @Override
4. 4.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
5. 5. 
6. 6.             /*** 在这编写map内容 ****/
7. 7.             /********** Begin **********/
8. 8.             // 作用跟前几关一样,不再描述
9. 9.             String[] atts = value.toString().split(",");
10. 10.             String item = atts[1];
11. 11.             String type = atts[2];
12. 12.             String behavior = atts[3];
13. 13.             if (behavior.equals("pv")) {
14. 14.                 context.write(new Text(type), new Text(item));
15. 15.             }
16. 16.             /********** End **********/
17. 17. 
18. 18.         }
19. 19.     }
20. 20. 
21. 21.     public static class ThisReduce extends Reducer<Text, Text, Text, Text> {
22. 22. 
23. 23.         @Override
24. 24.         protected void reduce(Text key, Iterable<Text> values, Context context)
25. 25.                 throws IOException, InterruptedException {
26. 26. 
27. 27.             /*** 在这编写reduce内容 ****/
28. 28.             /********** Begin **********/
29. 29. 
30. 30.             // 提示: 先得出所有商品id的数量,再从这些数量中找出最大值
31. 31. 
32. 32.             // 1. 一个map,用来保存各个商品id的数量
33. 33.             Map<String, Integer> map = new HashMap<>();
34. 34.             // 2. 统计values中各个value的数量
35. 35.             for (Text value : values) {
36. 36.                 String item = value.toString();
37. 37.                 Integer count = !map.containsKey(item) ? 1 : map.get(item) + 1;
38. 38.                 map.put(item, count);
39. 39.             }
40. 40.             // 3. 找出map中value最大的键值对
41. 41.             Map.Entry<String, Integer> itemMax = Collections.max(map.entrySet(), (entry1, entry2) -> {
42. 42.                 return entry1.getValue() - entry2.getValue();
43. 43.             });
44. 44.             // 4. 结果写入reduce输出
45. 45.             context.write(key, new Text(itemMax.getKey()));
46. 46. 
47. 47.             /********** End **********/
48. 48.         }
49. 49. 
50. 50.     }

(四)统计五种商品类别占比

1、项目需求分析及任务

任务:根据用户行为数据,编写 MapReduce 程序来统计出五种商品分类占比数据。统计出各个商品类别的数量,在把一个商品类别的数量除以所有商品类别的数量即可得到该商品类别的占比。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式:

商品类别,占总数比例

商品类别,占总数比例

···

2、技术方法

cleanup()方法

编程中可能会用到 cleanup() 方法,cleanup 方法是 mapper/reduce 对象执行完所有的 map/reduce 方法之后最后执行的方法,可用于清理资源释放或清理工作;默认继承的父类方法为空。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, IntWritable> {
2. 2. 
3. 3.         private static IntWritable one = new IntWritable(1);
4. 4. 
5. 5.         @Override
6. 6.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
7. 7.             /*** 在这编写map内容 ****/
8. 8.             /********** Begin **********/
9. 9. 
10. 10.             String[] atts = value.toString().split(",");
11. 11.             String type = atts[2];
12. 12.             context.write(new Text(type), one);
13. 13. 
14. 14.             /********** End **********/
15. 15.         }
16. 16.     }
17. 17. 
18. 18.     public static class ThisReduce extends Reducer<Text, IntWritable, Text, DoubleWritable> {
19. 19. 
20. 20.         // 保存reduce方法的处理结果
21. 21.         Map<String,Integer> map = new HashMap<>();
22. 22. 
23. 23.         @Override
24. 24.         protected void reduce(Text key, Iterable<IntWritable> values, Context context)
25. 25.                 throws IOException, InterruptedException {
26. 26.             /*** 在这编写reduce内容 ****/
27. 27.             /********** Begin **********/
28. 28.             int count = 0;
29. 29.             for (IntWritable one : values) {
30. 30.                 count += one.get();
31. 31.             }
32. 32.             map.put(key.toString(), count);
33. 33.             /********** End **********/
34. 34. 
35. 35. 
36. 36.         }
37. 37. 
38. 38.         // 需要重写 cleanup方法
39. 39.         @Override
40. 40.         protected void cleanup(Reducer<Text, IntWritable, Text, DoubleWritable>.Context context)
41. 41.                 throws IOException, InterruptedException {
42. 42. 
43. 43.             // 得到所有商品类别数量的总和
44. 44.             int sum = 0;
45. 45.             for (int v : map.values()) {
46. 46.                 sum += v;
47. 47.             }
48. 48.             // 得出每个商品类别的占比
49. 49.             for (String key : map.keySet()) {
50. 50.                 int value = map.get(key);
51. 51.                 double ratio = ((double) value) / sum;
52. 52.                 context.write(new Text(key), new DoubleWritable(ratio));
53. 53.             }
54. 54.         }
55. 55. 
56. 56.     }

(五)统计各类商品种类的购买次数

1、项目需求分析及任务

任务:根据用户行为数据,编写 MapReduce 程序来统计出各类商品种类的购买次数。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式:

商品类型,购买次数

商品类型,购买次数

···

2、技术方法

这是编程中用到的电商数据数据,为 CSV 格式,文件名user_behavior.csv,大小9948行,每一行数据(4列)分别表示: 用户id, 商品id, 商品类别, 用户行为;商品类别有 手机、平板电脑、笔记本、智能手表、耳机,总共5大类别;用户行为中pv代表点击浏览,cart代表加入购物车,fav代表添加到喜欢,buy代表购买。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, IntWritable> {
2. 2. 
3. 3.         private static IntWritable one = new IntWritable(1);
4. 4. 
5. 5.         @Override
6. 6.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
7. 7.             /*** 在这编写map内容 ****/
8. 8.             /********** Begin **********/
9. 9.             String[] atts = value.toString().split(",");
10. 10.             String type = atts[2];
11. 11.             if (atts[3].equals("buy")) {
12. 12.                 context.write(new Text(type), one);
13. 13.             }
14. 14.             /********** End **********/
15. 15. 
16. 16.         }
17. 17.     }
18. 18. 
19. 19.     public static class ThisReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
20. 20. 
21. 21.         @Override
22. 22.         protected void reduce(Text key, Iterable<IntWritable> values, Context context)
23. 23.                 throws IOException, InterruptedException {
24. 24. 
25. 25.             /*** 在这编写reduce内容 ****/
26. 26.             /********** Begin **********/
27. 27.             int count = 0;
28. 28.             for (IntWritable one : values) {
29. 29.                 count += one.get();
30. 30.             }
31. 31.             context.write(key, new IntWritable(count));
32. 32.             /********** End **********/
33. 33. 
34. 34.         }
35. 35.     }

(六)统计五类商品中各自点击量最高的商品的购买次数

1、项目需求分析及任务

任务:根据用户行为数据,编写 MapReduce 程序来统计出五类商品中各自点击量最高的商品的购买次数。

编程要求:

main 方法已给出,其中 Job 和输入输出路径已配置完成,无需更改,

map 和 reduce 的输入输出 key、value 已给出。

预期输出格式:

商品类型,本类型中点击量最高的id,购买次数

商品类型,本类型中点击量最高的id,购买次数

···

2、技术方法

这是编程中用到的电商数据数据,为 CSV 格式,文件名user_behavior.csv,大小9948行,每一行数据(4列)分别表示: 用户id, 商品id, 商品类别, 用户行为;商品类别有 手机、平板电脑、笔记本、智能手表、耳机,总共5大类别;用户行为中pv代表点击浏览,cart代表加入购物车,fav代表添加到喜欢,buy代表购买。

3、部分截图与相关代码

1. 1.     public static class ThisMap extends Mapper<Object, Text, Text, Text> {
2. 2. 
3. 3.         @Override
4. 4.         protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
5. 5.             /*** 在这编写map内容 ****/
6. 6.             /********** Begin **********/
7. 7.             String[] atts = value.toString().split(",");
8. 8.             String type = atts[2];
9. 9.             //把value作为map的输出值,因为到时还需要用到一些属性
10. 10.             context.write(new Text(type), value);
11. 11.             /********** End **********/
12. 12. 
13. 13.         }
14. 14.     }
15. 15. 
16. 16.     public static class ThisReduce extends Reducer<Text, Text, Text, Text> {
17. 17. 
18. 18.         @Override
19. 19.         protected void reduce(Text key, Iterable<Text> values, Context context)
20. 20.                 throws IOException, InterruptedException {
21. 21. 
22. 22.             /*** 在这编写reduce内容 ****/
23. 23.             /********** Begin **********/
24. 24. 
25. 25.             Map<String, Integer> map = new HashMap<>();
26. 26.             List<String> value_list = new ArrayList<>();
27. 27.             // 1. 因为需要遍历多次values里的值,把values可迭代对象转化为list
28. 28.             for (Text v : values) {
29. 29.                 value_list.add(v.toString());
30. 30.             }
31. 31.             // 2. 统计所有商品的数量
32. 32.             for (String v : value_list) {
33. 33.                 String[] atts = v.toString().split(",");
34. 34.                 String item = atts[1];
35. 35.                 Integer count = !map.containsKey(item) ? 1 : map.get(item) + 1;
36. 36.                 map.put(item, count);
37. 37.             }
38. 38.             // 3. 找出点击数量最大的商品
39. 39.             String itemClickMax = Collections.max(map.entrySet(), (entry1, entry2) -> {
40. 40.                 return entry1.getValue() - entry2.getValue();
41. 41.             }).getKey();
42. 42.             // 4. 统计点击量最大的商品的购买次数
43. 43.             int buyCount = 0;
44. 44.             for (String v : value_list) {
45. 45.                 String[] atts = v.toString().split(",");
46. 46.                 if (atts[1].equals(itemClickMax) && atts[3].equals("buy")) {
47. 47.                     buyCount++;
48. 48.                 }
49. 49.             }
50. 50.             // 5. 把商品类别、点击量最大的商品id、购买次数写入reducer输出
51. 51.             context.write(key, new Text(itemClickMax + "\t" + buyCount));
52. 52. 
53. 53.             /********** End **********/
54. 54. 
55. 55.         }
56. 56. 
57. 57.     }

六、项目心得

进行作业的过程中的需要仔细阅读题目,步骤的缺漏会影响最终的结果。编写代码时注意括号和分号的使用,遇到困难应该多思考多尝试。

相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
1月前
|
数据采集 运维 数据挖掘
API电商接口大数据分析与数据挖掘 (商品详情店铺)
API接口、数据分析以及数据挖掘在商品详情和店铺相关的应用中,各自扮演着重要的角色。以下是关于它们各自的功能以及如何在商品详情和店铺分析中协同工作的简要说明。
|
1月前
|
存储 JSON 大数据
大数据离线数仓---金融审批数仓
大数据离线数仓---金融审批数仓
128 1
|
18天前
|
JavaScript 前端开发 大数据
数字太大了,计算加法、减法会报错,结果不正确?怎么办?用JavaScript实现大数据(超过20位的数字)相加减运算。
数字太大了,计算加法、减法会报错,结果不正确?怎么办?用JavaScript实现大数据(超过20位的数字)相加减运算。
|
2月前
|
数据采集 监控 算法
利用大数据和API优化电商决策:商品性能分析实践
在数据驱动的电子商务时代,大数据分析已成为企业提升运营效率、增强市场竞争力的关键工具。通过精确收集和分析商品性能数据,企业能够洞察市场趋势,实现库存优化,提升顾客满意度,并显著增加销售额。本文将探讨如何通过API收集商品数据,并将这些数据转化为对电商平台有价值的洞察。
|
3月前
|
数据采集 传感器 人工智能
大数据关键技术之电商API接口接入数据采集发展趋势
本文从数据采集场景、数据采集系统、数据采集技术方面阐述数据采集的发展趋势。 01 数据采集场景的发展趋势 作为大数据和人工智能工程的源头,数据采集的场景伴随着应用场景的发展而变化,以下是数据采集场景的发展趋势。
|
数据采集 数据可视化 算法
电商API接口的大数据分析与挖掘技巧
随着电商行业的快速发展,电商平台上的交易数据量也越来越大。如何对这些数据进行分析和挖掘,从中获取有价值的信息,已经成为电商企业和开发者关注的重点。本文将介绍电商API接口的大数据分析与挖掘技巧。
|
1月前
|
存储 大数据 数据挖掘
云计算与大数据:从基础设施到实际应用
云计算与大数据:从基础设施到实际应用
135 0
|
3月前
|
数据挖掘
离线大数据分析的应用
离线大数据分析的应用
|
1月前
|
存储 大数据 数据挖掘
python数据分析——大数据和云计算
大数据和云计算作为当代信息技术的两大核心驱动力,正在以前所未有的速度改变着我们的生活、工作和思维方式。它们不仅为各行各业的创新提供了强大的技术支持,更是推动了整个社会的数字化转型。 从大数据的角度来看,它的核心价值在于通过对海量数据的收集、存储、分析和挖掘,发现其中的关联性和趋势,从而为决策提供更为科学、精准的依据。无论是商业领域的市场预测、消费者行为分析,还是公共服务领域的城市规划、交通管理,大数据都发挥着不可或缺的作用。同时,随着物联网、传感器等技术的普及,大数据的来源和种类也在不断扩展,这使得我们能够更全面地认识世界,把握规律。
47 0
|
2月前
|
SQL 分布式计算 数据库
离线数仓--大数据技术之DolphinScheduler
离线数仓--大数据技术之DolphinScheduler
145 2

热门文章

最新文章