---
# System prepended metadata

title: Untitled

---

使用Amazon EMR处理日志实验概述和目标 Apache Hadoop是一个开源框架，支持在一组实例上进行大规模数据处理。Hadoop可以在单个Amazon Elastic Compute Cloud（Amazon EC2）实例上运行，也可以在数千个实例上运行。Hadoop使用Hadoop分布式文件系统（HDFS）将数据存储在多个实例上，Hadoop称之为节点。Hadoop还可以从Amazon Simple Storage Service（Amazon S3）读取数据并将数据写入其中。Amazon EMR服务将核心Hadoop和其他与Hadoop相关的项目捆绑到每个版本中。在本实验中，创建EMR集群时，您将看到这些服务的列表。 在本实验中，您将使用Amazon EMR处理存储在S3存储桶中的日志。为了在Amazon EMR中处理数据，您将使用Apache Hive。Hive是一个基于Hadoop构建的开源数据仓库基础设施框架，通常用于处理大型数据集。使用Hive，您可以使用类似SQL的查询语句查询大型数据集。当您运行Hive查询时，请求将被翻译为Yet Another Resource Negotiator（YARN）作业。YARN是Hadoop软件的一部分，用于协调作业调度。 完成本实验后，您应该能够执行以下操作： 通过AWS管理控制台启动EMR集群。交互式运行Hive。使用Hive命令从存储在Amazon S3中的日志数据创建表。使用Hive命令连接表并将连接后的表存储在Amazon S3中。使用Hive查询存储在Amazon S3中的表。 持续时间完成本实验大约需要90分钟。 AWS服务限制在此实验环境中，可能仅限访问完成实验所需的AWS服务和服务操作。如果尝试访问其他服务或执行超出本实验描述的操作，可能会遇到错误。 场景另一个大学部门要求您的团队查找一组网络日志文件中的在线广告数据的趋势。由于日志轮换过程用于收集和存储日志，因此日志存在于多个文件中。已提供两种类型的日志： 展示日志：每个条目表示向用户显示的广告。点击日志：每个条目表示某人点击广告。您的挑战是开发一个概念验证（POC），以查找展示导致广告点击的趋势。 在与队友讨论了挑战后，您决定使用Amazon EMR处理此数据挑战是一个不错的选择。您知道Amazon EMR可以处理大型数据集，并且可以从Amazon S3中读取和写入数据。此外，您了解到可以使用Hive（作为Amazon EMR的一部分）构建数据仓库。然后，您可以对数据运行类似SQL的查询。 当您开始实验时，环境将包含以下图示中显示的资源。对于此实验环境，原始数据源是另一个AWS账户中的S3存储桶。 （下面是一个包含资源图示的图片）  
在实验结束时，您将创建如下图所示的附加架构。图后的表格提供了架构的详细说明。
（下面是一个包含架构图示的图片）


