24、Hive与AWS及HCatalog的使用指南

Hive与AWS及HCatalog的使用指南

1. Hive与AWS相关操作

在使用Hive与AWS的过程中,有多种操作和配置需要注意。

1.1 自定义启动脚本

使用自定义启动脚本的优势在于能更严格地控制其在工作流生命周期中的执行时间,但需要自行管理调用。另外,使用文件存储Hive初始化查询的一个附带好处是可以通过版本控制跟踪DDL的更改。不过,当元信息随着表和分区的增多而变大时,启动时间会变长,因此如果表或分区较多,不建议使用此方法。

1.2 MySQL转储到S3

另一种方法是在终止集群前备份元存储,并在下一个工作流开始时恢复。S3是在集群不使用时持久保存备份的好地方。需要注意的是,在EMR集群上运行的不同版本的Hive之间,元存储是不共享的。若要在不同Hive版本间共享元数据,需使用外部持久元存储。

1.3 HDFS和S3在EMR集群中的角色

HDFS和S3在EMR集群中有不同的角色,具体如下表所示:
| 存储类型 | 特点 | 使用建议 |
| ---- | ---- | ---- |
| HDFS | 由核心实例组节点的临时存储组成,集群终止后数据丢失 | 存储处理的中间结果 |
| S3 | 为EMR集群相关数据提供持久存储 | 存储集群的输入数据和最终处理结果 |

使用S3作为输入数据源会失去Hadoop数据本地化优化,若此优化对分析至关重要,可在处理前将“热”数据从S3导入HDFS。

1.4 将资源、配置和引导脚本上传到S3

应将所有引导脚本、配置脚本(如hive-site.xml和.hiverc)、资源(如需要放入分布式缓存的文件、UDF或流式JAR)等上传到S3。例如,可在.hiverc中添加以下内容:

ADD FILE s3n://example.hive.oreilly.com/files/my_file.txt;
ADD JAR s3n://example.hive.oreilly.com/jars/udfs.jar;
CREATE TEMPORARY FUNCTION my_count AS 'com.oreilly.hive.example.MyCount';
1.5 S3上的日志

Amazon EMR将日志文件保存到log-uri字段指向的S3位置。该字段可在elastic-mapreduce Ruby客户端安装目录的credentials.json文件中设置,也可在启动集群时使用–log-uri标志指定或覆盖。若未设置该字段,日志将无法在S3上获取。同时,若工作流配置为在作业出错时终止,设置log-uri可在集群终止后仍能在S3上获取日志,有助于调试,但需定期清除不必要的日志以节省存储成本。

1.6 现货实例

现货实例允许用户对未使用的亚马逊容量进行投标,以低于按需价格的费率获取实例。使用现货实例有以下两种情况:
- 所有实例组都使用现货实例:整个集群可能在工作流的任何阶段终止,导致中间数据丢失。若重复计算成本低,这可能不是严重问题;也可定期将中间数据持久化到S3,前提是作业能从这些快照重新开始。
- 仅任务实例组使用现货节点:若这些节点因不可用或现货价格上涨而被移除,工作流将继续使用主节点和核心节点,且不会丢失数据。节点重新加入集群后,可将MapReduce任务委派给它们,加快工作流。

使用elastic-mapreduce Ruby客户端订购现货实例的示例命令如下:

elastic-mapreduce --create --alive --hive-interactive \
--name "Test Spot Instances" \
--instance-group master --instance-type m1.large \
--instance-count 1 --instance-group core \
--instance-type m1.small --instance-count 2 --instance-group task \
--instance-type m1.small --instance-count 2 --bid-price 0.10

使用Java SDK启动类似集群的配置示例如下:

InstanceGroupConfig masterConfig = new InstanceGroupConfig()
.withInstanceCount(1)
.withInstanceRole("MASTER")
.withInstanceType("m1.large");
InstanceGroupConfig coreConfig = new InstanceGroupConfig()
.withInstanceCount(2)
.withInstanceRole("CORE")
.withInstanceType("m1.small");
InstanceGroupConfig taskConfig = new InstanceGroupConfig()
.withInstanceCount(2)
.withInstanceRole("TASK")
.withInstanceType("m1.small")
.withMarket("SPOT")
.withBidPrice("0.05");

需要注意的是,若依赖过多现货实例,作业时间可能不可预测或因TaskTrackers被移除而完全失败。

1.7 安全组

