280亿条大数据处理实战——(五)解决方案二

7 篇文章 0 订阅
6 篇文章 0 订阅

上面一篇讲到过,第一种方案有很多问题,于是问了很多人和做了较多实验有了第二种方案。第二种方案需要提前了解如下知识:

一、hive 表修复

hive 表修复网上有很多例子,这里可以简单理解为通过修复,可以直接快速的将 hdfs 与 hive 表进行关联。导入到 hdfs 里面的数据可以直接在 hive 表里面查询得到,同样的,在 hive 表里面进行增删改查也可以在 hdfs 里面查询得到,这样就可以节省很多时间,修复速度很快,几万上亿条的数据就可以一下子同步过去。不过 hive 表修复记得要分区,hive 增删该查时也可指定分区。

如下新建一个表存放原始 280 亿条数据:

CREATE EXTERNAL TABLE IF NOT EXISTS gdps(
gridt1 bigint,
gridt2 bigint,
startgrid int,
endgrid int,
userid int,
belongid int,
middleid int)
PARTITIONED BY (gdps_start int,gdps_end int)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim'=',',
'line.delim'='\n',
'serialization.format'='\t')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/tmp/hive/root/gdps';

LOCATION 可以指定 hdfs 的路径,gdps_stat 和 gdps_end 是分区字段名称,这两个字段名称可以不是数据里面的字段,自己新加的字段就行,这两个字段可以不参与运算,只用于分区,后续导出的数据也不会有这两个字段。在 hdfs 里面可以看到新建的 hive 表:

然后可以将本地数据传到服务器(通过 WinSCP 进行批量导入),再通过 shell 批处理脚本将数据导入到 hdfs 里面(批处理脚本里面会进行分区,有 489 个文件则分为 489 个区)

然后直接在 hive 里面输入:

hive> MSCK REPAIR TABLE gdps;

则 hdfs 里面的数据很快就直接导入到 hive 表里面了。

二、shell 批处理脚本的编写

本次处理中,由于文件个数很多,需要写多个 shell 脚本运行。shell 脚本很简单,主要有两点,第一是要以 #!/bin/sh 开头,第二是写完后,文件要授权,输入 chmod +x gethdfs.sh,则在终端输入:./gethdfs.sh 即可运行。

在写脚本时遇到一个问题,我的文件名后面数字保留的是三位数,文件名是 GD_PS_001.txt、GD_PS_002.txt。。。这种。后来找到一种方法,可以直接给数字赋值:num=`echo ${i}|awk '{printf("%05d\n",$0)}'`,则 num 的值就为 001、002。。。

如下是我写的一个 shell 批处理脚本,批量将 hdfs 里面的数据导出来:

#!/bin/sh
i=0
while ((i<=199))
do
        echo 1 > /proc/sys/vm/drop_caches
        num=`echo ${i}|awk '{printf("%05d\n",$0)}'`
        hadoop fs -get /tmp/hive/root/gdps_addend_stat/gdps_addend_stat_start=021/gdps_addend_stat_end=021/part-$num part$num.csv
        ((i++))
        echo 1 > /proc/sys/vm/drop_caches
done
echo 1 > /proc/sys/vm/drop_caches

后面那个语句:echo 1 > /proc/sys/vm/drop_caches 是清理缓存的意思。

后面发现,其实定时清理缓存,则计算所需的内存不需要很多(16G即可),需要的磁盘空间多点就行。

三、方案二

1、启动hadoop,进入 hive 里面建表
//新建每个文件对应的信息表(7个字段)---gdps
//新建城市基本信息表(11个字段)---base(注意base字段名称先写end,后面再修改)
//新建终点信息的表(15个字段)---gdps_addend
//新建开始结点信息的表(23个字段)---gdps_addend_stat

2、在 hdfs 里面建立文件夹(运行脚本);

3、将本地数据导入到 hdfs 文件夹里面(运行脚本);

4、在 hive 里面修复表,从而把数据从 hdfs 里面导入到 hive 表中;

5、进入到 spark-sql 操作页面:在 $SPARK_HOME/bin 目录下:
./spark-sql --master local[2] --jars /root/hadoop/source/mysql-connector-java-5.1.27.jar

6、首先将 gdps 表和 base 表 join 之后的结果插入到 gdps_addend 表;
注意 left join 和条件下推;
运行结束之后查看一下表里面条数;

insert overwrite table gdps_addend PARTITION (gdps_addend_start=021,gdps_addend_end=021)
select
a.gridt1,a.gridt2,a.startgrid,a.endgrid,a.userid,a.belongid,a.middleid,
b.end_lng,b.end_lat,b.end_province,b.end_city,b.end_citycode,b.end_district,b.end_adcode,b.end_township
from gdps a left join base b on a.endgrid=b.startgrid where a.gridt1>=20170121000000 and a.gridt1<20170122000000;

注意因为要根据天数分出来,故后面有个 where 条件。

7、将 gdps_addend 表和 base 表 join 之后的结果插入到 gdps_addend_stat 表;
注意是 left join;
运行结束之后查看一下表里面条数;

insert overwrite table gdps_addend_stat PARTITION (gdps_addend_stat_start=021,gdps_addend_stat_end=021)
select
a.gridt1,a.gridt2,a.startgrid,a.endgrid,a.userid,a.belongid,a.middleid,
a.end_lng,a.end_lat,a.end_province,a.end_city,a.end_citycode,a.end_district,a.end_adcode,a.end_township,
b.start_lng,b.start_lat,b.start_province,b.start_city,b.start_citycode,b.start_district,b.start_adcode,b.start_township
from gdps_addend a left join base b on a.startgrid=b.startgrid;

8、查找并统计个数(因为分析需要进行统计一下)
select count(*),start_city,end_city from gdps_addend_stat group by start_city,end_city;
这个可以直接将查询的结果打印出来,然后拷贝到本地 windows 电脑中;

9、目前 gdps_addend_stat 数据存在 hdfs 里面,写个脚本,将文件从 HDFS 里面导出到本地
hadoop fs -get /tmp/hive/root/gdps_addend_stat/gdps_addend_stat_start=001/gdps_addend_stat_end=001/001-part 001.csv
(可以写个脚本自动运行)

10、可以用 WinSCP 将服务器中的数据批量导入到本地电脑中。

至此,最终的数据都处理完毕。

总结:

本次处理中,由于资源条件较欠缺,故没有建立集群;

由于要按天数选出,因为有 21 天,故上述步骤需要运行大概 21 次;

有的天里面有 17 多亿条数据,在第六步将数据插入到 gdps_addend 表里面时需要大概 7.5 小时,在第七步将数据插入到 gdps_addend_stat 时,大概需要 4.6 小时,这个时间大概是插入字段,并选取一天数据的时间。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值