访问AWS管理控制台
在这些说明的顶部，选择“开始实验”。
实验会话开始。
页面顶部显示一个计时器，显示会话剩余的时间。
提示：要在任何时候刷新会话长度，请在计时器达到0:00之前再次选择“开始实验”。
在继续之前，请等待位于左上角AWS链接右侧的圆形图标变为绿色。
要连接到AWS管理控制台，请在终端窗口上方的左上角选择AWS链接。
会打开一个新的浏览器选项卡，将您连接到控制台。
提示：如果没有打开新的浏览器选项卡，通常浏览器顶部会有一个横幅或图标，显示浏览器阻止打开弹出窗口的站点。选择横幅或图标，然后选择允许弹出窗口。
此外，如果您看到“您登录链接中的凭据无效...要注销，请单击此处”消息，请选择“此处”链接，然后再次双击这些说明上方的AWS链接。
任务1：启动Amazon EMR集群
在此任务中，您将启动一个安装有Hive的EMR集群。
要访问EMR控制台，请在“服务”右侧的搜索框中搜索并选择EMR。
启动创建EMR集群的过程。
选择“创建集群”。 在页面顶部，在“创建集群-快速选项”右侧，选择“转到高级选项”。
配置第1步：软件和步骤的选项。
在软件配置部分，选择emr-5.29.0作为版本。
确保选择了以下应用程序：
Hadoop 2.8.5 
Hive 2.3.6 
取消选择其他所有选定的应用程序（例如Hue和Pig）。
保留其他默认设置，然后选择“下一步”。
分析：您选择的Amazon EMR版本确定了将在集群上安装的Hadoop版本。您还可以安装许多其他与Hadoop相关的项目，例如Hadoop用户体验（Hue）、Pig和Spark。但是，在此实验中，您只需要Hadoop和Hive。
Hadoop将安装和配置集群的内部HDFS以及用于处理集群上的作业的YARN资源调度程序和协调器。Hive是一个开源框架，可用于存储和查询大型数据集。Hive是一个抽象层，将SQL查询转换为在HDFS中存储的数据上运行和提取结果的YARN作业。Hue和Pig是Hadoop框架的其他组件，在此实验中不需要使用。
配置第2步：硬件的选项。
在网络部分：
对于网络，请选择Lab VPC。 对于EC2子网，请选择Lab子网。 在群集节点和实例部分，设置
要使用的实例类型和节点数量：
注意：在控制台上，您可能会看到将主节点称为主节点。本说明将使用术语"主节点"。
对于主节点类型，请选择实例类型旁边的铅笔图标。从列表中选择m4.large，然后选择保存。
对于核心节点类型，重复相同的过程。
重要提示：由于实验安全设置的限制，如果您不按照指示更改实例类型，EMR集群创建将失败。
验证每个节点类型的实例计数如下：主节点为1，核心节点为2，任务节点为0。
分析：主节点协调将在集群上运行的作业。主节点运行HDFS NameNode以及YARN ResourceManager。核心节点充当HDFS DataNode，并在磁盘上复制和存储HDFS数据。这些节点还根据YARN的指示运行MapReduce任务。任务节点是一个可选项，可以支持并行处理和Spot实例类型，但在本实验中不需要使用。有关HDFS、YARN、MapReduce和其他Hadoop主题的更多信息，请参阅Apache Hadoop网站。
保留其他默认设置，然后选择“下一步”。
配置第3步：常规集群设置的选项。
对于集群名称，请输入"Hive EMR cluster"。
确保选择了日志记录。
对于S3文件夹，请选择文件夹图标，并选择为Hive输出创建的S3存储桶。存储桶名称的格式为
```
s3://hive-output-xxxxxx/（其中xxxxxx是一个唯一字符串）。
```
选择"选择"。
取消选择调试和终止保护选项。
保留其他默认设置，然后选择“下一步”。
配置第4步：安全性的选项。
对于EC2密钥对，请选择已经存在于此帐户中的vockey密钥对。
注意：您将在此实验中将此密钥对下载为labsuser.pem。Vockey和labsuser.pem是同一密钥对。
对于权限，请选择"自定义"。
对于EMR角色，请确认选择了EMR_DefaultRole。
对于EC2实例配置文件，请确认选择了EMR_EC2_DefaultRole。
对于自动扩展角色，请选择"不使用角色继续"。
展开EC2安全组部分。请注意，Amazon EMR将为主节点创建一个安全组，为核心节点和任务节点创建另一个安全组。保留这些默认设置。
选择"创建集群"完成集群创建。
现在，您的集群将被预配。在继续下一步之前，请不要等待预配过程完成。
提示：您可以忽略警告消息，该消息指出在使用此版本的EMR时，此帐户不支持自动终止。
配置主节点的安全组，以允许从AWS Cloud9实例进行SSH连接。
在集群的摘要选项卡上，转到安全性和
访问部分。
在主节点的安全组旁边，选择安全组的链接。如果尚未看到链接，请刷新页面。可能需要一两分钟才能出现链接。
一个新的选项卡将在Amazon EC2控制台中打开到安全组页面。
选择主节点的安全组。
提示：您可能需要展开安全组名称列才能看到完整名称。
在底部窗格中，选择入站规则选项卡，然后选择编辑入站规则。
在页面底部，选择添加规则，然后为为您创建的AWS Cloud9实例配置SSH访问：
类型：选择SSH。
来源：选择Anywhere-IPv4。
注意：在生产环境中，对于来源，您通常会将SSH访问仅限制为更有限的IP地址范围。例如，您可以指定特定的安全组。但是，在此实验中，为了在提交时获得完整的工作信用，请保持Anywhere-IPv4设置。
选择保存规则。
注意：在下一个任务中，您将使用AWS Cloud9实例中可用的bash终端通过SSH连接到EMR集群。这就是为什么您要将入站SSH连接的允许来源设置为使用AWS Cloud9安全组的EC2实例。
确认集群现在可用。
返回到仍然打开的Amazon EMR控制台。
刷新页面。
在网络和硬件部分，验证主节点和核心节点类型的状态为"正在运行"。
提示：自从创建集群以来，可能需要多达10分钟才能完成预配。刷新页面以更新状态。
重要提示：在集群的状态显示为"等待"且节点的状态显示为"正在运行"之前，请不要继续下一个任务。
在此任务中，您创建了一个运行Hive的EMR集群。还配置了集群中的主节点的安全组，以接受SSH连接。
任务2：使用SSH连接到Hadoop主节点
在此任务中，您将使用SSH客户端和Amazon EC2密钥对私钥连接到Amazon EMR的主节点。
在集群摘要选项卡上，在摘要部分，找到主节点的公共DNS地址。将该值复制到剪贴板。
连接到AWS Cloud9 IDE。
在"服务"右侧的搜索框中搜索并选择Cloud9，打开AWS Cloud9控制台。
对于Cloud9实例环境，请选择"打开IDE"。
在IDE中，选择"文件" > "新建文件"。
将剪贴板中的公共DNS值粘贴到文件中。
您很快将使用此值。
将SSH密钥复制到AWS Cloud9实例并进行配置。
在这些实验说明上方，选择"AWS详细信息"。
在打开的面板中，选择"下载PEM"，并将文件保存到您选择的目录中。
返回AWS Cloud9 IDE。
选择"文件" > "上传本地文件..."。
将labsuser.pem文件
上传到AWS Cloud9 IDE中。
注意：上传文件后，它将出现在IDE左侧环境窗口的文件列表中的Cloud9实例文件夹下。
关闭"上传文件"对话框。
接下来，为了使SSH软件允许您使用密钥对私钥，您需要在密钥对文件上修改权限。在IDE的终端选项卡中运行以下命令：
```
chmod 400 labsuser.pem
```
建立与集群主节点的SSH连接。
运行以下命令。将<PUBLIC-DNS>替换为您之前复制的主节点的公共DNS地址。
```
ssh -i labsuser.pem hadoop@<PUBLIC-DNS>
```
注意使用hadoop用户登录。通过使用此用户登录，您将能够访问Hive客户端。
当提示是否继续连接时，输入yes。
类似以下消息表示连接成功。