Hadoop JobTracker和NameNode用户界面分别在EMR主节点的9100和9101端口可访问,可使用ssh隧道或动态SOCKS代理查看。若要从客户端机器的浏览器查看,需通过AWS Web控制台修改Elastic MapReduce主安全组,添加新的自定义TCP规则,允许客户端机器IP地址在9100和9101端口的入站连接。

1.8 EMR与EC2和Apache Hive对比

与EMR相比,启动多个Amazon EC2节点并在自定义AMI上安装Hadoop和Hive能让用户更好地控制Hive和Hadoop的版本和配置,但Apache Hive版本可能不具备EMR的一些定制功能。例如,S3文件系统在Apache Hive上不完全支持,且减少亚马逊S3查询启动时间的优化仅在EMR Hive中可用,可通过在hive-site.xml中添加以下内容启用:

<property>
  <name>hive.optimize.s3.query</name>
  <value>true</value>
  <description> Improves Hive query performance for Amazon S3 queries
  by reducing their start up time </description>
</property>

或者在Hive CLI中运行以下命令:

set hive.optimize.s3.query=true;

另外,若分区存在于HDFS或S3的正确目录结构中,可使用以下命令恢复分区:

ALTER TABLE emr_table RECOVER PARTITIONS;

创建表的语句示例如下:

CREATE EXTERNAL TABLE emr_table(id INT, value STRING)
PARTITIONED BY (dt STRING)
LOCATION 's3n://example.hive.oreilly.com/tables/emr_table';
2. HCatalog介绍

HCatalog的出现是为了满足在Hadoop上使用其他工具的用户访问Hive元存储的需求。它具有以下特点:
- 提供MapReduce和Pig的连接器,使用户能读写Hive仓库中的数据。
- 提供命令行工具,让不使用Hive的用户可以使用Hive DDL语句操作元存储。
- 提供通知服务,使工作流工具(如Oozie)能在仓库中有新数据可用时得到通知。

HCatalog是一个独立于Hive的Apache项目,目前最新版本是HCatalog 0.4.0 - incubating,可与Hive 0.9、Hadoop 1.0和Pig 0.9.2配合使用。

3. MapReduce与HCatalog结合使用
3.1 读取数据

MapReduce使用Java类InputFormat读取输入数据,HCatalog提供HCatInputFormat,使MapReduce用户能读取Hive数据仓库中的数据。其操作步骤如下:
1. 创建InputJobInfo类,指定要读取的数据库、表和分区过滤器:

InputJobInfo inputInfo =  InputJobInfo.create(dbName, inputTableName, filter);

其中,databaseName表示Hive数据库(或模式),若为null则使用默认数据库;tableName为要读取的表名,必须有效;filter为分区过滤器,格式为类似SQL的where子句,如“datestamp = ‘2012 - 05 - 26’”。需要注意的是,Hive v0.9.0及更早版本的ORM映射层存在一个bug,会导致包含>、>=、<或<=的过滤子句失败,可通过应用补丁HIVE - 2084.D2397.1.patch解决。
2. 将InputJobInfo实例传递给HCatInputFormat:

Job job = new Job(conf, "Example");
HCatInputFormat.setInput(job, inputInfo);
  1. 映射任务需指定HCatRecord作为值类型,示例如下:
public static class Map extends
    Mapper<WritableComparable, HCatRecord, Text, Text> {
    @Override
    protected void map(
        WritableComparable key,
        HCatRecord value,
        org.apache.hadoop.mapreduce.Mapper<WritableComparable,
            HCatRecord, Text, HCatRecord>.Context context) {
        ...
    }
}

HCatRecord提供简单的get和set接口,可按位置或名称请求记录。若不想读取输入中的所有列,可在作业配置时传递描述所需列的模式,示例如下:

HCatSchema baseSchema = HCatBaseInputFormat.getOutputSchema(context);
List<HCatFieldSchema> fields = new List<HCatFieldSchema>(2);
fields.add(baseSchema.get("user"));
fields.add(baseSchema.get("url"));
HCatBaseInputFormat.setOutputSchema(job, new HCatSchema(fields));
3.2 写入数据

写入数据时,需指定要写入的数据库和表,若写入分区表且只写一个分区,还需指定分区。操作步骤如下:
1. 创建OutputJobInfo实例:

OutputJobInfo outputInfo = OutputJobInfo.create(dbName, outputTableName, partitionValues);

其中,databaseName和tableName含义与读取数据时相同,partitionValues表示要创建的分区,若表未分区,该字段可留空。若要进行动态分区,分区列的值必须存在于数据中。
2. 将OutputJobInfo实例传递给HCatOutputFormat:

