HCatalog快速入门

1 HCatalog简介

1、什么是HCatalog

HCatalog是Hadoop的表存储管理工具。它将Hive Metastore的表格数据公开给其他Hadoop应用程序。使得具有不同数据处理工具(Pig,MapReduce)的用户能够轻松将数据写入网格。它确保用户不必担心数据存储在何处或以何种格式存储。

HCatalog像Hive的一个关键组件一样工作,它使用户能够以任何格式和任何结构存储他们的数据。

2、为什么选择HCatalog

为正确的作业启用正确的工具

Hadoop生态系统包含用于数据处理的不同工具,如Hive,Pig和MapReduce。虽然这些工具不需要元数据,但它们仍然可以从中受益。共享元数据存储还可以使跨工具的用户更容易地共享数据。数据加载和使用MapReduce或Pig进行标准化然后通过Hive分析的工作流程非常普遍。如果所有这些工具共享一个Metastore,则每个工具的用户可以立即访问使用其他工具创建的数据。不需要加载或传输步骤。

捕获处理状态以启用共享

HCatalog可以发布您的分析结果。所以其他程序员可以通过“REST”访问您的分析平台。您发布的schemas对其他数据科学家也很有用。其他数据科学家将您的发现用作后续发现的输入。

将Hadoop与其他一切集成在一起

Hadoop作为处理和存储环境为企业开辟了很多机会; 然而,为了推动采用,它必须与现有工具合作并扩大现有工具。Hadoop应作为分析平台的输入或与运营数据存储和Web应用程序集成。组织应该享受Hadoop的价值,而无需学习全新的工具集。REST服务使用熟悉的API和SQL类语言为企业打开了平台。企业数据管理系统使用HCatalog与Hadoop平台进行更深入的整合。

3、HCalalog架构

下图显示了HCatalog的整体架构。

HCatalog支持以任何可以编写SerDe(串行器 - 解串器)的格式读取和写入文件。默认情况下,HCatalog支持RCFile,CSV,JSON,SequenceFile和ORC文件格式。要使用自定义格式,您必须提供InputFormat,OutputFormat和SerDe。

HCatalog建立在Hive Metastore的顶部,并结合了Hive的DDL。HCatalog为Pig和MapReduce提供了读写接口,并使用Hive的命令行界面来发布数据定义和元数据探索命令。

2 HCatalog安装

所有Hadoop子项目,如Hive,Pig和HBase都支持Linux操作系统。因此,您需要在您的系统上安装Linux。HCatalog于2013年3月26日与HiveInstallation合并。从版本Hive-0.11.0开始,HCatalog随附Hive安装。因此,请按照以下步骤安装Hive,然后Hive会自动将HCatalog安装到您的系统上。

第1步:验证JAVA安装

在安装Hive之前,必须在您的系统上安装Java。您可以使用以下命令来检查您的系统上是否已安装Java -

$ java –version

如果您的系统上已经安装了Java,您将看到以下响应 -

java version "1.7.0_71"

Java(TM) SE Runtime Environment (build 1.7.0_71-b13)

Java HotSpot(TM) Client VM (build 25.0-b02, mixed mode)

如果您的系统上没有安装Java,那么您需要按照以下步骤操作。

第2步:安装Java

通过访问以下链接http://www.oracle.com/下载Java(JDK <最新版本> - X64.tar.gz)

然后将jdk-7u71-linux-x64.tar.gz下载到您的系统中。

通常,您会在Downloads文件夹中找到下载的Java文件。验证它并使用以下命令提取jdk-7u71-linux-x64.gz文件。

$ cd Downloads/

$ ls

jdk-7u71-linux-x64.gz

$ tar zxf jdk-7u71-linux-x64.gz

$ ls

jdk1.7.0_71 jdk-7u71-linux-x64.gz

要使所有用户都可以使用Java,必须将其移至“/ usr / local /”位置。打开root并键入以下命令。

$ su

password:

# mv jdk1.7.0_71 /usr/local/

# exit

要设置PATH和JAVA_HOME变量,请将以下命令添加到〜/ .bashrc文件中。

export JAVA_HOME=/usr/local/jdk1.7.0_71

export PATH=PATH:$JAVA_HOME/bin

现在使用终端上的命令java-version来验证安装,如上所述。

第3步:验证Hadoop安装

在安装Hive之前,Hadoop必须安装在您的系统上。让我们使用以下命令验证Hadoop安装 -

$ hadoop version

如果您的系统上已经安装了Hadoop,那么您将得到以下响应 -

Hadoop 2.4.1

Subversion https://svn.apache.org/repos/asf/hadoop/common -r 1529768

Compiled by hortonmu on 2013-10-07T06:28Z

Compiled with protoc 2.5.0

From source with checksum 79e53ce7994d1628b240f09af91e1af4

如果您的系统上未安装Hadoop,请继续执行以下步骤 -

第4步:下载Hadoop

使用以下命令从ApacheSoftware Foundation下载并提取Hadoop2.4.1。

$ su

password:

# cd /usr/local

# wget http://apache.claz.org/hadoop/common/hadoop-2.4.1/

hadoop-2.4.1.tar.gz

# tar xzf hadoop-2.4.1.tar.gz

# mv hadoop-2.4.1/* to hadoop/

# exit

第5步:以伪分布式模式安装Hadoop

以下步骤用于以伪分布式模式安装Hadoop2.4.1。

设置Hadoop

您可以通过将以下命令附加到〜/ .bashrc文件来设置Hadoop环境变量。

export HADOOP_HOME=/usr/local/hadoop

export HADOOP_MAPRED_HOME=$HADOOP_HOME

export HADOOP_COMMON_HOME=$HADOOP_HOME

export HADOOP_HDFS_HOME=$HADOOP_HOME

export YARN_HOME=$HADOOP_HOME

export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native

export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin

现在将所有更改应用到当前正在运行的系统中。

$ source ~/.bashrc

Hadoop配置

您可以在位置“$HADOOP_HOME / etc / hadoop”中找到所有Hadoop配置文件。您需要根据您的Hadoop基础架构对这些配置文件进行适当的更改。

$ cd $HADOOP_HOME/etc/hadoop

为了使用Java开发Hadoop程序,必须通过将JAVA_HOME值替换为系统中Java的位置来重置hadoop-env.sh文件中的Java环境变量。

export JAVA_HOME=/usr/local/jdk1.7.0_71

下面列出了您必须编辑才能配置Hadoop的文件列表。

core-site.xml

该文件包含的信息,用于Hadoop的实例的端口号,分配给文件系统的内存配置,存储数据的内存限制,以及读/写缓冲器的大小。

打开core-site.xml并在<configuration>和</ configuration>标记之间添加以下属性。

<configuration>

   <property>

      <name>fs.default.name</name>

      <value>hdfs://localhost:9000</value>

   </property>

</configuration>

hdfs-site.xml

在文件中包含的信息,如数据副本的数量,namenode的路径,你的本地文件系统的datanode路径。datanode就是你想要存储Hadoop基础架构的地方。

让我们假设以下数据。

dfs.replication (data replication value) = 1

(In the following path /hadoop/ is the user name.

hadoopinfra/hdfs/namenode is the directory created by hdfs file system.)

