目录:
第一章 基础知识
1.1 Hadoop 和 MapReduce 综述
1.2 Hadoop 生态系统中的Hive
1.2.1 Pig
1.2.2 HBase
1.2.3 Java 和 Hive:词频统计算法
正文:
Hadoop 生态系统就是为了处理大数据集而产生的一个解决方案。Hadoop 实现了一个特殊的计算模型,也就是MapReduce,其可以将计算任务分割成多个处理单元,然后分散到一群家用或者服务器级别的硬件机器上,从而降低成本并提供水平可伸缩性。这个计算模型下面是一个被称为 Hadoop 分布式文件系统(HDFS)的文件系统。
而原有的非 Hadoop 架构是基于传统关系型数据库和结构化查询语句(SQL)的,且对于大量的SQL用户来说,使用 Hadoop 仍旧存在挑战。这就是 Hive出现的原因。Hive 提供了一种 HQL 的方式用以查询存储在 Hadoop 集群种的数据。
Hive 可以将大多数的查询转换为 MapReduce 任务。它适合用于数据仓库应用程序,使用该应用程序进行相关的静态数据分析,不需要快速响应给出结果,而且数据本身不会频繁变化。Hive 不是一个完整的数据库。Hadoop 以及 HDFS 的设计本身约束和局限性地限制了 Hive 所能胜任的工作。最大的限制就是 Hive 不支持记录级别的更新、插入或者删除操作。但是用户可以通过查询生成新表或者将查询结果导入到文件中;因为 Hadoop 是一个面向批处理的系统,而 MapReduce 任务的启动过程需要消耗较长的时间,所以 Hive 查询延时比较严重。传统数据库中在秒级别可以完成的查询,在 Hive 中,即使数据集相对较小,往往也需要执行更长的时间;Hive 不支持事务,因此,Hive 不支持 OLTP(联机事务处理)所需的关键功能,而更接近成为一个 OLAP(联机分析技术)工具。但因为延时较大,所以 Hive 并没有满足 OLAP 中的“联机”部分。
因此 Hive 是最适合数据仓库应用程序的,其可以维护海量数据,而且可以对数据进行挖掘,然后形成意见和报告等。相对其他 Hadoop 语言和工具来说,Hive 似的开发者将基于 SQL 的应用程序一直到 Hadoop 变得更加容易。
1.1 Hadoop 和 MapReduce 综述
理解 MapReduce的基础原理将有助于了解 Hive 底层是如何运作的,已经了解如何才能更 高效的使用 Hive。
MapReduce 这个属于来自于两个基本的数据转换操作:map 和 reduce。map 操作会将集合中的元素从一种形式转换成另一种形式。在这种情况下,输入的键值对会被转换成零到多个键值对输出。其中,输入和输出的键必须完全不同,而输入和输入的值则可能完全不同(?)。某个键的所有键值对都会被分发到同一个 reduce 操作中。确切地说,这个键和这个键所对应的所有值会被传递给同一个 Reducer。reduce 过程的目的是将值的集合转换成一个值(例如对一组数组求和或求平均值),或者转换成另一个集合。这个 Reducer 最终会产生一个键值对。
Hadoop 提供了一套技术设施来处理大多数困难的工作来保证任务能够执行成功。例如,Hadoop 决定如果将提交的 job 分解成多个独立的 map 和reduce 任务(task)来执行,它就会对这些 task 进行调度并为其分配合适的资源,决定将某个 task 分配到集群中哪个位置(通常是这个 task 所要处理的数据所在的位置,这样可以最小化网络开销)。它会监控每一个 task 以确保成功完成,并重启一些失败的 task。
Hadoop 分布式文件系统(也就是 HDFS),或者一个同类的分布式文件系统,管理着集群中的数据,每个数据块(block)都会被冗余多份(默认3份),这样可以保证数据的高可用,同时因为处理非常大的数据集,所以 HDFS 的数据块都非常大(64MB或者整数倍),这样可以使数据在磁盘上连续存储,保证以最少的磁盘寻址次数进行读写,从而最大化读写性能。
我的理解是 MapReduce 实际上是对算法任务的一个归类拆分,一堆数据可能存在大量不同的类型或者不同权重的数据或模型,不同的数据需要不同的算法任务将相同的数据集传递到同一个地方统一处理。因此,第一步 map 就是先将相同类型或者权重的数据聚合到一个个组中,第二步 reduce 就是对相同类型的组执行对应的任务。
举两个例子:
1. 现在有一堆混在一起的图形,有三角形、长方形和圆形,计算出所有图形的边的总数,计算出。已知三角形有三条边,长方形有四条边,圆形有一条边(暂时不考虑割圆术),因此不同的图形有不同的值。使用 MapReduce 的算法来计算的话,具体操作如下:第一步 map:先将图形分类,如得到 13 个三角形,5 个长方形,9 个圆形;第二步 reduce:针对三角形采用每个+3 分,得到 39 分,长方形每个 +4 分,得到 20 分,圆形每个 +1 分,得到 9 分,最后全部加起来得到 68 分,也就是这一堆图形一共有 68 条边。第一步 map:依次将图形取出,当取到三角形时,则标记为{"三角形":3},然后将这个键值对通过 Sort 和 Shuffle 后传递给 Reducer,Reducer 每次接收到则将值存储到 "三角形" 这个键所对应的数组中,随着图形的遍历,最后 Reducer 得到 {"三角形":[3,3,3,3,3,3,3,......]}, {"长方形":[4,4,4,4,4,4,......]}, {"圆形":[1,1,1,1,1,......]},然后 Reducer 将每个键所对应的值相加得到最后的总边数。
2. 得到一个人群包,已知其中人群的收入已知,分为高、中、低三类。通过市场规律分析某辆奢华车低收入人群不可能购买,中收入人群购买比例为3%,高收入人群购买比例为17%。计算该人群包针对该奢华车型的购买分。这个例子比较接近业务场景,可以用最简单的方式如同上面的例子,当然有经验的数据分析师或者数据建模师会用其他的算法来计算这个分数。
1.2 Hadoop 生态系统中的 Hive
上面已经说过引入 Hive 的原因,Hive 不仅提供了一个熟悉 SQL 的用户所能熟悉的编程模型,还消除了大量的通用代码。
下图显示了 Hive 的主要模块,以及 Hive 是如何与 Hadoop 交互工作的。本书主要关注与 CLI(命令行界面)的交互方式。喜欢图形界面的用户可以使用 Karmasphere 发布的商业产品,Cloudera 提供的开源的 Hue 项目等方式。
Hive发行版中附带的模块有 CLI,一个称为 HWI 的网页界面,以及可通过 JDBC、ODBC 和一个 Thrift 服务器进行便横访问的几个模块。所有的命令和查询都会进入到 Driver(驱动模块),通过该模块对输入进行解析编程,对需求的计算进行优化,然后按照指定的步骤执行(通常是启动多个 MapReduce 任务来执行)。当需要启动 MapReduce 任务时, Hive 本身是不会生成 Java MapReduce 算法程序的。相反, Hive 通过一个表示 ”job 执行计划“ 的 XML 文件驱动执行内置的 原生的 Mapper 和 Reducer 模块。类似于通过配置或者插件来实现复杂的整合的功能。
Hive 通过和 JobTracker 通信来初始化 MapReduce 任务,而不必部署在 JobTracker所在的管理节点上执行。通常要处理的数据文件是存储在 HDFS 中的,而 HDFS 和由 NameNode 进行管理的。
Metastore(元数据存储)是一个独立的关系型数据库(通常是一个 MySQL 实例),Hive 会在其中保存表模式和其他系统元数据。
1.2.1 Pig
Pig 是 Hive 的替代工具,是由 Yahoo! 开发的,同时期的 Facebook 正在开发 Hive。Pig 也是一个和 Hadoop 紧密联系的顶级 Apache 项目。
Pig 被描述成一种数据流语言,而不是一种查询语言。在 Pig 中,用户需要写一系列的声明语句来定义某些关系和其他一些关系之间的联系,这里的新关系都会执行新的数据转换过程。Pig 会查找这些声明,然后穿件一系列有次序的 MapReduce 任务,来对数据进行转换,知道产生符合预期的计算方式所得到的最终结果。
通常 Hadoop 团队会将 Hive 和 Pig 结合使用。
Pig可以非常方便的处理HDFS和HBase的数据,和Hive一样,Pig可以非常高效的处理其需要做的,通过直接操作Pig查询可以节省大量的劳动和时间。当你想在你的数据上做一些转换,并且不想编写MapReduce jobs就可以用Pig.
1.2.2 HBase
HBase 是一个NoSQL,提供了 Hive 不支持的数据库特性(行级别的更新,快速的查询响应时间,以及支持事务)。HBase 是一个分布式的,可伸缩的数据存储(但不支持多行事务)。设计灵感来自谷歌的 BigTable,但是 HBase 没有全部实现它的特性。HBase 支持的一个重要特性就是列存储,列可以组织成列族,列族在分布式集群中物理上是存储在一起的。这样使得查询只是所有列的子集时,读写速度会快很多(因为只用读取需要的列)。HBase 可以像键值存储一样被使用,每一行都是用一个唯一键来提供非常快的速度读写这一行的列或者列族,同时 HBase 会对每个列保留多个版本的值以供回滚。
HBase 使用 分布式文件系统(通常是HDFS)来持久化存储数据,为了优化数据的更新和查询性能,HBase 也使用内存缓存技术对数据和本地文件进行追加数据更新操作日志。通过日志定期更新持久化文件。
1.2.3 Cascading、Crunch 及其他
Apache Hadoop 生态系统之外还有几个”高级“语言,他们也在 Hadoop 上提供了不错的抽象来减少对于特定任务的底层编码工作。它们提供了 Hive 本身没有提供的额外功能。
1.3 Java 和 Hive:词频统计算法
本章主要是对比使用 Java 和 Hive 来实现词频统计复杂度对比,可以预见的是,Java 需要引入大量的包依赖,然后继承 Mapper 和 Reducer 然后再在 mian 函数调用 Job 并设定输入输出路径,最后再编译成一个 JAR 包执行。而 Hive 则只有8行就能实现。