HCatOutputFormat.setOutput(job, outputInfo);
  1. 写入时,输出键类型不重要,值必须为HCatRecord,可从归约器或仅映射作业的映射任务中写入记录。

以下是一个完整的示例代码,用于从表rawevents中读取日期戳为20120531的分区,统计每个用户的事件数量,并将结果写入表cntd:

public class MRExample extends Configured implements Tool {
    public static class Map extends
        Mapper<WritableComparable, HCatRecord, Text, LongWritable> {
        protected void map(WritableComparable key,
                           HCatRecord value,
                           Mapper<WritableComparable, HCatRecord,
                             Text, LongWritable>.Context context)
                           throws IOException, InterruptedException {
            // Get our schema from the Job object.
            HCatSchema schema = HCatBaseInputFormat.getOutputSchema(context);
            // Read the user field
            String user = value.get("user", schema);
            context.write(new Text(user), new LongWritable(1));
        }
    }
    public static class Reduce extends Reducer<Text, LongWritable,
        WritableComparable, HCatRecord> {
        protected void reduce(Text key, Iterable<LongWritable> values,
            Reducer<Text, LongWritable,
            WritableComparable, HCatRecord>.Context context)
            throws IOException ,InterruptedException {
            List<HCatFieldSchema> columns = new ArrayList<HCatFieldSchema>(2);
            columns.add(new HCatFieldSchema("user", HCatFieldSchema.Type.STRING, ""));
            columns.add(new HCatFieldSchema("cnt", HCatFieldSchema.Type.BIGINT, ""));
            HCatSchema schema = new HCatSchema(columns);
            long sum = 0;
            Iterator<IntWritable> iter = values.iterator();
            while (iter.hasNext()) sum += iter.next().getLong();
            HCatRecord output = new DefaultHCatRecord(2);
            record.set("user", schema, key.toString());
            record.setLong("cnt", schema, sum);
            context.write(null, record);
        }
    }
    public int run(String[] args) throws Exception {
        Job job = new Job(conf, "Example");
        // Read the "rawevents" table, partition "20120531", in the default
        // database
        HCatInputFormat.setInput(job, InputJobInfo.create(null, "rawevents",
            "datestamp='20120531'"));
        job.setInputFormatClass(HCatInputFormat.class);
        job.setJarByClass(MRExample.class);
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        job.setOutputKeyClass(WritableComparable.class);
        job.setOutputValueClass(DefaultHCatRecord.class);
        // Write into "cntd" table, partition "20120531", in the default database
        HCatOutputFormat.setOutput(job, OutputJobInfo.create(null, "cntd", "ds=20120531"));
        job.setOutputFormatClass(HCatOutputFormat.class);
        return (job.waitForCompletion(true) ? 0 : 1);
    }
    public static void main(String[] args) throws Exception {
        int exitCode = ToolRunner.run(new MRExample(), args);
        System.exit(exitCode);
    }
}

综上所述,通过合理使用Hive与AWS的相关功能以及HCatalog,能更高效地进行数据处理和分析。在实际应用中,需根据具体需求和场景选择合适的方法和配置。

Hive与AWS及HCatalog的使用指南

4. 操作总结与注意事项
4.1 Hive与AWS操作总结

以下是Hive与AWS操作的关键要点总结:
| 操作类型 | 关键要点 |
| ---- | ---- |
| 自定义启动脚本 | 可严格控制执行时间,但需自行管理调用,数据量大时启动时间长 |
| MySQL转储到S3 | 备份元存储,不同Hive版本不共享,需外部持久元存储 |
| HDFS和S3使用 | HDFS存中间结果,S3存输入和最终结果,S3使用可能失去数据本地化优化 |
| 资源上传到S3 | 上传脚本、配置和资源,方便后续Hadoop作业使用 |
| S3日志管理 | 设置log - uri保存日志,定期清理节省成本 |
| 现货实例使用 | 按需选择实例组,注意作业时间可能受影响 |
| 安全组配置 | 修改安全组规则,允许特定端口入站连接 |
| EMR与EC2对比 | EC2可自定义配置,但可能缺少EMR定制功能 |

4.2 HCatalog操作总结

HCatalog主要用于让其他工具访问Hive元存储,其操作总结如下:
- 读取数据 :创建InputJobInfo指定读取信息,使用HCatInputFormat读取,可按需指定列。
- 写入数据 :创建OutputJobInfo指定写入信息,使用HCatOutputFormat写入,支持动态分区。