注意：由于您提供了正确的密钥对进行身份验证，因此不会提示输入密码。请记住，当您创建集群时，您指定了vockey作为要使用的Amazon EC2密钥对。
现在，您通过使用SSH从AWS Cloud9实例连接到正在运行的Amazon EMR主节点，该主节点位于一个EC2实例上。
恭喜！在这个任务中，您成功通过使用AWS Cloud9终端连接到了集群的主节点。在下一个任务中，您将使用终端运行Hive命令。
任务3：运行交互式Hive 在这个任务中，您将为Hive配置一个日志目录，然后在EMR集群的主节点上启动一个交互式Hive会话。
要为Hive创建一个日志目录，请运行以下命令：
```
sudo chown hadoop -R /var/log/hive
mkdir /var/log/hive/user/hadoop
```
注意：当运行Hive客户端时，该目录应存在。您将在稍后的步骤中使用Hive客户端。
配置Hive。
运行以下命令以检索要存储Hive输出的S3存储桶的名称：
```
aws s3 ls /
```
运行以下命令。将 <hive-output bucket> 替换为 hive-output 存储桶的完整名称。
```
hive -d SAMPLE=s3://aws-tc-largeobjects/CUR-TF-200-ACDENG-1/emr-lab -d DAY=2009-04-13 -d HOUR=08 -d NEXT_DAY=2009-04-13 -d NEXT_HOUR=09 -d OUTPUT=s3://<HIVE-BUCKET-NAME>/output/
```
该命令需要几秒钟的时间来运行，然后显示以下输出。这表示您现在已连接到交互式 Hive 客户端：
Logging initialized using configuration in file:/etc/hive/conf.dist/hive-log4j2.properties Async: true
hive> 
分析：该命令调用了Hive程序。请注意您指定的-d参数。每个参数定义了会话中的不同键值对。例如，SAMPLE键/值对指定您要查询的Amazon S3中的数据位置。这些数据位于您AWS帐户之外的存储桶中。OUTPUT键值对指定了查询结果的输出位置。在这种情况下，您指定了一个存在于您AWS帐户中的S3存储桶作为存储任何Hive查询结果的位置。
很棒！在这个任务中，您配置了Hive的日志记录并建立了与Hive的连接。
任务4：使用Hive从源数据创建表 在这个任务中，您将创建两个Hive表，这些表将组成您的数据仓库。这些表将引用存储在Amazon S3中的数据。这些表将作为您稍后在实验中运行的查询的输入数据。在这个任务中，您将使用HiveQL，一种类似于SQL的语言，来加载数据和运行查询。
要创建一个名为impressions的外部表，请在AWS Cloud9终端中运行以下代码：
```
CREATE EXTERNAL TABLE impressions (
requestBeginTime string,
adId string,
impressionId string,
referrer string,
userAgent string,
userCookie string,
ip string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe' with serdeproperties
('paths'='requestBeginTime, adId, impressionId, referrer, userAgent, userCookie, ip')
LOCATION '${SAMPLE}/tables/impressions';
```
The output is similar to the following:
```
OK
Time taken: 12.599 seconds
```
分析：请注意，此命令创建了一个外部表。当创建外部表时，表数据不会被复制到HDFS中。如果您没有指定external，表数据将被复制到HDFS中。该表的数据仍然存储在Amazon S3中。如果将来删除此外部表，数据将不会从Amazon S3中删除。
如命令中的LOCATION部分所示，Hive被告知数据位于在上一任务中启动Hive时使用的SAMPLE键值对中指定的S3存储桶中。在该存储桶中，有一个名为tables的文件夹，其中包含一个名为impressions的子文件夹。impressions文件夹包含分区数据。
如果您熟悉关系型数据库，在其中您首先定义表结构，然后将数据插入到表中，那么您在这里所做的可能会显得有些反常和令人困惑。您所做的是将Hive指向现有数据。这些现有数据具有结构，在创建表命令中，您通知Hive该结构是什么。
以下是您在Amazon S3中指向的数据的一行。数据中包含数千行类似于这样的数据。在这里，为了方便阅读，将数据显示为多行，但在源数据中，所有这些信息都在一行上。此源数据采用JSON格式，并具有16个一级名称-值对。但是，您的表定义仅引用其中的七个。因此，您的表仅引用了部分源数据。
```
{
"number": "348309",
"referrer": "example.com",
"processId": "1505",
"adId": "2h8VvmXWGFrm4tAGoKPQ3UfWj3g4Jt",
"browserCookie": "bxsbcgatmx",
"userCookie": "CbHCJK7atU0RrnX4GAlh0w1kcvbuIJ",
"requestEndTime": "1239581899000",
"impressionId": "OtGijGGr0OjjUXnj181fXXsql7G3f6",
"userAgent": "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; InfoPa",
"timers": {
"modelLookup": "0.2444",
"requestTime": "0.7636"
},
"threadId": "98",
"ip": "22.68.182.56",
"modelId": "bxxiuxduab",
"hostname": "ec2-64-28-73-15.amazon.com",
"sessionId": "APrPRwrrXhwPUwsIKuOCCHpHSDTfxW",
"requestBeginTime": "1239581898000"
}
```
如果您回顾创建表时使用的语句，请注意在定义行格式时，您引用了一个JSON序列化器/反序列化器（称为SerDe）来解析源数据。
更新impressions表的Hive元数据，以包括所有分区。
要查看impressions表当前有多少分区，请运行以下命令：
describe formatted impressions;
输出描述了列名、数据位置、分区数量和关于表的其他元数据。numPartitions行应该显示为0。
要检查输入数据并将分区应用于元数据存储，运行以下命令：
set hive.msck.path.validation=ignore;
MSCK REPAIR TABLE impressions;
注意：MSCK REPAIR TABLE命令会扫描Amazon S3，寻找在创建表之后添加到文件系统中的与Hive兼容的分区。如果找到分区，它们将被添加到表的元数据中。该命令是AWS版本的Hive中的扩展命令。
命令运行完成后，输出类似于以下内容：
```
[truncated]...
Repair: Added partition to metastore impressions:dt=2009-04-14-12-10
Repair: Added partition to metastore impressions:dt=2009-04-14-12-15
Repair: Added partition to metastore impressions:dt=2009-04-14-12-20
Repair: Added partition to metastore impressions:dt=2009-04-14-13-00
Time taken: ...[truncated]

Run the following command again:
describe formatted impressions;
```    

