问题是找出 280 亿条数据里面起点位置所在的经纬度省市区等信息、终点位置所在的经纬度省市区等信息,而且要根据天数来分出来(大概是 21 天)。其实就在 280 亿条数据里面增加 14 个字段。如果是小数据量,直接在数据库中 join 就行了,但是数据量一大,很多方法就不可用了。
初步想到的是将数据存放在 hive 里面,然后在 spark-sql 里面执行插入操作。第一个解决方案如下:
1、进入 hive 里面。首先在 $HIVE_HOME/bin 目录下输入:./hive
2、新建 hive 表;新建三个表,两个需要join的表和一个新表;
3、将数据导入到 hive 表;
load data local inpath ‘/home/ocean/Downloads/data/GP_PS_001.txt’ into table gdps_addstart;
4、进入到 spark-sql 操作(也可以在 hvie 中操作,但是对比 hive 操作时间和 sparksql 操作时间,sparksql 操作明显快于hive):
在 $SPARK_HOME/bin 目录下:
./spark-sql --master local[2] --jars /root/hadoop/source/mysql-connector-java-5.1.27.jar
5、将两个表 join 操作后插入到新表:
insert overwrite table gdps_addstart
select
a.gridT1,a.gridT2,a.startgrid,a.endgrid,a.userid,a.belongid,a.middleid,a.provice,a.city,a.mark,
b.startprovince,b.startcity,b.startcitycode,b.startdistrict,b.startadcode,b.starttownship
from gdps_add a join gdps_start b on a.startgrid=b.startid;
6、进入 spark-shell 操作页面:在 $SPARK_HOME/bin 目录下:
./spark-shell --master local[2] --jars /root/hadoop/source/mysql-connector-java-5.1.27.jar
将 hive 表数据存到 HDFS(因为这个只能在 spark-shell 下才能进行 write.csv() 操作);
spark.sql("select * from dept").write.csv("hdfs://ocean:8020/tmp/output")
7、从 HDFS 里面导出(可以写个脚本)
hadoop fs -get /tmp/output/part-00000-e716d1ee-2b92-4727-a387-206735b60a3a.csv dept.csv
8、将导出的文件拼接成一个大文件:
cat file1 file2 … >> file3
问题:
上述方案对单个文件可以适用,但对多个文件有挺多问题,1)我们数据是放在 489 个文件中,每个文件有 5000 多万条数据,那么上述第三步将数据导入到 hive 表中,需要写个批处理程序,批处理程序好写,主要问题是担心后面那个文件放到 hive 表中会将前面那个放到 hive 表中的数据给覆盖了,如将 GD_PS_001.txt 导入到 hive 表之后,再将 GD_PS_002.txt 导入到 hive 表后,会把 GD_PS_001.txt 的数据给覆盖掉。2)join 操作需要花费一段时间,后面将 hive 表数据存到 HDFS 中又需要花费一段时间。3)上述步骤中较复杂,需要进行到 hive、sparksql、spark-shell 中操作几步。4)第八步是否需要将众多小文件拼接成大文件还需要进一步考虑,因为如果拼接成一个大文件,后续分析的人也打开不了那些几十亿条数据。
后来问了很多人,给了很多的建议和方法,比如建议 hive 表修复,原先我都不知道修复是啥意思,后来自己也慢慢做实验,慢慢的就有了第二个解决方案,且第二个解决方案可行,最终使用的就是第二个解决方案。