5. 操作流程梳理
5.1 Hive与AWS操作流程
graph LR
    A[选择操作类型] --> B{自定义启动脚本}
    A --> C{MySQL转储到S3}
    A --> D{资源上传到S3}
    A --> E{日志管理}
    A --> F{使用现货实例}
    A --> G{安全组配置}
    A --> H{选择EMR或EC2}
    B --> B1[编写脚本并管理调用]
    C --> C1[备份元存储到S3]
    D --> D1[上传脚本、配置和资源]
    E --> E1[设置log - uri]
    E --> E2[定期清理日志]
    F --> F1{选择实例组}
    F1 --> F2[配置现货实例参数]
    G --> G1[修改安全组规则]
    H --> H1{选择EMR}
    H --> H2{选择EC2}
    H1 --> H11[使用EMR定制功能]
    H2 --> H21[自定义安装配置]
5.2 HCatalog操作流程
graph LR
    I[选择操作类型] --> J{读取数据}
    I --> K{写入数据}
    J --> J1[创建InputJobInfo]
    J1 --> J2[使用HCatInputFormat读取]
    J2 --> J3[按需指定列]
    K --> K1[创建OutputJobInfo]
    K1 --> K2[使用HCatOutputFormat写入]
    K2 --> K3{是否动态分区}
    K3 --> |是| K4[确保分区列在数据中]
    K3 --> |否| K5[指定分区信息]
6. 常见问题与解决方案
6.1 Hive与AWS常见问题
  • 问题 :自定义启动脚本启动时间过长。
  • 解决方案 :减少表和分区数量,或考虑其他启动方式。
  • 问题 :不同Hive版本无法共享元数据。
  • 解决方案 :使用外部持久元存储。
  • 问题 :S3使用失去数据本地化优化。
  • 解决方案 :处理前将“热”数据从S3导入HDFS。
  • 问题 :现货实例导致作业时间不可预测或失败。
  • 解决方案 :减少现货实例使用,或定期保存中间数据。
6.2 HCatalog常见问题
  • 问题 :Hive v0.9.0及更早版本过滤子句失败。
  • 解决方案 :应用补丁HIVE - 2084.D2397.1.patch。
  • 问题 :写入数据时分区错误。
  • 解决方案 :确保分区列信息正确,动态分区时分区列在数据中。
7. 实际应用案例分析

假设一家电商公司需要对用户行为数据进行分析,以了解用户的购买习惯和偏好。以下是使用上述技术的实际应用案例:

7.1 数据存储与管理
  • 使用S3存储原始用户行为数据,如用户浏览记录、购买记录等。
  • 使用Hive创建外部表,关联S3上的数据,方便后续查询和分析。
CREATE EXTERNAL TABLE user_behavior(id INT, user_id INT, action_type STRING, product_id INT)
PARTITIONED BY (dt STRING)
LOCATION 's3n://example.hive.oreilly.com/tables/user_behavior';
7.2 数据处理与分析
  • 使用HCatalog和MapReduce对数据进行处理,例如统计每个用户的购买次数。
public class UserBehaviorAnalysis extends Configured implements Tool {
    public static class Map extends
        Mapper<WritableComparable, HCatRecord, Text, LongWritable> {
        protected void map(WritableComparable key,
                           HCatRecord value,
                           Mapper<WritableComparable, HCatRecord,
                             Text, LongWritable>.Context context)
                           throws IOException, InterruptedException {
            HCatSchema schema = HCatBaseInputFormat.getOutputSchema(context);
            String user_id = value.get("user_id", schema);
            context.write(new Text(user_id), new LongWritable(1));
        }
    }
    public static class Reduce extends Reducer<Text, LongWritable,
        WritableComparable, HCatRecord> {
        protected void reduce(Text key, Iterable<LongWritable> values,
            Reducer<Text, LongWritable,
            WritableComparable, HCatRecord>.Context context)
            throws IOException ,InterruptedException {
            List<HCatFieldSchema> columns = new ArrayList<HCatFieldSchema>(2);
            columns.add(new HCatFieldSchema("user_id", HCatFieldSchema.Type.STRING, ""));
            columns.add(new HCatFieldSchema("purchase_count", HCatFieldSchema.Type.BIGINT, ""));
            HCatSchema schema = new HCatSchema(columns);
            long sum = 0;
            Iterator<LongWritable> iter = values.iterator();
            while (iter.hasNext()) sum += iter.next().get();
            HCatRecord output = new DefaultHCatRecord(2);
            output.set("user_id", schema, key.toString());
            output.setLong("purchase_count", schema, sum);
            context.write(null, output);
        }
    }
    public int run(String[] args) throws Exception {
        Job job = new Job(conf, "UserBehaviorAnalysis");
        HCatInputFormat.setInput(job, InputJobInfo.create(null, "user_behavior",
            "dt='2024 - 01 - 01'"));
        job.setInputFormatClass(HCatInputFormat.class);
        job.setJarByClass(UserBehaviorAnalysis.class);
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        job.setOutputKeyClass(WritableComparable.class);
        job.setOutputValueClass(DefaultHCatRecord.class);
        HCatOutputFormat.setOutput(job, OutputJobInfo.create(null, "user_purchase_count", null));
        job.setOutputFormatClass(HCatOutputFormat.class);
        return (job.waitForCompletion(true) ? 0 : 1);
    }
    public static void main(String[] args) throws Exception {
        int exitCode = ToolRunner.run(new UserBehaviorAnalysis(), args);
        System.exit(exitCode);
    }
}
7.3 结果存储与使用