现在输出应该显示表中存在241个分区。
分析：分区通过逻辑上的组织来存储数据，以提高查询性能。通常，您将数据分割为分区，以便更快地访问特定子集的数据。例如，针对此日志数据的查询很可能是基于时间戳的，因此此数据被基于时间进行了分区。这是您在创建表时指定的。

创建另一个外部表，并再次查看其分区。此表的名称为clicks，它引用点击流日志。
运行以下命令创建表：
```
CREATE EXTERNAL TABLE clicks (impressionId string, adId string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
WITH SERDEPROPERTIES ('paths'='impressionId')
LOCATION '${SAMPLE}/tables/clicks';
```
以下示例是来自clicks源日志的单行条目。正如您所看到的，日志中有比您提取到表中的数据更多的信息；但是，您确实提取了impressionId和adId的值。
```
{
"number": "8673",
"processId": "1010",
"adId": "S5KtvIerGRLpNxjnkn4MdRH2GqOq5A",
"requestEndTime": "1239612672000",
"impressionId": "PEWl8ecT2D77hdVce8oXdgtPe1m7kr",
"timers": {
"requestTime": "0.9578"
},
"threadId": "100",
"hostname": "ec2-0-51-75-39.amazon.com",
"requestBeginTime": "1239612671000"
}
```
To return all partitions from the click-stream log data, run the following command:
```
MSCK REPAIR TABLE clicks;
```
该命令可能需要大约20秒才能运行并返回到hive>提示符。
验证现在存在这两个表。
运行以下命令：
```
show tables;
```
输出返回存储在Amazon S3中的两个外部表的名称：clicks和impressions。
要描述clicks表，请运行以下命令：
```
describe formatted clicks;
```    

