您好,欢迎访问一九零五行业门户网

使用Apache Hadoop、Impala和MySQL进行数据分析_MySQL

apache
apache hadoop是目前被大家广泛使用的数据分析平台,它可靠、高效、可伸缩。percona公司的alexander rubin最近发表了一篇博客文章介绍了他是如何将一个表从mysql导出到hadoop然后将数据加载到cloudera impala并在这上面运行报告的。
在alexander rubin的这个测试示例中他使用的集群包含6个数据节点。下面是具体的规格:
用途
服务器规格
namenode、datanode、hive 元数据存储等
2x poweredge 2950, 2x l5335 cpu @ 2.00ghz, 8 cores, 16gb ram, 使用8个sas驱动器的raid 10
仅做数据节点
4x poweredge sc1425, 2x xeon cpu @ 3.00ghz, 2 cores, 8gb ram, 单个4tb 驱动器
数据导出
有很多方法可以将数据从mysql导出到hadoop。在rubin的这个示例中,他简单地将ontime表导出到了一个文本文件中:
select*intooutfile '/tmp/ontime.psv'
fields terminated by ','
fromontime;
你可以使用“|”或者任何其他的符号作为分隔符。当然,还可以使用下面这段简单的脚本直接从www.transtats.bts.gov上下载数据。
foryin{1988..2013}
do
foriin{1..12}
do
                u=http://www.transtats.bts.gov/download/on_time_on_time_performance_${y}_${i}.zip
                wget $u -o ontime.log
                unzipon_time_on_time_performance_${y}_${i}.zip
done
done
载入hadoop hdfs
rubin首先将数据载入到了hdfs中作为一组文件。hive或者impala将会使用导入数据的那个目录,连接该目录下的所有文件。在rubin的示例中,他在hdfs上创建了/data/ontime/目录,然后将本地所有匹配on_time_on_time_performance_*.csv模式的文件复制到了该目录下。
$ hdfs dfs -mkdir /data/ontime/
$ hdfs -v dfs -copyfromlocalon_time_on_time_performance_*.csv /data/ontime/
在impala中创建外部表
当所有数据文件都被载入之后接下来需要创建一个外部表:
create external table ontime_csv (
yeardint,
quartertinyint ,
monthdtinyint ,
dayofmonthtinyint ,
dayofweektinyint ,
flightdatestring,
uniquecarrierstring,
airlineidint,
carrierstring,
tailnumstring,
flightnumstring,
originairportidint,
originairportseqidint,
origincitymarketidint,
originstring,
origincitynamestring,
originstatestring,
originstatefipsstring,
originstatenamestring,
originwacint,
destairportidint,
destairportseqidint,
destcitymarketidint,
deststring,
...
row format delimited fields terminated by ','
stored as textfile
location '/data/ontime';
注意“external”关键词和location,后者指向hdfs中的一个目录而不是文件。impala仅会创建元信息,不会修改表。创建之后就能立即查询该表,在rubin的这个示例中执行的sql是:
>selectyeard, count(*)fromontime_psv groupbyyeard;
该sql耗时131.38秒。注意group by并不会对行进行排序,这一点不同于mysql,如果要排序需要添加 order by yeard语句。另外通过执行计划我们能够发现impala需要扫描大小约为45.68gb的文件。
impala使用面向列的格式和压缩
impala最大的好处就是它支持面向列的格式和压缩。rubin尝试了新的使用snappy压缩算法的parquet格式。因为这个例子使用的表非常大,所以最好使用基于列的格式。为了使用parquet格式,首先需要载入数据,这在impala中已经有表、hdfs中已经有文件的情况下是非常容易实现的。本示例大约使用了729秒的时间导入了约1亿5千万条记录,导入之后使用新表再次执行同一个查询所耗费的时间只有4.17秒,扫描的数据量也小了很多,压缩之后的数据只有3.95gb。
impala复杂查询示例
select
   min(yeard), max(yeard),carrier, count(*)ascnt,
   sum(if(arrdelayminutes>30, 1, 0))asflights_delayed,
   round(sum(if(arrdelayminutes>30, 1, 0))/count(*),2)asrate
from ontime_parquet_snappy
where
dayofweeknotin(6,7)andoriginstatenotin('ak', 'hi', 'pr', 'vi')
anddeststatenotin('ak', 'hi', 'pr', 'vi')
andflightdate groupbycarrier
having cnt > 100000andmax(yeard) > 1990
orderbyrate desc
limit 1000;
注意:以上查询不支持sum(arrdelayminutes>30)语法,需要使用sum(if(arrdelayminutes>30, 1, 0) 代替。另外查询故意被设计为不使用索引:大部分条件仅会过滤掉不到30%的数据。
该查询耗时15.28秒比最初的mysql结果(非并行执行时15分56.40秒,并行执行时5分47秒)要快很多。当然,它们之间并不是一个“对等的比较”:
mysql将扫描45gb的数据而使用parquet的impala仅会扫描3.5gb的数据mysql运行在一台服务器上,而hadoop和impala则并行运行在6台服务器上尽管如此,hadoop和impala在性能方面的表现依然令人印象深刻,同时还能够支持扩展,因此在大数据分析场景中它能为我们提供很多帮助。
感谢崔康对本文的审校。
给infoq中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@infoq)或者腾讯微博(@infoq)关注我们,并与我们的编辑和其他读者朋友交流。
其它类似信息

推荐信息