将处理结果存储在S3上,方便后续进一步分析或可视化展示。

6. 总结与建议

通过合理使用Hive与AWS的各项功能以及HCatalog,能够高效完成数据的存储、处理和分析任务。在实际应用中,建议:
- 根据数据量和业务需求选择合适的存储方式,如HDFS和S3的搭配使用。
- 谨慎使用现货实例,避免作业时间不可控。
- 及时处理S3上的日志,节省存储成本。
- 利用HCatalog实现不同工具间的数据共享,提高工作效率。

总之,充分掌握这些技术和操作方法,能为数据处理和分析工作带来极大的便利和效率提升。

内容概要:本文介绍了一种基于蒙特卡洛模拟和拉格朗日优化方法的电动汽车充电站有序充电调度策略,重点针对分时电价机制下的分散式优化问题。通过Matlab代码实现,构建了考虑用户充电需求、电网负荷平衡及电价波动的数学模【电动汽车充电站有序充电调度的分散式优化】基于蒙特卡诺和拉格朗日的电动汽车优化调度(分时电价调度)(Matlab代码实现)型,采用拉格朗日乘子法处理约束条件,结合蒙特卡洛方法模拟大量电动汽车的随机充电行为,实现对充电功率和时间的优化分配,旨在降低用户充电成本、平抑电网峰谷差并提升充电站运营效率。该方法体现了智能优化算法在电力系统调度中的实际应用价值。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源汽车、智能电网相关领域的工程技术人员。; 使用场景及目标:①研究电动汽车有序充电调度策略的设计仿真;②学习蒙特卡洛模拟拉格朗日优化在能源系统中的联合应用;③掌握基于分时电价的需求响应优化建模方法;④为微电网、充电站运营管理提供技术支持和决策参考。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注目标函数构建、约束条件处理及优化求解过程,可尝试调整参数设置以观察不同场景下的调度效果,进一步拓展至多目标优化或多类型负荷协调调度的研究。
内容概要:本文围绕面向制造业的鲁棒机器学习集成计算流程展开研究,提出了一套基于Python实现的综合性计算框架,旨在应对制造过程中数据不确定性、噪声干扰面向制造业的鲁棒机器学习集成计算流程研究(Python代码实现)及模型泛化能力不足等问题。该流程集成了数据预处理、特征工程、异常检测、模型训练优化、鲁棒性增强及结果可视化等关键环节,结合集成学习方法提升预测精度稳定性,适用于质量控制、设备故障预警、工艺参数优化等典型制造场景。文中通过实际案例验证了所提方法在提升模型鲁棒性和预测性能方面的有效性。; 适合人群:具备Python编程基础和机器学习基础知识,从事智能制造、工业数据分析及相关领域研究的研发人员工程技术人员,尤其适合工作1-3年希望将机器学习应用于实际制造系统的开发者。; 使用场景及目标:①在制造环境中构建抗干扰能力强、稳定性高的预测模型;②实现对生产过程中的关键指标(如产品质量、设备状态)进行精准监控预测;③提升传统制造系统向智能化转型过程中的数据驱动决策能力。; 阅读建议:建议读者结合文中提供的Python代码实例,逐步复现整个计算流程,并针对自身业务场景进行数据适配模型调优,重点关注鲁棒性设计集成策略的应用,以充分发挥该框架在复杂工业环境下的优势。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值