完美！在这个任务中，您成功创建了两个外部Hive表，现在可以用它们来查询数据。
任务5：使用Hive进行表连接 在本实验的这个部分，您将使用Hive将impressions表与clicks表进行连接。通过将向用户展示的广告信息（impressions数据）与用户选择广告的信息（clicks数据）进行组合，您可以了解用户行为，并针对广告服务进行定位和变现。
以下图示说明了您在本任务中要完成的内容。

clicks和impressions两个表都是分区表。当这两个表进行连接时，CREATE TABLE命令将告诉新表也进行分区。
要创建一个名为joined_impressions的新外部表，请运行以下命令：
```
CREATE EXTERNAL TABLE joined_impressions (
requestBeginTime string,
adId string,
impressionId string,
referrer string,
userAgent string,
userCookie string,
ip string,
clicked Boolean)
PARTITIONED BY (day string, hour string)
STORED AS SEQUENCEFILE
LOCATION '${OUTPUT}/tables/joined_impressions';
```
分析：joined_impressions表定义了与impressions表相同的七个列；但是，新表还包含了一个名为clicked的第八个列。
与您创建的前两个表（impressions和clicks）不同，这个表的数据位置是您定义的一个新位置，目前还没有数据。
STORED AS SEQUENCEFILE子句在数据存储之前对数据进行了压缩。使用这种本机的Hadoop压缩格式将比保留数据的JSON格式获得更好的性能。在数据存储为JSON格式时，您需要使用SerDe来读取数据，但是在使用存储为SEQUENCEFILE格式时，您将不再需要SerDe。
到目前为止，该表还没有任何数据。当数据添加时，它将存储在hive-output S3存储桶中。
为了在HDFS中创建一个名为tmp_impressions的新临时表来存储中间数据，请运行以下命令：
```
CREATE TABLE tmp_impressions (
requestBeginTime string,
adId string,
impressionId string,
referrer string,
userAgent string,
userCookie string,
ip string)
STORED AS SEQUENCEFILE;
```
分析：这个表将在本地HDFS分区中存储临时数据。您知道它存储在HDFS中（而不是S3），因为命令没有指定EXTERNAL作为表类型。该表具有与impressions表相同的列名。
要插入所引用的时间段的impression日志数据，请运行以下命令：
```
INSERT OVERWRITE TABLE tmp_impressions
SELECT
from_unixtime(cast((cast(i.requestBeginTime as bigint) / 1000) as int)) requestBeginTime,
i.adId,
i.impressionId,
i.referrer,
i.userAgent,
i.userCookie,
i.ip
FROM impressions i
WHERE i.dt >= '${DAY}-${HOUR}-00'
AND i.dt < '${NEXT_DAY}-${NEXT_HOUR}-00';
```

