MapReduce 二次排序:对表格数据进行多字段排序
MapReduce 在传递<key, value>对时默认根据 key 进行排序,所以当需要对表格数据按某一字段进行排序时,可以设置排序的字段为 key。但有时候我们需要对两个字段分别进行排序,这种自定义排序称为'二次排序'。
例如,有以下数据:
如果对上面的数据按第一个字段值进行升序排列,那么有些数据的顺序是相同的,这时候我们就要按照第二个字段值再进行一次排序。例如:先按照第一个值(字母)升序排列,再按照第二个值(数字)进行降序排列得到:
'A, 3' 'B, 5' 'C, 1' 'B, 6' 'A, 4' 'C, 5' 'A, 4' 'A, 3' 'B, 6' 'B, 5' 'C, 5' 'C, 1'
需求: 编写一个 Java 程序,利用 MapReduce 技术对数据进行二次排序,把程序打包成 jar 文件运行得到结果。
(1) 读取表格数据 在程序中读取给定的表格文件 datas.xlsx 的内容(表格的第一行为标题,处理时需要排除),首先对 first_name 按首字母(不区分大小写)进行分区,首字母相同的行在同一分区(即输出在同一个文件,如 A、a 开头的行在第 1 个分区 part-r-00000,Z、z 开头的行在第 26 个分区 part-r-00025)。
(2) 二次排序 然后在每个分区内对数据进行二次排序,要求先对 first_name 字段降序排列,再对 last_name 字段也进行降序排列。最后 MapReduce 输出的每一行结果中,first_name 和 last_name 之间用空格分隔,其他字段用英文分号分隔,例如在第一个分区 (part-r-00000) 内的数据应该如下:
'599;AUSTIN CINTRON;AUSTIN.CINTRON@sakilacustomer.org' '173;AUDREY RAY;AUDREY.RAY@sakilacustomer.org' '63;ASHLEY RICHARDSON;ASHLEY.RICHARDSON@sakilacustomer.org' '346;ARTHUR SIMPKINS;ARTHUR.SIMPKINS@sakilacustomer.org' '522;ARNOLD HAVENS;ARNOLD.HAVENS@sakilacustomer.org' ... '367;ADAM GOOCH;ADAM.GOOCH@sakilacustomer.org' '375;AARON SELBY;AARON.SELBY@sakilacustomer.org'
再如:表格中没有 X 开头的 数据,则 part-r-00023 的内容应该为空内容。
由于题目中给出的数据是以 Excel 表格的形式存在,因此需要先将表格数据转化为文本形式再进行 MapReduce 操作。可以使用 Apache POI 库来读取 Excel 文件,并将读取结果转化为文本格式。
实现思路:
- 读取 Excel 文件,将表格数据按行读取并转化为文本格式。
- 编写 MapReduce 程序,对文本进行处理。
- Mapper 阶段:将每行数据按首字母分区,并将其转化为 <key, value> 对,其中 key 为首字母,value 为一行数据的字符串。
- Reducer 阶段:对每个分区中的数据进行二次排序,先按 first_name 降序排列,再按 last_name 降序排列。输出排序结果。
- 打包程序并在 Hadoop 上运行,得到排序结果。
代码实现:
...
原文地址: https://www.cveoy.top/t/topic/oI4D 著作权归作者所有。请勿转载和采集!