namenode path = //home/hadoop/hadoopinfra/hdfs/namenode

(hadoopinfra/hdfs/datanode is the directory created by hdfs file system.)

datanode path = //home/hadoop/hadoopinfra/hdfs/datanode

打开此文件,并在该文件的<configuration>,</ configuration>标记之间添加以下属性。

<configuration>

   <property>

      <name>dfs.replication</name>

      <value>1</value>

   </property>

  

   <property>

      <name>dfs.name.dir</name>

      <value>file:///home/hadoop/hadoopinfra/hdfs/namenode</value>

   </property>

   <property>

      <name>dfs.data.dir</name>

      <value>file:///home/hadoop/hadoopinfra/hdfs/datanode</value>

   </property>

</configuration>

注 -在上面的文件中,所有属性值都是用户定义的,您可以根据Hadoop基础结构进行更改。

yarn-site.xml

该文件用于将yarn配置到Hadoop。打开yarn-site.xml文件并在该文件的<configuration>,</ configuration>标记之间添加以下属性。

<configuration>

   <property>

      <name>yarn.nodemanager.aux-services</name>

      <value>mapreduce_shuffle</value>

   </property>

</configuration>

mapred-site.xml

该文件用于指定我们正在使用的MapReduce框架。默认情况下,Hadoop包含一个yarn-site.xml模板。首先,您需要使用以下命令将文件从mapred-site,xml.template复制到mapred-site.xml文件。

<configuration>

   <property>

      <name>mapreduce.framework.name</name>

      <value>yarn</value>

   </property>

</configuration>

第6步:验证Hadoop安装

以下步骤用于验证Hadoop安装。

Namenode设置

使用命令“hdfsnamenode -format”设置namenode,如下所示 -

$ cd ~

$ hdfs namenode -format

预期结果如下 -

10/24/14 21:30:55 INFO namenode.NameNode: STARTUP_MSG:

/************************************************************

STARTUP_MSG: Starting NameNode

STARTUP_MSG: host = localhost/192.168.1.11

STARTUP_MSG: args = [-format]

STARTUP_MSG: version = 2.4.1

...

...

10/24/14 21:30:56 INFO common.Storage: Storage directory

/home/hadoop/hadoopinfra/hdfs/namenode has been successfully formatted.

10/24/14 21:30:56 INFO namenode.NNStorageRetentionManager: Going to retain 1

images with txid >= 0 10/24/14 21:30:56 INFO util.ExitUtil: Exiting with status 0

10/24/14 21:30:56 INFO namenode.NameNode: SHUTDOWN_MSG:

/************************************************************

SHUTDOWN_MSG: Shutting down NameNode at localhost/192.168.1.11

************************************************************/

验证HadoopDFS

以下命令用于启动DFS。执行此命令将启动您的Hadoop文件系统。

$ start-dfs.sh

预期产出如下 –

10/24/14 21:37:56 Starting namenodes on [localhost]

localhost: starting namenode, logging to

/home/hadoop/hadoop-2.4.1/logs/hadoop-hadoop-namenode-localhost.out localhost:

starting datanode, logging to

   /home/hadoop/hadoop-2.4.1/logs/hadoop-hadoop-datanode-localhost.out

Starting secondary namenodes [0.0.0.0]

验证yarn脚本

以下命令用于启动Yarn脚本。执行这个命令将启动你的Yarn守护进程。

$ start-yarn.sh

预期产出如下 –

starting yarn daemons

starting resourcemanager, logging to /home/hadoop/hadoop-2.4.1/logs/

yarn-hadoop-resourcemanager-localhost.out

localhost: starting nodemanager, logging to

   /home/hadoop/hadoop-2.4.1/logs/yarn-hadoop-nodemanager-localhost.out

在浏览器上访问Hadoop

访问Hadoop的默认端口号是50070.使用以下URL在浏览器上获取Hadoop服务。

http://localhost:50070/

验证集群的所有应用程序

访问群集的所有应用程序的默认端口号是8088.使用以下URL访问此服务。

http://localhost:8088/

完成Hadoop的安装后,继续下一步并在您的系统上安装Hive。

第7步:下载Hive

我们在本教程中使用hive-0.14.0。您可以通过访问以下链接http://apache.petsads.us/hive/hive-0.14.0/来下载它。让我们假设它被下载到/ Downloads目录中。在这里,我们为本教程下载名为“apache-hive-0.14.0-bin.tar.gz ”的Hive归档。以下命令用于验证下载 –

$ cd Downloads

$ ls

成功下载后,您会看到以下回复 -

apache-hive-0.14.0-bin.tar.gz

第8步:安装Hive

在您的系统上安装Hive需要以下步骤。让我们假设Hive归档文件被下载到/ Downloads目录中。

提取并验证Hive存档

以下命令用于验证下载并提取Hive归档文件 -

$ tar zxvf apache-hive-0.14.0-bin.tar.gz

$ ls

成功下载后,您会看到以下回复 -

apache-hive-0.14.0-bin apache-hive-0.14.0-bin.tar.gz

将文件复制到/ usr / local / hive目录

我们需要从超级用户“su- ”复制文件。以下命令用于将解压目录中的文件复制到/usr / local / hive目录。

$ su -

passwd:

# cd /home/user/Download

# mv apache-hive-0.14.0-bin /usr/local/hive

# exit

为Hive设置环境

您可以通过将以下行添加到〜/ .bashrc文件来设置Hive环境-

export HIVE_HOME=/usr/local/hive

export PATH=$PATH:$HIVE_HOME/bin