该命令运行了一个MapReduce作业来处理请求。输出类似于以下图像：

分析：INSERT OVERWRITE TABLE命令将使用新数据替换tmp_impressions表中的任何现有数据。
SELECT命令从impressions表中选择数据，但只选择与特定时间段相对应的记录。由于impressions表是按照requestBeginTime分区的，只有与指定时间范围相关的分区才会被读取，这提高了性能。
分区表的命名语法为[分区列]=[分区值]。例如，dt=2009-04-13-05，其中dt（日期/时间）是分区列名，2009-04-13-05是分区值。
时间段的起始是DAY-HOUR，时间段的结束是NEXT_DAY-NEXT_HOUR。NEXT_DAY是下一个时间段的日期。它与${DAY}仅在处理一天的最后一个小时时不同。在这种情况下，时间段结束于下一天。
Hive将SELECT查询转换为分布式的MapReduce应用程序。主节点将应用程序分发到核心节点。这在您希望利用分布式处理的能力来存储和查询数据时非常有用，而无需编写自己的MapReduce应用程序（例如使用Java等编程语言）。
创建一个名为tmp_clicks的临时表，并将数据插入该表。
要创建表，请运行以下命令：
```
CREATE TABLE tmp_clicks ( impressionId string, adId string )
STORED AS SEQUENCEFILE;
```
要将数据插入tmp_clicks表中，请运行以下命令：
```
INSERT OVERWRITE TABLE tmp_clicks
SELECT impressionId, adId
FROM clicks c
WHERE c.dt >= '${DAY}-${HOUR}-00'
AND c.dt < '${NEXT_DAY}-${NEXT_HOUR}-20';
```
该命令启动另一个MapReduce作业。输出与下面的图像类似。完成该作业大约需要1分钟时间。

分析：对于tmp_clicks表，分析的时间段比tmp_impressions表中捕获的时间段长20分钟。这样确保了在广告显示后20分钟内发生的任何广告点击仍会出现在结果集中。
创建tmp_clicks和tmp_impressions的左外连接，并将生成的数据集写入到S3输出存储桶中的joined_impressions表中，请运行以下命令：
```
INSERT OVERWRITE TABLE joined_impressions
PARTITION (day='${DAY}', hour='${HOUR}')
SELECT
i.requestBeginTime,
i.adId,
i.impressionId,
i.referrer,
i.userAgent,
i.userCookie,
i.ip,
(c.impressionId is not null) clicked
FROM tmp_impressions i
LEFT OUTER JOIN tmp_clicks c ON i.impressionId=c.impressionId;
```
另一个MapReduce作业正在运行。它大约需要30秒的时间。输出应该类似于以下内容：

分析：左外连接返回tmp_impressions中的所有记录，即使连接条件在tmp_clicks表中找不到匹配的记录也是如此。如果在tmp_clicks中找不到匹配的记录，每列将返回null值。
左外连接排除了在所选时间段内未从impressions中衍生的任何tmp_clicks数据。
由于joined_impressions表存储在Amazon S3中，输出可以供其他EMR集群使用。
恭喜！在这个任务中，您成功地将两个源表的数据合并到一个可查询的表中。以下图表总结了您的成果，并显示了每个表的数据所在位置。

