本书内容包括大数据离线分析概述、Hive数据库表、基于HiveQL的常规操作、视图、索引和Pig等数据处理分析等基础工具知识, 还有Hive函数、Pig Latin编程、ETL工具Sqoop和工作流引擎Oozie等相关高级技术。
大数据离线处理目前技术上已经成熟。Hadoop框架是主流技术,使用HDFS存储数据,使用MapReduce做批量计算;需要数据仓库的存入Hive,然后从Hive进行分析和展现;涉及复杂业务场景时,使用Sqoop、Pig、Oozie等工具会更灵活方便。本书综合了大数据离线分析所需的主流技术,并配以案例和丰富的辅助学习资源,足以满足广大学习者入门的需要。
为什么要写这本书
数据时代(DataTime)的到来使大数据技术得到了学术界和产业界的重视,并获得了快速发展。随着全球数字化、移动互联网和物联网在各行各业的应用发展,使累积的数据量越来越大。诸多先行的企业、行业和国家已经证明,利用大数据技术可以更好地服务客户、发现新商业机会、扩大新市场、转换新动能。
当前正处于大数据产业发展的前期,市场需求日趋旺盛,但是人才缺口巨大,技术支撑严重不足,大数据专业知识的广泛传播非常紧迫。
本书基于教育部“2016年产学合作协同育人项目”——普开数据教学内容和课程体系改革项目,作为项目成果公开出版。北京普开数据技术有限公司在多届全国高校教师培训工作中起到了“种子”教师培养的作用,本书编者都是在培训过程中结识并展开合作的;同时在本书编写过程中,公司给予了强力支持,在此表示感谢。
读者对象
(1)学习大数据离线分析的本科和高职高专学生。
(2)从事数据分析相关工作的技术人员。
如何阅读本书
本书主要介绍了基于Hadoop生态圈的大数据离线处理技术。主流的大数据离线分析技术一般包括:使用HDFS存储数据,使用MapReduce做批量计算;需要数据仓库的存入Hive,从Hive进行分析和展现;涉及复杂业务场景时,使用Sqoop、Pig、Oozie等工具会更加灵活方便。
本书略过了HDFS存储数据、MapReduce批量计算的相关内容。HDFS是Hadoop提供的分布式存储框架,它可以用来存储海量数据,MapReduce是Hadoop提供的分布式计算框架,它可以用来统计和分析HDFS上的海量数据。该部分内容为Hadoop基础知识,读者如果需要深入学习,可以参考其他书籍或材料(如清华大学出版社2016年6月出版的《大数据技术基础》)。
本书内容是重点围绕Hive数据仓库展开的,Hive在Hadoop上提供了SQL接口,开发人员只需要编写简单易上手的SQL语句就可以实现创建表、删除表、加载数据、下载数据、分析数据等功能,读者可以从目录的章节名称中快速检索并学习各方面的知识。
同时,本书针对离线分析过程中的工程任务场景还提供了一些辅助工具介绍。Sqoop解决在Hadoop和关系数据库之间传递数据的问题,如果读者有这方面的基础或对其他ETL工具更熟悉,可以略过。Pig为大型数据集的处理提供了更高层次的抽象,以更灵活方便的方法实现加载数据、表达转换数据和存储最终结果,有这方面基础或暂无需求的读者可以略过书中第6、7章。Oozie实现对系统中多任务的管理,当平台中任务数量很大、需要维大数据
离线分析
前言
护和运行时,Oozie可以方便地完成调度监控这些任务的功能,对于仅处理简单任务场景的读者可以略过该部分内容。
偏重实践操作是本书的特色,书中所讲内容基本都配有实践操作演示。通过每部分知识的学习和相应操作环节,可以很快地掌握技术,并有很强的工程应用场景感。本书最后提供了一个综合应用案例,读者可以应用所学知识实现一个工程项目,从而有效训练工程应用开发能力。
勘误和支持
由于本书编者水平有限,书中难免会出现一些错误或者不准确的地方,恳请读者批评、指正。如果在教材使用中遇到问题,或者要学习更多相关内容,请关注微信号或联系普开数据在线实验平台。
编者
第章
3
HiveQL数据操作
本章摘要
在第2章中学习了管理表、外部表、分区表和桶表的概念,并且学习了创建、修改和删除表。在本章中将学习如何对Hive表中的数据进行操作。
首先,将学习如何把数据加载到表中,以及如何把表中的数据导出到指定的位置;其次,作为本章最重要的部分,将要学习一些数据查询语句,包括简单的查询语句和复杂的查询语句,因为好多用户需求需要通过查询语句得出结果;最后,简单介绍抽样查询。
3.1数据加载与导出
本节主要学习如何往表中加载数据,以及怎么导出数据。数据加载的几种主要方式:从本地系统中导入数据到Hive表中、从HDFS上导入数据到Hive表中、通过查询语句向Hive表中导入数据,以及动态分区插入数据;数据导出包括如何导出数据和导到何处。
3.1.1数据加载
1.从本地系统中导入数据到Hive表中
实例:hive>LOADDATALOCALINPATH'/home/zkpk/empmessages'INTOTABLEemp_messages;本例是把本地文件empmessages中的数据导入创建的Hive表emp_messages中。通过这个实例,整理出通用的语句格式是:LOADDATALOCALINPATH'/本地文件路径'INTOTABLEtablename;注意:关键字LOCAL不能漏掉。如果忘记此关键字,则默认从HDFS上去寻找所需要的数据文件路径。
2.从HDFS上导入数据到Hive表中
实例:\[zkpk@master~\]$hadoopfs-put/home/zkpk/empmessages/data/emp_messages;由于已创建的管理表就在HDFS上,所以只需要将文件put到管理表所在的目录就可以完成数据导入。通过这个实例,整理出来通用的语句格式是:hadoopfs-put'/数据所存放的本地路径''/创建表时存放表的路径'大数据
离线分析
0第3章
HiveQL数据操作
03.通过查询语句向Hive表中导入数据
通过查询语句向一张Hive空表中导入数据的实例。hive>INSERTINTOTABLEemp_messagesSELECTFROMold_emp_messages;如该例所示,首次向表中插入数据时,语句为INSERTINTOTABLEtablenameSELECT...INTO...。
查看此时表中的数据,验证执行结果。使用OVERWRITE关键字时,可以覆盖目标表中原来相同partition中的所有数据,如果目标表中没有partition,则覆盖整个表。hive>INSERTOVERWRITETABLEemp_messagesSELECTFROMold_emp_messages;查看此时表中的数据,验证执行结果。4.动态分区插入数据
所谓动态分区,也称作动态分区插入,指的是插入目标表时仅指定分区字段,不指定分区值,分区值是从原始表中取得的。静态分区和动态分区的区别在于导入数据时,是手动输入分区名称,还是通过数据来判断数据分区。如果一次插入上百上千个分区中,只写插入的代码就很多,这种场景就适合使用动态分区插入功能。
默认情况下,Hive是支持动态分区插入的,但是并没有开启。开启后,默认是以“严格”模式执行:要求至少有一列分区字段是静态的。这有助于阻止因设计错误导致查询产生大量的分区。表31描述了动态分区相关的属性设置。表31动态分区属性
属性名称默认值描述hive.exec.dynamic.partitionfalse设置成true,表示开启动态分区功能hive.exec.dynamic.partition.modestrict设置成nonstrict,表示允许所有分区都是动态的hive.exec.max.dynamic.partitions.pernode100每个Mapper或Reducer可以创建的最大动态分区个数。如果某个Mapper或Reducer尝试创建大于这个值的分区,则会抛出一个致命的错误信息hive.exec.max.dynamic.partitions1000一个动态分区创建语句可以创建的最大动态分区个数。如果超过这个值,则会抛出一个致命错误信息hive.exec.max.created.files100000全局可以创建的最大文件个数。有一个Hadoop计数器会跟踪记录创建了多少个文件,如果超过这个值,则会抛出一个致命错误信息在学习动态分区插入数据前,先学习静态分区插入数据。所谓的静态分区插入数据就是在写插入语句时,分区的值为一个确定的值,通过如下的例子可以加深认识。hive>INSERTOVERWRITETABLEtestparPARTITION(days='0328')
>SELECTFROMtesttWHEREt.day='0328';接下来,查看一下插入的结果。动态分区,顾名思义,就是在分区的字段值不确定的情况下进行数据插入操作。hive>INSERTOVERWRITETABLEtestparPARTITION(days)
>SELECTFROMtest;注意:如果分区是可以确定的,建议用静态分区的方式。不要用动态分区,因为动态分区的值是在reduce运行阶段确定的,也就是会把所有的记录distributeby。可想而知,表记录非常大的情况下,只有一个reduce处理,后果是不可想象的。然而,静态分区在编译阶段已经确定,不需要reduce处理。
3.1.2数据导出
数据导出可以分为:导出到本地文件系统中;导出到HDFS文件中;从一张表导出到另一张表中。
1.把数据导出到本地文件系统中hive>INSERTOVERWRITELOCALDIRECTORY'/home/zkpk/test'
>SELECTFROMtest;执行完上面的语句,在本地文件系统中查看有没有导出数据的文件。2.把数据导出到HDFS文件中hive>INSERTOVERWRITEDIRECTORY'/data/test_1'
>SELECTFROMtest;查看结果如下:3.从一张表导出到另一张表中hive>INSERTINTOTABLEtest_1
>SELECTFROMtest;查看结果如下:
如果数据文件恰好是用户所需要的格式,那么只需要把数据复制到目标路径下。hadoopfs-cp/source_path/target_path
3.2数据查询
在本节中,通过搜狗搜索日志分析系统案例来介绍一些常用的数据查询语句。
创建表:hive>CREATETABLEsougou_20111230(
>logdateSTRING,
>uidSTRING,
>keywordSTRING,
>rankINT,
>searchorderINT,
>urlSTRING)
>ROWFORMATDELIMITED
>FIELDSTERMINATEDBY'\\t'
>LOCATION'/data/sogou_20111230';
hive>CREATETABLEsougou_old_20111230(
>logdateSTRING,
>uidSTRING,
>keywordSTRING,
>rankINT,
>searchorderINT,
>urlSTRING)
>ROWFORMATDELIMITED
>FIELDSTERMINATEDBY'\\t'
>LOCATION'/data/sogou_old_20111230';3.2.1SELECT...FROM语句
SELECT...FROM语句和MySQL中的语法是一致的,SELECT是SQL中的投影算子,FROM子句标识了从哪个表、视图或嵌套查询中选择记录。
查询表sougou_20111230中的所有字段信息。一张表中的字段有可能非常多,当用户所需要查询的字段只需要少数几个时,把需要的字段列举出来即可。对于集合数据类型,引用集合数据类型中的元素有以下方式。
(1)数组引用方式,其索引是从0开始的(和Java一样),语句如下:SELECT字段名\[集合数据类型中的元素的位置\]FROMtablename;注意:引用一个不存在的元素将会返回NULL。
(2)为了引用一个MAP元素,用户还可以使用ARRAY\[...\]语法,但是使用的键值是非整数索引。语句如下:SELECT字段名\[集合数据类型中的元素内容\]FROMtablename;(3)为了引用STRUCT中的一个元素,用户可以使用“.”符号,类似于“表的别名.列名”。SELECT字段名.集合中的某个元素FROMtablename;FROM子句在使用中还有以下用法和功能。
1.LIMIT语句
往往典型的查询会返回多行数据,有时候不需要查询那么多行,这时候可以使用LIMIT关键字来限制行数。例如,查询表sougou_20111230中5行数据。hive>SELECTFROMsougou_20111230LIMIT5;结果如下:
……