export CLASSPATH=$CLASSPATH:/usr/local/Hadoop/lib/*:.

export CLASSPATH=$CLASSPATH:/usr/local/hive/lib/*:.

以下命令用于执行〜/ .bashrc文件。

$ source ~/.bashrc

第9步:配置Hive

为了用Hadoop配置hive,你需要编辑hive-env.sh文件,该文件被放置在$ HIVE_HOME / conf目录。以下命令重定向到Hive config文件夹并复制模板文件 -

$ cd $HIVE_HOME/conf

$ cp hive-env.sh.template hive-env.sh

通过追加以下行编辑hive-env.sh文件 -

export HADOOP_HOME=/usr/local/hadoop

这样,Hive安装就完成了。现在您需要一个外部数据库服务器来配置Metastore。我们使用Apache Derby数据库。

第10步:下载并安装Apache Derby

按照以下步骤下载并安装ApacheDerby -

下载ApacheDerby

以下命令用于下载ApacheDerby。需要一些时间来下载。

$ cd ~

$ wget http://archive.apache.org/dist/db/derby/db-derby-10.4.2.0/db-derby-10.4.2.0-bin.tar.gz

以下命令用于验证下载 -

$ ls

成功下载后,您会看到以下回复 -

db-derby-10.4.2.0-bin.tar.gz

提取并验证Derby档案

以下命令用于提取和验证Derby存档 -

$ tar zxvf db-derby-10.4.2.0-bin.tar.gz

$ ls

成功下载后,您会看到以下回复 -

db-derby-10.4.2.0-bin db-derby-10.4.2.0-bin.tar.gz

将文件复制到/ usr / local / derby目录

我们需要从超级用户“su- ”复制。以下命令用于将解压目录中的文件复制到/usr / local / derby目录 -

$ su -

passwd:

# cd /home/user

# mv db-derby-10.4.2.0-bin /usr/local/derby

# exit

为derby设置环境

您可以通过将以下行添加到〜/ .bashrc文件来设置Derby环境-

export DERBY_HOME=/usr/local/derby

export PATH=$PATH:$DERBY_HOME/bin

export CLASSPATH=$CLASSPATH:$DERBY_HOME/lib/derby.jar:$DERBY_HOME/lib/derbytools.jar

以下命令用于执行〜/ .bashrc文件 -

$ source ~/.bashrc

为Metastore创建一个目录

在$DERBY_HOME目录中创建一个名为data的目录来存储Metastore数据。

$ mkdir $DERBY_HOME/data

derby安装和环境设置现已完成。

步骤11:配置Hive Metastore

配置Metastore意味着指定Hive存储数据库的位置。您可以通过编辑位于$ HIVE_HOME /conf目录中的hive-site.xml文件来完成此操作。首先,使用以下命令复制模板文件 -

$ cd $HIVE_HOME/conf

$ cp hive-default.xml.template hive-site.xml

编辑hive-site.xml并在<configuration>和</ configuration>标记之间附加以下几行 -

<property>

   <name>javax.jdo.option.ConnectionURL</name>

   <value>jdbc:derby://localhost:1527/metastore_db;create = true</value>

   <description>JDBC connect string for a JDBC metastore</description>

</property>

创建一个名为jpox.properties的文件并将以下行添加到其中 -

javax.jdo.PersistenceManagerFactoryClass = org.jpox.PersistenceManagerFactoryImpl

org.jpox.autoCreateSchema = false

org.jpox.validateTables = false

org.jpox.validateColumns = false

org.jpox.validateConstraints = false

org.jpox.storeManagerType = rdbms

org.jpox.autoCreateSchema = true

org.jpox.autoStartMechanismMode = checked

org.jpox.transactionIsolation = read_committed

javax.jdo.option.DetachAllOnCommit = true

javax.jdo.option.NontransactionalRead = true

javax.jdo.option.ConnectionDriverName = org.apache.derby.jdbc.ClientDriver

javax.jdo.option.ConnectionURL = jdbc:derby://hadoop1:1527/metastore_db;create = true

javax.jdo.option.ConnectionUserName = APP

javax.jdo.option.ConnectionPassword = mine

第12步:验证Hive安装

在运行Hive之前,您需要在HDFS中创建/ tmp文件夹和单独的Hive文件夹。在这里,我们使用/ user / hive/ warehouse文件夹。您需要为这些新创建的文件夹设置写入权限,如下所示 -

chmod g+w

现在在验证Hive之前将它们设置在HDFS中。使用以下命令 -

$ $HADOOP_HOME/bin/hadoop fs -mkdir /tmp

$ $HADOOP_HOME/bin/hadoop fs -mkdir /user/hive/warehouse

$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /tmp

$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /user/hive/warehouse

以下命令用于验证Hive安装 -

$ cd $HIVE_HOME

$ bin/hive

在成功安装Hive后,您会看到以下回复 -

Logging initialized using configuration in

   jar:file:/home/hadoop/hive-0.9.0/lib/hive-common-0.9.0.jar!/

hive-log4j.properties Hive history

   =/tmp/hadoop/hive_job_log_hadoop_201312121621_1494929084.txt

………………….

hive>

您可以执行以下示例命令来显示所有表格 -

hive> show tables;

OK Time taken: 2.798 seconds

hive>

第13步:验证HCatalog安装

使用以下命令为HCatalogHome 设置系统变量HCAT_HOME。

export HCAT_HOME = $HiVE_HOME/HCatalog

使用以下命令验证HCatalog安装。

cd $HCAT_HOME/bin

./hcat

如果安装成功,您将看到以下输出 -

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

usage: hcat { -e "<query>" | -f "<filepath>" }

   [ -g "<group>" ] [ -p "<perms>" ]

   [ -D"<name> = <value>" ]

    

-D <property = value>    use hadoop value for given property

-e <exec>                hcat command given from command line

-f <file>                hcat commands in file

-g <group>               group for the db/table specified in CREATE statement

-h,--help                Print help information

-p <perms>               permissions for the db/table specified in CREATE statement

3 CLI

可以从$HIVE_HOME / HCatalog / bin / hcat命令中调用HCatalog命令行界面(CLI),其中$HIVE_HOME是Hive的主目录。hcat是用于初始化HCatalog服务器的命令。

使用以下命令初始化HCatalog命令行。

cd $HCAT_HOME/bin

./hcat

如果安装已经正确完成,那么您将得到以下输出 -

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

usage: hcat { -e "<query>" | -f "<filepath>" }

   [ -g "<group>" ] [ -p "<perms>" ]

   [ -D"<name> = <value>" ]

    

-D <property = value>    use hadoop value for given property

-e <exec>                hcat command given from command line

-f <file>                hcat commands in file

-g <group>               group for the db/table specified in CREATE statement

-h,--help                Print help information

-p <perms>               permissions for the db/table specified in CREATE statement

HCatalog CLI支持这些命令行选项 -

Sr.No

选项

示例和说明

1

-G

hcat -g mygroup ...

要创建的表必须具有组“mygroup”。

2

-p

hcat -p rwxr-xr-x ...

要创建的表必须具有读取,写入和执行权限。

3

-F

hcat -f myscript.HCatalog ...

myscript.HCatalog是一个包含要执行的DDL命令的脚本文件。

4

-e

hcat -e'create table mytable(int);' ...

将以下字符串视为DDL命令并执行它。

5

-D

hcat -Dkey = value ...

将键值对作为Java系统属性传递给HCatalog。

6

-

hcat

打印使用信息。

注 -

该-g和-p选项是不是强制性的。

有一次,可以提供-e或-f选项,而不是两者。

选择顺序并不重要; 您可以按任意顺序指定选项。

Sr.No

DDL命令和描述

1

CREATE TABLE

使用HCatalog创建一个表。如果您使用CLUSTERED BY子句创建表,则无法使用Pig或MapReduce写入该表。

2

ALTER TABLE

除了REBUILD和CONCATENATE选项以外,支持。它的行为与Hive中的行为相同。

3

DROP TABLE

支持的。行为与Hive相同(删除完整的表格和结构)。

4

CREATE / ALTER / DROP VIEW

支持的。行为与Hive相同。

注 - Pig和MapReduce无法读取或写入视图。

5

SHOW TABLES

显示表格列表。

6

SHOW PARTITIONS

显示分区列表。

7

Create/Drop Index

支持CREATE和DROP FUNCTION操作,但创建的函数仍然必须在Pig中注册并放入MapReduce的CLASSPATH中。

8

DESCRIBE

支持。行为与Hive相同。描述结构。

上表中的一些命令将在后面的章节中解释。

4 语法

1 创建表

本章介绍如何创建表格以及如何向其中插入数据。在HCatalog中创建表格的约定与使用Hive创建表格非常相似。

创建表格的声明

创建表格是一种声明,用于使用HCatalog在Hive Metastore中创建表格。其语法和示例如下所示 -

语法

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS][db_name.] table_name

[(col_name data_type [COMMENT col_comment], ...)]

[COMMENT table_comment]

[ROW FORMAT row_format]

[STORED AS file_format]

让我们假设您需要使用CREATETABLE语句创建一个名为employee的表。下表列出了employee表中的字段及其数据类型-

Sr.No

字段名称

数据类型

1

Eid

int

2

Name

String

3

Salary

Float

4

Designation

String

以下数据定义了支持的字段,如注释,行格式字段,如字段终止符,行终止符和存储文件类型。

COMMENT Employee details

FIELDS TERMINATED BY \t

LINES TERMINATED BY \n

STORED IN TEXT FILE

以下查询使用上述数据创建一个名为employee的表。

./hcat –e "CREATE TABLE IF NOT EXISTS employee ( eidint, name String,

   salary String,destination String) \

COMMENT 'Employee details' \

ROW FORMAT DELIMITED \

FIELDS TERMINATED BY ‘\t’ \

LINES TERMINATED BY ‘\n’ \

STORED AS TEXTFILE;"

如果添加选项IFNOT EXISTS,HCatalog会在表存在的情况下忽略语句。

成功创建表格后,您会看到以下回复 -

OK

Time taken: 5.905 seconds

加载数据声明

通常,在SQL中创建表之后,我们可以使用Insert语句插入数据。但在HCatalog中,我们使用LOAD DATA语句插入数据。

将数据插入HCatalog时,最好使用LOAD DATA来存储批量记录。有两种加载数据的方式:一种来自本地文件系统,另一种来自Hadoop文件系统。

句法

LOAD DATA的语法如下 -

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTOTABLE tablename

[PARTITION (partcol1=val1, partcol2=val2 ...)]

  • LOCAL是指定本地路径的标识符。这是可选的。
  • OVERWRITE是可选的,用于覆盖表中的数据。
  • PARTITION是可选的。

我们将在表格中插入以下数据。这是一个名为文本文件sample.txt的在/ home / user的目录。

1201  Gopal       45000    Technical manager

1202  Manisha      45000   Proof reader

1203 Masthanvali  40000    Technical writer

1204  Kiran        40000   Hr Admin

1205  Kranthi      30000   Op Admin

以下查询将给定的文本加载到表中。

./hcat –e "LOAD DATA LOCAL INPATH '/home/user/sample.txt'

OVERWRITE INTO TABLE employee;"

成功下载后,您会看到以下回复 -

OK

Time taken: 15.905 seconds

2 修改表

本章介绍如何更改表的属性,例如更改表名称,更改列名称,添加列以及删除或替换列。

改变表格语句

您可以使用ALTERTABLE语句来更改Hive中的表。

语法

该语句根据我们希望在表中修改的属性采用以下任何语法。

ALTER TABLE name RENAME TO new_name

ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])

ALTER TABLE name DROP [COLUMN] column_name

ALTER TABLE name CHANGE column_name new_name new_type

ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])

下面解释了一些情况。

RenameTo...语句

以下查询将雇员表格重新命名为emp。

./hcat –e "ALTER TABLE employee RENAME TO emp;"

Change语句

下表包含employee表的字段,它显示了要更改的字段(粗体)。

字段名称

从数据类型转换

更改字段名称

转换为数据类型

eid

int

eid

int

name

String

ename

String

salary

Float

salary

Double

designation

String

designation

String

以下查询使用上述数据重命名列名和列数据类型 -

./hcat –e "ALTER TABLE employee CHANGE name enameString;"

./hcat –e "ALTER TABLE employee CHANGE salary salaryDouble;"

AddColumns语句

以下查询将名为dept的列添加到employee表中。

./hcat –e "ALTER TABLE employee ADD COLUMNS (deptSTRING COMMENT 'Department name');"

Replace语句

以下查询将删除employee表中的所有列,并用emp和name列替换它-

./hcat – e "ALTER TABLE employee REPLACE COLUMNS (eid INT empid Int, ename STRING name String);"

Drop Table语句

本章介绍如何在HCatalog中删除表格。从Metastore中删除表格时,会删除表格/列数据及其元数据。它可以是一个普通表(存储在Metastore中)或外部表(存储在本地文件系统中); HCatalog以同样的方式对待它们,而不考虑它们的类型。

语法如下 -

DROP TABLE [IF EXISTS] table_name;

以下查询将删除名为employee的表-

./hcat –e "DROP TABLE IF EXISTS employee;"

在查询成功执行后,您将看到以下响应 -

OK

Time taken: 5.3 seconds

3 View

本章介绍如何在HCatalog中创建和管理视图。数据库视图是使用CREATE VIEW语句创建的。可以从单个表格,多个表格或其他视图创建视图。

要创建视图,用户必须根据特定的实现具有适当的系统特权。

Create View语句

CREATE VIEW用给定的名字创建一个视图。如果已经存在具有相同名称的表或视图,则会引发错误。您可以使用IFNOT EXISTS来跳过该错误。

如果没有提供列名称,视图列的名称将自动从定义的SELECT表达式派生。

注 -如果SELECT包含不带别名的标量表达式(如x + y),则生成的视图列名称将以_C0,_C1等形式生成

重命名列时,也可以提供列注释。注释不会自动从底层的列继承。

如果视图的定义SELECT表达式无效,则CREATE VIEW语句将失败。

语法

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name[COMMENT column_comment], ...) ]

[COMMENT view_comment]

[TBLPROPERTIES (property_name = property_value, ...)]

AS SELECT ...;

以下是员工表数据。现在让我们看看如何创建一个名为Emp_Deg_View的视图,其中包含薪水大于35,000的员工的字段id,名称,指定和薪水。

+------+-------------+--------+-------------------+-------+

ID  |   Name     | Salary |    Designation    | Dept |

+------+-------------+--------+-------------------+-------+

| 1201 |   Gopal    | 45000  | Technical manager |  TP   |

| 1202 |  Manisha   | 45000  | Proofreader       | PR   |

| 1203 | Masthanvali | 30000  | Technical writer  | TP   |

| 1204 |   Kiran    | 40000  | Hr Admin          | HR   |

| 1205 |  Kranthi   | 30000  | Op Admin          | Admin |

+------+-------------+--------+-------------------+-------+

以下是基于上述给定数据创建视图的命令。

./hcat –e "CREATE VIEW Emp_Deg_View (salary COMMENT' salary more than 35,000')

   AS SELECT id,name, salary, designation FROM employee WHERE salary ≥ 35000;"

输出

OK

Time taken: 5.3 seconds

Drop View语句

DROP VIEW删除指定视图的元数据。在删除其他视图引用的视图时,不会给出警告(依赖视图会留下无效状态,必须由用户删除或重新创建)。

语法

DROP VIEW [IF EXISTS] view_name;

以下命令用于删除名为Emp_Deg_View的视图。

DROP VIEW Emp_Deg_View;

4 Show Tables

您通常希望列出数据库中的所有表或列出表中的所有列。显然,每个数据库都有自己的语法来列出表和列。

Show Tables语句显示所有表的名称。默认情况下,它将列出当前数据库中的表或IN子句中指定的数据库中的表。

本章介绍如何列出HCatalog中当前数据库的所有表。

显示表格声明

SHOW TABLES的语法如下 -

SHOW TABLES [IN database_name] ['identifier_with_wildcards'];

以下查询显示表的列表 -

./hcat –e "Show tables;"

在查询成功执行后,您将看到以下响应 -

OK

emp

employee

Time taken: 5.3 seconds

5 ShowPartitions

分区是用于创建单独的表或视图的表格数据的条件。SHOWPARTITIONS列出给定基表的所有现有分区。分区按字母顺序列出。在Hive0.6之后,还可以指定分区规范的各个部分来过滤结果列表。

您可以使用SHOWPARTITIONS命令查看特定表中存在的分区。本章介绍如何列出HCatalog中特定表的分区。

显示分区声明

语法如下 -

SHOW PARTITIONS table_name;

以下查询将删除名为employee的表-

./hcat –e "Show partitions employee;"

在查询成功执行后,您将看到以下响应 -

OK

Designation = IT

Time taken: 5.3 seconds

动态分区

HCatalog将表组织成分区。这是根据分区列(如日期,城市和部门)的值将表分成相关部分的一种方法。使用分区,很容易查询一部分数据。

例如,名为Tab1的表包含员工数据,例如id,姓名,部门和yoj(即加入年份)。假设您需要检索2012年加入的所有员工的详细信息。查询会搜索整个表以获取所需的信息。但是,如果您将员工数据与年份进行分区并将其存储在单独的文件中,则会缩短查询处理时间。以下示例显示如何对文件及其数据进行分区 -

以下文件包含employeedata表。

/tab1/employeedata/file1

id, name,   dept, yoj

1,  gopal,   TP, 2012

2,  kiran,   HR, 2012

3,  kaleel,  SC, 2013

4, Prasanth, SC, 2013

上述数据使用年份分为两个文件。

/tab1/employeedata/2012/file2

1, gopal, TP, 2012

2, kiran, HR, 2012

/tab1/employeedata/2013/file3

3, kaleel,   SC, 2013

4, Prasanth, SC, 2013

添加分区

我们可以通过改变表格将分区添加到表格中。让我们假设我们有一个名为员工的表,其中包含Id,Name,Salary,Designation,Dept和yoj等字段。

语法

ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec

[LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;

partition_spec:

: (p_column = p_col_value, p_column = p_col_value, ...)

以下查询用于将分区添加到employee表。

./hcat –e "ALTER TABLE employee ADD PARTITION (year = '2013') location '/2012/part2012';"

重命名分区

您可以使用RENAME-TO命令来重命名分区。其语法如下 -

./hact –e "ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;"

以下查询用于重命名分区 -

./hcat –e "ALTER TABLE employee PARTITION (year=’1203’) RENAME TO PARTITION (Yoj='1203');"

删除分区

用于删除分区的命令的语法如下所示 -

./hcat –e "ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec,.

   PARTITION partition_spec,...;"

以下查询用于删除分区 -

./hcat –e "ALTER TABLE employee DROP [IF EXISTS] PARTITION (year=’1203’);"

6 Indexes

创建索引

索引只不过是表格中特定列的指针。创建索引意味着在表格的特定列上创建指针。其语法如下 -

CREATE INDEX index_name

ON TABLE base_table_name (col_name, ...)

AS 'index.handler.class.name'

[WITH DEFERRED REBUILD]

[IDXPROPERTIES (property_name = property_value, ...)]

[IN TABLE index_table_name]

[PARTITIONED BY (col_name, ...)][

   [ ROW FORMAT ...] STORED AS ...

   | STORED BY ...

]

[LOCATION hdfs_path]

[TBLPROPERTIES (...)]

让我们举一个例子来理解索引的概念。使用相同的员工,我们已经与域ID,名称,工资,型号,以及部创建一个名为索引之前使用表index_salary对工资的列职员表。

以下查询创建一个索引 -

./hcat –e "CREATE INDEX inedx_salary ON TABLE employee(salary)

AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler';"

它是一个指向薪水栏的指针。如果列被修改,则使用索引值存储更改。

删除索引

以下语法用于删除索引 -

DROP INDEX <index_name> ON <table_name>

以下查询将删除索引index_salary-

./hcat –e "DROP INDEX index_salary ON employee;"

5 API

1、Reader Writer

HCatalog包含一个用于并行输入和输出的数据传输API,无需使用MapReduce。此API使用表和行的基本存储抽象来从Hadoop集群中读取数据并将数据写入其中。

数据传输API主要包含三个类; 那些是 -

HCatReader - 从Hadoop集群读取数据。

HCatWriter - 将数据写入Hadoop集群。

DataTransferFactory - 生成读取器和写入器实例。

该API适用于主从节点设置。让我们在HCatReader和HCatWriter上进一步讨论。

HCatReader

HCatReader是HCatalog内部的一个抽象类,它抽象出检索记录的底层系统的复杂性。

Sr.No.

Method Name & Description

1

Public abstract ReaderContext prepareRead() throws HCatException

这应该在主节点被调用以获得ReaderContext,然后应该被序列化并且发送从节点。

2

Public abstract Iterator <HCatRecorder> read() throws HCaException

这应该在从节点上读取HCatRecords

3

Public Configuration getConf()

它将返回配置类对象

HCatReader类用于从HDFS读取数据。读取是一个两步过程,其中第一步发生在外部系统的主节点上。第二步在多个从节点上并行执行。

读取是在ReadEntity上完成的。在开始阅读之前,您需要定义要读取的ReadEntity。这可以通过ReadEntity.Builder完成。您可以指定数据库名称,表名,分区和过滤器字符串。例如 -

ReadEntity.Builder builder = new ReadEntity.Builder();

ReadEntity entity = builder.withDatabase("mydb").withTable("mytbl").build(); 10.

上面的代码片段定义了一个ReadEntity对象(“实体”),在名为mydb的数据库中包含一个名为mytbl的表,该表可以读取该表的所有行。请注意,此表在操作开始之前必须存在于HCatalog中。

定义ReadEntity后,您将使用ReadEntity和群集配置获取HCatReader的实例 -

HCatReader reader = DataTransferFactory.getHCatReader(entity, config);

下一步是从阅读器获取ReaderContext,如下所示 -

ReaderContext cntxt = reader.prepareRead();

HCatWriter

这个抽象是HCatalog内部的。这是为了便于从外部系统写入HCatalog。不要试图直接实例化。相反,使用DataTransferFactory。

Sr.No.

Method Name & Description

1

Public abstract WriterContext prepareRead() throws HCatException

外部系统应该只从主节点调用一次该方法。它返回一个WriterContext。这应该被序列化并发送到从节点来在那里构建HCatWriter

2

Public abstract void write(Iterator<HCatRecord> recordItr) throws HCaException

该方法应该用于从节点来执行写操作。recordItr是一个迭代器对象,它包含要写入HCatalog的记录集合

3

Public abstract void abort(WriterContext cntxt) throws HCatException

这个方法应该在主节点上调用。这种方法的主要目的是在发生故障时进行清理。

4

public abstract void commit(WriterContext cntxt) throws HCatException

这个方法应该在主节点上调用。这个方法的目的是做元数据提交。

与读取类似,写入也是一个两步过程,其中第一步发生在主节点上。随后,第二步在从节点上并行发生。

写入是在一个WriteEntity上完成的,它可以以类似于读取的方式构建 -

WriteEntity.Builder builder = new WriteEntity.Builder();

WriteEntity entity = builder.withDatabase("mydb").withTable("mytbl").build();

上面的代码创建了一个WriteEntity对象entity,该对象可用于写入数据库mydb中名为mytbl的表中。

创建WriteEntity之后,下一步是获取WriterContext -

HCatWriter writer = DataTransferFactory.getHCatWriter(entity, config);

WriterContext info = writer.prepareWrite();

以上所有步骤都发生在主节点上。主节点然后序列化WriterContext对象并使其可用于所有从属。

在从属节点上,您需要使用WriterContext获取HCatWriter,如下所示 -

HCatWriter writer = DataTransferFactory.getHCatWriter(context);

然后,writer将一个迭代器作为该write方法的参数-

writer.write(hCatRecordItr);

然后writer在一个循环中调用此迭代器上的getNext()并写出附加到迭代器的所有记录。

该TestReaderWriter.java文件用于测试HCatreader和HCatWriter类。以下程序演示了如何使用HCatReader和HCatWriter API从源文件读取数据,然后将其写入目标文件。

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.hive.metastore.api.MetaException;

import org.apache.hadoop.hive.ql.CommandNeedRetryException;

import org.apache.hadoop.mapreduce.InputSplit;

import org.apache.hive.HCatalog.common.HCatException;

import org.apache.hive.HCatalog.data.transfer.DataTransferFactory;

import org.apache.hive.HCatalog.data.transfer.HCatReader;

import org.apache.hive.HCatalog.data.transfer.HCatWriter;

import org.apache.hive.HCatalog.data.transfer.ReadEntity;

import org.apache.hive.HCatalog.data.transfer.ReaderContext;

import org.apache.hive.HCatalog.data.transfer.WriteEntity;

import org.apache.hive.HCatalog.data.transfer.WriterContext;

import org.apache.hive.HCatalog.mapreduce.HCatBaseTest;

import org.junit.Assert;

import org.junit.Test;

public class TestReaderWriter extends HCatBaseTest {

   @Test

   public void test() throws MetaException, CommandNeedRetryException,

      IOException, ClassNotFoundException {

        

      driver.run("drop table mytbl");

      driver.run("create table mytbl (a string, b int)");

        

      Iterator<Entry<String, String>> itr = hiveConf.iterator();

      Map<String, String> map = new HashMap<String, String>();

        

      while (itr.hasNext()) {

         Entry<String, String> kv = itr.next();

         map.put(kv.getKey(), kv.getValue());

      }

        

      WriterContext cntxt = runsInMaster(map);

      File writeCntxtFile = File.createTempFile("hcat-write", "temp");

      writeCntxtFile.deleteOnExit();

        

      // Serialize context.

      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(writeCntxtFile));

      oos.writeObject(cntxt);

      oos.flush();

      oos.close();

        

      // Now, deserialize it.

      ObjectInputStream ois = new ObjectInputStream(new FileInputStream(writeCntxtFile));

      cntxt = (WriterContext) ois.readObject();

      ois.close();

      runsInSlave(cntxt);

      commit(map, true, cntxt);

        

      ReaderContext readCntxt = runsInMaster(map, false);

      File readCntxtFile = File.createTempFile("hcat-read", "temp");

      readCntxtFile.deleteOnExit();

      oos = new ObjectOutputStream(new FileOutputStream(readCntxtFile));

      oos.writeObject(readCntxt);

      oos.flush();

      oos.close();

        

      ois = new ObjectInputStream(new FileInputStream(readCntxtFile));

      readCntxt = (ReaderContext) ois.readObject();

      ois.close();

        

      for (int i = 0; i < readCntxt.numSplits(); i++) {

         runsInSlave(readCntxt, i);

      }

   }

    

   private WriterContext runsInMaster(Map<String, String> config) throws HCatException {

      WriteEntity.Builder builder = new WriteEntity.Builder();

      WriteEntity entity = builder.withTable("mytbl").build();

        

      HCatWriter writer = DataTransferFactory.getHCatWriter(entity, config);

      WriterContext info = writer.prepareWrite();

      return info;

   }

    

   private ReaderContext runsInMaster(Map<String, String> config,

      boolean bogus) throws HCatException {

      ReadEntity entity = new ReadEntity.Builder().withTable("mytbl").build();

      HCatReader reader = DataTransferFactory.getHCatReader(entity, config);

      ReaderContext cntxt = reader.prepareRead();

      return cntxt;

   }

    

   private void runsInSlave(ReaderContext cntxt, int slaveNum) throws HCatException {

      HCatReader reader = DataTransferFactory.getHCatReader(cntxt, slaveNum);

      Iterator<HCatRecord> itr = reader.read();

      int i = 1;

        

      while (itr.hasNext()) {

         HCatRecord read = itr.next();

         HCatRecord written = getRecord(i++);

             

         // Argh, HCatRecord doesnt implement equals()

         Assert.assertTrue("Read: " + read.get(0) + "Written: " + written.get(0),

         written.get(0).equals(read.get(0)));

             

         Assert.assertTrue("Read: " + read.get(1) + "Written: " + written.get(1),

         written.get(1).equals(read.get(1)));

             

         Assert.assertEquals(2, read.size());

      }

        

      //Assert.assertFalse(itr.hasNext());

   }

    

   private void runsInSlave(WriterContext context) throws HCatException {

      HCatWriter writer = DataTransferFactory.getHCatWriter(context);

      writer.write(new HCatRecordItr());

   }

    

   private void commit(Map<String, String> config, boolean status,

      WriterContext context) throws IOException {

      WriteEntity.Builder builder = new WriteEntity.Builder();

      WriteEntity entity = builder.withTable("mytbl").build();

      HCatWriter writer = DataTransferFactory.getHCatWriter(entity, config);

        

      if (status) {

         writer.commit(context);

      } else {

         writer.abort(context);

      }

   }

    

   private static HCatRecord getRecord(int i) {

      List<Object> list = new ArrayList<Object>(2);

      list.add("Row #: " + i);

      list.add(i);

      return new DefaultHCatRecord(list);

   }

    

   private static class HCatRecordItr implements Iterator<HCatRecord> {

      int i = 0;

        

      @Override

      public boolean hasNext() {

         return i++ < 100 ? true : false;

      }

        

      @Override

      public HCatRecord next() {

         return getRecord(i);

      }

        

      @Override

      public void remove() {

         throw new RuntimeException();

      }

   }

}

上述程序以记录的形式从HDFS读取数据,并将记录数据写入mytable。

2、Input Output Format

HCatInputFormat和HCatOutputFormat接口用于读取从HDFS和处理之后的数据,使用MapReduce工作所得到的数据写入到HDFS。让我们详细说明输入和输出格式接口。

HCatInputFormat

该HCatInputFormat是使用MapReduce作业来读取HCatalog管理表中的数据。HCatInputFormat公开Hadoop 0.20 MapReduce API来读取数据,就好像它已经发布到表一样。

Sr.No.

Method Name & Description

1

public static HCatInputFormat setInput(Job job, String dbName, String tableName)throws IOException

设置用于作业的输入。它使用给定的输入规范查询Metastore,并将匹配分区序列化为MapReduce任务的作业配置。

2

public static HCatInputFormat setInput(Configuration conf, String dbName, String tableName) throws IOException

设置用于作业的输入。它使用给定的输入规范查询Metastore,并将匹配分区序列化为MapReduce任务的作业配置。

3

public HCatInputFormat setFilter(String filter)throws IOException

在输入表上设置一个过滤器。

4

public HCatInputFormat setProperties(Properties properties) throws IOException

设置输入格式的属性。

该HCatInputFormatAPI包含以下方法-

setInput

setOutputSchema

getTableSchema

要使用HCatInputFormat读取数据,首先使用正在读取的表中的必要信息实例化InputJobInfo,然后使用InputJobInfo调用setInput。

您可以使用setOutputSchema方法来包含投影模式,以指定输出字段。如果未指定模式,则将返回表中的所有列。您可以使用getTableSchema方法来确定指定输入表的schema。

HCatOutputFormat

HCatOutputFormat与MapReduce作业一起用于将数据写入HCatalog-managed表。HCatOutputFormat阐述了Hadoop 0.20 MapReduce API将数据写入一个表的过程。当MapReduce作业使用HCatOutputFormat写入输出时,将使用为该表配置的默认OutputFormat,并在作业完成后将新分区发布到表中。

Sr.No.

Method Name & Description

1

public static void setOutput (Configuration conf, Credentials credentials, OutputJobInfo outputJobInfo) throws IOException

设置作业的输出信息。它查询元数据服务器以查找用于该表的StorageHandler。如果分区已经发布,它会引发错误。

2

public static void setSchema (Configuration conf, HCatSchema schema) throws IOException

设置写入分区的数据的模式。如果未调用此分区,则默认使用表架构。

3

public RecordWriter <WritableComparable<?>, HCatRecord > getRecordWriter (TaskAttemptContext context)throws IOException, InterruptedException

获取该作业的RecordWriter。它使用StorageHandler的默认OutputFormat来获取RecordWriter。

4

public OutputCommitter getOutputCommitter (TaskAttemptContext context) throws IOException, InterruptedException

获取输出格式的输出提交者。它确保输出正确提交。

该HCatOutputFormatAPI包含以下方法-

setOutput

setSchema

getTableSchema

HCatOutputFormat的第一次调用必须是setOutput ; 任何其他调用都会抛出一个异常,说明输出格式未初始化。

正在写出数据的schema由setSchema方法指定。您必须调用此方法,提供您正在写出的数据schema。如果您的数据具有与表schema相同的schema,则可以使用HCatOutputFormat.getTableSchema()获取表模式,然后将其传递给setSchema()。

下面的MapReduce程序从其假定在第二列(“第1列”)中具有整数的一个表中读取数据,并且计算它找到的每个不同值的多少个实例。也就是说,它相当于”selectcol1,count(*) from $table group by col1;”。

例如,如果第二列中的值为{1,1,1,3,3,5},那么程序将生成以下值和计数输出 -

1, 3

3, 2

5, 1

现在让我们看看程序代码 –

import java.io.IOException;

import java.util.Iterator;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.conf.Configured;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.io.WritableComparable;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

import org.apache.hadoop.util.GenericOptionsParser;

import org.apache.hadoop.util.Tool;

import org.apache.hadoop.util.ToolRunner;

import org.apache.HCatalog.common.HCatConstants;

import org.apache.HCatalog.data.DefaultHCatRecord;

import org.apache.HCatalog.data.HCatRecord;

import org.apache.HCatalog.data.schema.HCatSchema;

import org.apache.HCatalog.mapreduce.HCatInputFormat;

import org.apache.HCatalog.mapreduce.HCatOutputFormat;

import org.apache.HCatalog.mapreduce.InputJobInfo;

import org.apache.HCatalog.mapreduce.OutputJobInfo;

public class GroupByAge extends Configured implements Tool {

   public static class Map extends Mapper<WritableComparable,

      HCatRecord, IntWritable, IntWritable> {

      int age;

        

      @Override

      protected void map(

         WritableComparable key, HCatRecord value,

         org.apache.hadoop.mapreduce.Mapper<WritableComparable,

         HCatRecord, IntWritable, IntWritable>.Context context

      )throws IOException, InterruptedException {

         age = (Integer) value.get(1);

         context.write(new IntWritable(age), new IntWritable(1));

      }

   }

    

   public static class Reduce extends Reducer<IntWritable, IntWritable,

      WritableComparable, HCatRecord> {

      @Override

      protected void reduce(

         IntWritable key, java.lang.Iterable<IntWritable> values,

         org.apache.hadoop.mapreduce.Reducer<IntWritable, IntWritable,

         WritableComparable, HCatRecord>.Context context

      )throws IOException ,InterruptedException {

         int sum = 0;

         Iterator<IntWritable> iter = values.iterator();

             

         while (iter.hasNext()) {

            sum++;

            iter.next();

         }

             

         HCatRecord record = new DefaultHCatRecord(2);

         record.set(0, key.get());

         record.set(1, sum);

         context.write(null, record);

      }

   }

    

   public int run(String[] args) throws Exception {

      Configuration conf = getConf();

      args = new GenericOptionsParser(conf, args).getRemainingArgs();

        

      String serverUri = args[0];

      String inputTableName = args[1];

      String outputTableName = args[2];

      String dbName = null;

      String principalID = System

        

      .getProperty(HCatConstants.HCAT_METASTORE_PRINCIPAL);

      if (principalID != null)

      conf.set(HCatConstants.HCAT_METASTORE_PRINCIPAL, principalID);

      Job job = new Job(conf, "GroupByAge");

      HCatInputFormat.setInput(job, InputJobInfo.create(dbName, inputTableName, null));

      // initialize HCatOutputFormat

      job.setInputFormatClass(HCatInputFormat.class);

      job.setJarByClass(GroupByAge.class);

      job.setMapperClass(Map.class);

      job.setReducerClass(Reduce.class);

        

      job.setMapOutputKeyClass(IntWritable.class);

      job.setMapOutputValueClass(IntWritable.class);

      job.setOutputKeyClass(WritableComparable.class);

      job.setOutputValueClass(DefaultHCatRecord.class);

        

      HCatOutputFormat.setOutput(job, OutputJobInfo.create(dbName, outputTableName, null));

      HCatSchema s = HCatOutputFormat.getTableSchema(job);

      System.err.println("INFO: output schema explicitly set for writing:" + s);

      HCatOutputFormat.setSchema(job, s);

      job.setOutputFormatClass(HCatOutputFormat.class);

      return (job.waitForCompletion(true) ? 0 : 1);

   }

    

   public static void main(String[] args) throws Exception {

      int exitCode = ToolRunner.run(new GroupByAge(), args);

      System.exit(exitCode);

   }

}

在编译上述程序之前,您必须下载一些jar并将其添加到此应用程序的类路径中。您需要下载所有Hive jar和HCatalog jar(HCatalog-core-0.5.0.jar,hive-metastore-0.10.0.jar,libthrift-0.7.0.jar,hive-exec-0.10.0.jar, libfb303-0.7.0.jar,jdo2-api-2.3-ec.jar,slf4j-api-1.6.1.jar)。

使用以下命令将这些jar文件从本地复制到HDFS并将其添加到类路径中。

bin/hadoop fs -copyFromLocal $HCAT_HOME/share/HCatalog/HCatalog-core-0.5.0.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/hive-metastore-0.10.0.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/libthrift-0.7.0.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/hive-exec-0.10.0.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/libfb303-0.7.0.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/jdo2-api-2.3-ec.jar /tmp

bin/hadoop fs -copyFromLocal $HIVE_HOME/lib/slf4j-api-1.6.1.jar /tmp

export LIB_JARS=hdfs:///tmp/HCatalog-core-0.5.0.jar,

hdfs:///tmp/hive-metastore-0.10.0.jar,

hdfs:///tmp/libthrift-0.7.0.jar,

hdfs:///tmp/hive-exec-0.10.0.jar,

hdfs:///tmp/libfb303-0.7.0.jar,

hdfs:///tmp/jdo2-api-2.3-ec.jar,

hdfs:///tmp/slf4j-api-1.6.1.jar

使用以下命令来编译和执行给定的程序。

$HADOOP_HOME/bin/hadoop jar GroupByAge tmp/hive

现在,检查输出文件(part_0000,part_0001)的输出目录(hdfs:user / tmp / hive)。

3、Loader和Storer

HCatLoader和HCatStorer的API与Pig脚本用来读取和写入HCatalog管理表中的数据。这些接口不需要HCatalog特定的设置。

HCatloader

HCatLoader与Pig脚本一起使用来从HCatalog管理的表中读取数据。使用以下语法使用HCatloader将数据加载到HDFS。

A = LOAD 'tablename' USING org.apache.HCatalog.pig.HCatLoader();

您必须用单引号指定表名:LOAD'tablename'。如果您使用的是非默认数据库,那么您必须将输入指定为“dbname.tablename”。

Hive Metastore允许您创建表而不指定数据库。如果以这种方式创建表,那么数据库名称是'default',并且在为HCatLoader指定表时不是必需的。

下表包含了HCatloader类的重要方法和描述。

Sr.No.

Method Name & Description

1

public InputFormat<?,?> getInputFormat()throws IOException

使用HCatloader类读取加载数据的输入格式。

2

public String relativeToAbsolutePath(String location, Path curDir) throws IOException

它返回绝对路径的字符串格式。

3

public void setLocation(String location, Job job) throws IOException

它设置作业可以执行的位置。

4

public Tuple getNext() throws IOException

返回循环中的当前元组(键和值)。

HCatStorer

HCatStorer与Pig脚本一起使用来将数据写入HCatalog管理的表。使用以下语法进行存储操作。

A = LOAD ...

B = FOREACH A ...

...

...

my_processed_data = ...

STORE my_processed_data INTO 'tablename' USING org.apache.HCatalog.pig.HCatStorer();

您必须用单引号指定表名:LOAD'tablename'。数据库和表都必须在运行Pig脚本之前创建。如果您使用的是非默认数据库,那么您必须将输入指定为“dbname.tablename”。

Hive Metastore允许您创建表而不指定数据库。如果以这种方式创建表,那么数据库名称是'default',您不需要在商店语句中指定数据库名称。

对于USING子句,可以有一个表示分区的键/值对的字符串参数。当您写入分区表并且分区列不在输出列中时,这是一个强制参数。不应引用分区键的值。

下表包含了HCatStorer类的重要方法和描述。

Sr.No.

Method Name & Description

1

public OutputFormat getOutputFormat() throws IOException

使用HCatStorer类读取存储数据的输出格式。

2

public void setStoreLocation (String location, Job job) throws IOException

设置执行此store应用程序的位置

3

public void storeSchema (ResourceSchema schema, String arg1, Job job) throws IOException

Store the schema.

4

public void prepareToWrite (RecordWriter writer) throws IOException

它有助于使用RecordWriter将数据写入特定文件。

5

public void putNext (Tuple tuple) throws IOException

将元组数据写入文件。

使用HCatelog运行Pig

Pig不会自动添加HCatalog的jars。为了引入必要的jar,你可以在Pig命令中使用一个标志,或者按照下面的描述设置环境变量PIG_CLASSPATH和PIG_OPTS。

为了引入与HCatalog一起工作的适当jar,只需包含以下标志 –

pig –useHCatalog <Sample pig scripts file>

设置执行的CLASSPATH

使用以下CLASSPATH设置将HCatalog与Apache Pig同步。

export HADOOP_HOME = <path_to_hadoop_install>

export HIVE_HOME = <path_to_hive_install>

export HCAT_HOME = <path_to_hcat_install>

export PIG_CLASSPATH = $HCAT_HOME/share/HCatalog/HCatalog-core*.jar:\

$HCAT_HOME/share/HCatalog/HCatalog-pig-adapter*.jar:\

$HIVE_HOME/lib/hive-metastore-*.jar:$HIVE_HOME/lib/libthrift-*.jar:\

$HIVE_HOME/lib/hive-exec-*.jar:$HIVE_HOME/lib/libfb303-*.jar:\

$HIVE_HOME/lib/jdo2-api-*-ec.jar:$HIVE_HOME/conf:$HADOOP_HOME/conf:\

$HIVE_HOME/lib/slf4j-api-*.jar

假设我们在HDFS中有一个文件student_details.txt,其中包含以下内容。

student_details.txt

001, Rajiv,    Reddy,       21, 9848022337, Hyderabad

002, siddarth, Battacharya, 22, 9848022338, Kolkata

003, Rajesh,   Khanna,      22, 9848022339, Delhi

004, Preethi,  Agarwal,     21, 9848022330, Pune

005, Trupthi,  Mohanthy,    23, 9848022336, Bhuwaneshwar

006, Archana,  Mishra,      23, 9848022335, Chennai

007, Komal,    Nayak,       24, 9848022334, trivendram

008, Bharathi, Nambiayar,   24, 9848022333, Chennai

我们还在同一个HDFS目录中有一个名为sample_script.pig的示例脚本。该文件包含对学生关系进行操作和转换的语句,如下所示。

student = LOAD 'hdfs://localhost:9000/pig_data/student_details.txt' USING

   PigStorage(',') as (id:int, firstname:chararray, lastname:chararray,

   phone:chararray, city:chararray);

    

student_order = ORDER student BY age DESC;

STORE student_order INTO 'student_order_table' USING org.apache.HCatalog.pig.HCatStorer();

student_limit = LIMIT student_order 4;

Dump student_limit;

该脚本的第一个语句会将名为student_details.txt的文件中的数据加载为名为student的关系。

脚本的第二条语句将按照年龄降序排列关系的元组,并将其存储为student_order。

第三个语句将处理的数据student_order结果存储在名为student_order_table的单独表中。

脚本的第四条语句将把student_order的前四个元组存储为student_limit。

最后,第五条语句将转储关系student_limit的内容。

现在让我们执行sample_script.pig,如下所示。

$./pig -useHCatalog hdfs://localhost:9000/pig_data/sample_script.pig

现在,检查输出文件(part_0000,part_0001)的输出目录(hdfs:user / tmp / hive)。


猜你喜欢

转载自blog.csdn.net/ancony_/article/details/79903705