因为您将非临时数据存储在Amazon S3中，所以可以随时访问它。例如，您可能不希望长时间保持该集群运行，因为与仅存储数据相比，运行服务器的成本相对较高。通过将数据存储在Amazon S3中，您可以随时删除该集群，然后在以后需要运行更多查询时，创建一个新的集群连接到相同的数据。
任务6：查询生成的数据集 在此任务中，您将使用Hive对现在存在于joined_impressions表中的数据运行类似SQL的查询。这将使您能够分析哪些impressions导致了广告点击。
使用类似SQL的查询来查询生成的数据集。
为了让HiveSQL客户端在结果集中打印列名作为标题，请运行以下命令
```
set hive.cli.print.header=true;
```

为了返回joined_impressions表中的前10行数据，请运行以下SELECT命令：
```
SELECT * FROM joined_impressions LIMIT 10;
```
结果应该很快返回。以下屏幕截图显示了结果中返回的10行数据的前几列：

这证明了该表含有数据。
现在运行一个更有趣的查询。
```
SELECT adid, count(*) AS hits FROM joined_impressions WHERE clicked = true GROUP BY adid ORDER BY hits DESC LIMIT 10;
```
这个查询返回了在您正在分析的那个小时内点击量最高的20个广告的adId值。看起来在那段时间里，adId为70n4fCvgAV0wfojgw5xw3QAEiaULMg的广告是被点击最多的。这很有趣。但是更有趣的是找出哪些推荐网站为点击最多广告的用户提供了访问者。推荐网站是指将访问者发送到您正在分析的网站的网站。
接下来，您将学习如何从Hive外部运行Hive查询。
要退出Hive CLI，请运行以下命令：
```
exit;
```
您会发现提示符不再显示为hive>。相反，提示符应该是[hadoop@ip-xx-xx-xx-xx ~]$的格式，这表示您仍然从AWS Cloud9实例连接到一个EMR集群实例。
继续对数据集运行SQL查询。
接下来，运行以下命令：
```
hive -e "SELECT referrer, count(*) as hits FROM joined_impressions WHERE clicked = true GROUP BY referrer ORDER BY hits DESC LIMIT 10;" > /home/hadoop/result.txt
```
该查询将返回前十个最有效的网站推荐者的列表，这意味着这些推荐导致了最多的广告点击。结果将被写入一个文件。
当前面的命令完成后，运行以下命令来读取结果：
```
cat /home/hadoop/result.txt
```
正如您所看到的，现在您已经将表数据加载到了Amazon EMR中，并学会了如何使用Hive进行类似SQL的查询，您拥有了进行趋势分析的工具。
要退出SSH会话，请运行以下命令：
```
exit
```
现在提示符应该显示为voclabs:~/environment $。
分析Amazon S3输出中的日志文件之一。
要重新查找包含joined_impressions表数据的存储桶的名称，请运行以下命令：
```
aws s3 ls /
```
接下来，要下载包含您查询的数据的文件，请运行以下命令（确保将<bucket-name>替换为实际的hive-output存储桶名称）
```
aws s3 cp s3://<bucket-name>/output/tables/joined_impressions/day=2009-04-13/hour=08/000000_0 example-log.txt
```
在环境窗口的文件列表中出现了一个新的example-log.txt文件，位于IDE左侧。
打开example-log.txt文件，然后查看其中的内容。
分析：回想一下，当您创建joined_impressions表时，您指定了数据应以Sequence格式存储。这不是一个普通的文本文件，但Hadoop可以解析它。这就是为什么这个文件的一些内容在文本编辑器中显示不好的原因。
恭喜！在这个实验中，您创建了一个EMR集群，然后使用Hive基于两组合并的日志文件创建了一个数据仓库。然后，您能够运行查询来发现数据中的一些趋势，比如哪些推荐网站导致用户频繁点击广告。
您的POC成功地展示了如何处理这个大型数据集。通过更多的分析，您可以从这个数据集中揭示更多有意义的信息。例如，您可以构建一个分析仪表板，以更友好的方式展示数据。您将在以后的实验中进行这项工作。

