Advertisement

在Spark或MR引擎中插入的数据,在Hive表中的查询结果为0

  •  5星
  •     浏览量: 0
  •     大小:None
  •      文件类型:DOC


简介:
当在Apache Spark或MapReduce引擎中处理并存储数据至Hive表后遇到查询结果显示为空的情况时,本文将提供排查此类问题的方法和建议。 ### Spark或MR引擎插入的数据在Hive表查询为0的问题解析 #### 问题背景与现象 大数据处理场景下,经常使用不同的执行引擎(如Spark、MapReduce (MR) 或 Tez)进行数据操作。常见的问题是:当通过Spark或MR引擎向Hive表中写入数据后,用Hive查询这些表时发现没有返回任何记录。具体表现为用户报告在Tez引擎环境下可以正常获取到正确结果,但在使用Spark-SQL查询同一张表时却无法读取到任何数据。 #### 原因分析 该问题的根本原因在于执行写入操作的引擎(如Tez)在处理`UNION ALL`指令时会在原始分区目录下生成一个额外子目录,例如`HIVE_UNION_SUBDIR_1`(或类似的命名)。当使用这种机制进行数据合并后,并没有直接将结果存储到对应的主分区中,而是放在了这个新创建的子目录内。如果查询使用的引擎未正确配置处理这种情况,则会导致无法读取实际写入的数据。 #### 解决方案 为解决上述问题,可以从调整数据插入方式和优化查询时的设置两个方面入手: ##### 方案一:改变数据写入策略 1. **更换执行引擎**:最直接的方法是避免使用Tez进行`UNION ALL`操作。可以改用Hive或Spark-SQL作为主要的数据写入工具,这样能确保数据直接存储在指定的分区目录中。 2. **利用二次处理方法**: - 在通过Tez完成合并后,可以通过表插入的方式将分散于子目录中的数据重新组织到主分区文件夹内。 - 另一种选择是在执行`UNION ALL`操作时添加`DISTRIBUTE BY`指令来强制启动一次Reduce过程,这有助于整理和优化数据分布。 ##### 方案二:调整查询引擎配置 1. **MapReduce(MR)的设置**: 设置以下参数以支持子目录读取: ``` set hive.mapred.supports.subdirectories=true; set mapred.input.dir.recursive=true; ``` 2. **Spark-SQL的设置**: 同样需要如下配置来确保数据被正确识别和读取: ``` --conf spark.sql.hive.convertMetastoreOrc=false --conf spark.hadoop.mapred.input.dir.recursive=true ``` #### 结论 通过对上述分析可以了解到,当使用Spark或MR引擎插入的数据在Hive表查询时显示为0条记录的问题主要是由于Tez执行`UNION ALL`操作后产生的子目录问题。通过改变数据写入策略或者优化查询配置都可以有效地解决此问题,在实际应用中可以根据具体情况选择最合适的解决方案以确保数据的准确读取和处理。

全部评论 (0)

还没有任何评论哟~
客服
客服
  • SparkMRHive0
    优质
    当在Apache Spark或MapReduce引擎中处理并存储数据至Hive表后遇到查询结果显示为空的情况时,本文将提供排查此类问题的方法和建议。 ### Spark或MR引擎插入的数据在Hive表查询为0的问题解析 #### 问题背景与现象 大数据处理场景下,经常使用不同的执行引擎(如Spark、MapReduce (MR) 或 Tez)进行数据操作。常见的问题是:当通过Spark或MR引擎向Hive表中写入数据后,用Hive查询这些表时发现没有返回任何记录。具体表现为用户报告在Tez引擎环境下可以正常获取到正确结果,但在使用Spark-SQL查询同一张表时却无法读取到任何数据。 #### 原因分析 该问题的根本原因在于执行写入操作的引擎(如Tez)在处理`UNION ALL`指令时会在原始分区目录下生成一个额外子目录,例如`HIVE_UNION_SUBDIR_1`(或类似的命名)。当使用这种机制进行数据合并后,并没有直接将结果存储到对应的主分区中,而是放在了这个新创建的子目录内。如果查询使用的引擎未正确配置处理这种情况,则会导致无法读取实际写入的数据。 #### 解决方案 为解决上述问题,可以从调整数据插入方式和优化查询时的设置两个方面入手: ##### 方案一:改变数据写入策略 1. **更换执行引擎**:最直接的方法是避免使用Tez进行`UNION ALL`操作。可以改用Hive或Spark-SQL作为主要的数据写入工具,这样能确保数据直接存储在指定的分区目录中。 2. **利用二次处理方法**: - 在通过Tez完成合并后,可以通过表插入的方式将分散于子目录中的数据重新组织到主分区文件夹内。 - 另一种选择是在执行`UNION ALL`操作时添加`DISTRIBUTE BY`指令来强制启动一次Reduce过程,这有助于整理和优化数据分布。 ##### 方案二:调整查询引擎配置 1. **MapReduce(MR)的设置**: 设置以下参数以支持子目录读取: ``` set hive.mapred.supports.subdirectories=true; set mapred.input.dir.recursive=true; ``` 2. **Spark-SQL的设置**: 同样需要如下配置来确保数据被正确识别和读取: ``` --conf spark.sql.hive.convertMetastoreOrc=false --conf spark.hadoop.mapred.input.dir.recursive=true ``` #### 结论 通过对上述分析可以了解到,当使用Spark或MR引擎插入的数据在Hive表查询时显示为0条记录的问题主要是由于Tez执行`UNION ALL`操作后产生的子目录问题。通过改变数据写入策略或者优化查询配置都可以有效地解决此问题,在实际应用中可以根据具体情况选择最合适的解决方案以确保数据的准确读取和处理。
  • Python元组实例
    优质
    本文介绍了如何使用Python进行数据库查询,并展示了将查询结果存储为列表或元组的具体示例。通过这些例子,读者可以轻松掌握数据处理技巧。 在Python进行数据库查询时通常会使用一些连接库如MySQLdb(适用于MySQL)或pymysql。这些库提供了与数据库交互的方法,包括执行SQL语句、获取查询结果等。 默认情况下,MySQLdb库返回的查询结果是一个包含多个tuple的list,每个tuple代表一行记录,并且tuple中的元素对应于查询结果中的列值。例如,如果你有一个用户表`user`,它有两个字段:`num`和`age`, 查询所有记录可能会得到如下格式的结果: ```python [(1000L, 0L), (2000L, 0L), (3000L, 0L)] ``` 这种返回方式要求通过索引访问数据,如 `result[0][1]` 来获取第一行的第二列值。 为了使查询结果更易于处理,可以将游标设置为字典类型(DictCursor)。这使得查询结果以键-值对形式呈现出来。修改后的代码如下: ```python import MySQLdb from MySQLdb.cursors import DictCursor # 连接数据库并创建一个使用字典类型的游标的连接对象。 db = MySQLdb.connect(host=localhost, user=root, passwd=123456, db=test, cursorclass=DictCursor) cur = db.cursor() cur.execute(SELECT * FROM user) rs = cur.fetchall() # 现在可以通过列名直接访问数据,如 rs[0][age]。 print(rs) # 输出类似 { num: 1000L, age: 0L }, { num: 2000L, age: 0L }等字典形式的数据 ``` 对于pymysql来说使用方法相似: ```python import pymysql db = pymysql.connect(localhost, root, 123456, test) cursor = db.cursor(pymysql.cursors.DictCursor) # 查询并获取所有结果。 sql = SELECT * FROM tablelist WHERE id>%s cursor.execute(sql, [4]) result = cursor.fetchall() print(result) ``` 在上面的pymysql示例中,我们使用了DictCursor来使查询返回字典形式的结果。此外还展示了如何执行参数化查询,并且展示了一种遍历tuple类型的查询结果的方法: ```python # 对((6, engineeringdata20180901, 1535731200),)类型数据的提取。 for i in range(len(result)): id_list.append(result[i][0]) tablename_list.append(result[i][1]) tabletime_lsit.append(result[i][2]) print(id_list) print(tabletime_lsit) ``` 通过这种方式,你可以更方便地处理和操作查询结果。特别是在列名较多或含义清晰时使用字典形式的数据会更加直观和高效。在实际应用中可以根据需求选择合适的方式存储和处理数据库的查询结果。
  • 并行计算Spark系列介绍
    优质
    本简介将探讨并行计算引擎Apache Spark,在处理大规模数据集时所展现的强大性能与灵活性,并将其与其他大数据技术进行对比。 本段落介绍的是Apache Spark,这是一个为大规模数据处理设计的快速通用计算引擎。Spark是由加州大学伯克利分校AMP实验室开源的一个类似Hadoop MapReduce的并行框架。它具备了MapReduce的优点,但与之不同的是,在作业中间输出结果可以存储在内存中,因此无需读写HDFS(分布式文件系统),这使得Spark更适合用于数据挖掘和机器学习等需要迭代处理的任务。Spark是一个类似于Hadoop的开源集群计算环境,不过两者之间存在一些差异。
  • MongoDBJSP展示
    优质
    本教程介绍如何将MongoDB数据库中的查询结果通过Java Server Pages (JSP)技术呈现给用户,包括连接数据库、执行查询及动态生成HTML页面等步骤。 在使用MongoDB查询数据并以`DBCursor.next()`形式获取值的情况下,如何将这些值传递到JSP页面进行显示呢?可以上传一个项目示例Demo,导入后可以直接运行,并查看其中的代码实现方式。该项目采用jquery.ajax方法来展示后台返回的Json串格式的数据。如果需要更详细的了解,请参考相关博客文章。
  • MySQL两张示例
    优质
    本教程提供在MySQL数据库中如何从两个不同的表格提取数据的具体示例和SQL语句解释。适合初学者快速掌握基本的多表查询技巧。 主要介绍了如何在MySQL中同时查询两张表的数据示例,即一次查询操作可以返回两张表的结果,有需要的朋友可以参考一下。
  • MySQL两个示例
    优质
    本文章提供了一个实用的例子,展示了如何在MySQL数据库中进行跨两个不同表格的数据查询操作。通过这个例子,读者可以学习到JOIN语句的基本用法以及怎样优化SQL查询以获得更高效的结果提取。适合初学者和有一定经验的开发者参考。 在这个例子中,我们从两个表中各取出前两行数据,并将它们合并到一个表格里。 在实际应用中,经常会遇到这样的场景:在一个数据库中有两个表,假设第一个表存储了公司产品本季度的销售信息,第二个表则记录了公司的欠款情况。如果需要在同一页面上展示这两个信息,通常的做法是在程序代码中执行两次SQL查询来获取结果集,并分别显示出来,这样操作起来比较繁琐。 下面是一个实现上述功能的示例代码: ```sql CREATE PROCEDURE test AS SET NOCOUNT ON --指示存储过程不返回查询影响的行数 DECLARE @col1c varchar(20),@col2c varchar(20) ``` 这段SQL脚本创建了一个名为test的过程,通过设置`NOCOUNT ON`来避免显示每次执行语句的影响行数,并且声明了两个变量用于后续操作。
  • Java展示
    优质
    本教程介绍如何在Java应用程序中高效地执行数据库查询,并将查询结果显示给用户。通过实例讲解,帮助开发者掌握连接数据库、编写SQL语句及处理结果集的方法。 在利用Java开发数据库应用的过程中,常常需要将查询结果展示给用户。为实现这一目标,可以采用Vector、JTable及AbstractTableModel这三个类。 首先解释一下这些类的功能: 1. **Vector 类**: 这是一个存储数据的容器类型,在这里定义如下:`public class Vector extends AbstractList implements List, Cloneable, Serializable{...}` 2. **JTable 类** JTable 是 Swing 包中的一个组件,用于在用户界面中以二维表格的形式展示数据。它的定义为:`public class JTable extends JComponentimplements TableModelListener, Scrollable, TableColumnModelListener, ListSelectionListener, CellEditorListener, Accessible{...}` 3. **AbstractTableModel 类** 这个类是所有表模型的基类,它需要实现以下三个方法: - `public int getRowCount();` - `public int getColumnCount();` - `public Object getValueAt(int row, int column);` 为了展示一个简单的5x5表格实例: ```java TableModel dataModel = new AbstractTableModel() { public int getColumnCount() { return 5; } public int getRowCount() { return 5;} public Object getValueAt(int row, int col) { return new Integer(row*col); } }; JTable table = new JTable(dataModel); JScrollPane scrollpane = new JScrollPane(table); ``` 对于数据库操作,我们使用 Sybase 数据库。这个数据库位于 D:WORKER 文件夹中,并且名为 worker.dbf。此表包含以下字段: - Wno(职工号):VARCHAR - Wname(职工名):VARCHAR - Sex(性别):VARCHAR - Birthday(出生日期):DATE - Wage(工资):FLOAT 为了连接数据库,我们使用了 `java.sql` 包中的 `DriverManager` 类。以下为连接步骤: 1. 加载 Sybase JDBC 驱动程序。 2. 使用驱动管理器注册该驱动。 3. 通过 URL、用户名和密码获取到数据库的连接。 完成这些后就可以利用 Statement 接口进行数据查询或更新操作了。 在实际应用中,我们定义如下对象: - `AbstractTableModel tm;` - `JTable jg_table;` - `Vector vect;` - `JScrollPane jsp;` 并根据需要定制表格。例如设置列名、行数和单元格值等方法,并将数据模型绑定到 JTable 上。 最后,连接数据库后执行 SQL 查询以获取查询结果: ```java Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(select * from worker); // 将查询的数据放入向量中然后更新表格显示。 ``` 为了实现记录的前后翻页功能,可以使用 `rs.previous()` 和 `rs.next()` 方法(如果支持 JDBC2.0),或者通过 Vector 按行读取 JTable 数据并改变指针位置来完成。
  • C#SqlServer库以获取单一方法
    优质
    本文章介绍如何使用C#编程语言连接SqlServer数据库并执行SQL查询来检索单个记录。通过示例代码详细解释了实现过程和关键步骤。适合需要操作数据库的开发者阅读。 在C#编程中与SQL Server数据库交互是一项常见的任务。当我们需要从数据库获取单个值(如整数、字符串或日期)时,可以使用`SqlCommand`对象的`ExecuteScalar`方法或者通过`SqlDataReader`来实现。 为了开始这项工作,请确保已经正确安装了 `System.Data.SqlClient` 命名空间。这是连接和操作SQL Server数据库所需的关键库。如果项目中还没有引用此命名空间,则可以在`.csproj`文件中添加以下内容: ```xml ``` 接下来,我们来看如何编写一个通用的方法来执行SQL查询并返回单个值。这个方法接收三个参数:SQL查询语句、参数数组(如果有的话)以及数据库连接字符串。 以下是示例代码: ```csharp using System; using System.Data.SqlClient; public static class DatabaseHelper { public static string GetSingleValueAsString(string sqlText, SqlParameter[] sqlParameters, string databaseConnectionString) { string result = ; try { // 创建SqlConnection对象并使用给定的连接字符串打开数据库连接。 using (SqlConnection connection = new SqlConnection(databaseConnectionString)) { // 使用SQL查询语句创建SqlCommand对象,并将参数添加到命令中(如果有的话)。 using (SqlCommand command = new SqlCommand(sqlText, connection)) { if (sqlParameters != null) { command.Parameters.AddRange(sqlParameters); } // 打开数据库连接并执行查询,`ExecuteScalar`方法返回第一行的第一列的值。 connection.Open(); object data = command.ExecuteScalar(); // 检查是否有结果,并且该结果可以转换为字符串类型。 if (data != null && data != DBNull.Value) result = data.ToString(); } } } catch (Exception ex) { // 记录或处理异常,例如将错误信息打印到控制台 Console.WriteLine($Error occurred while fetching single value: {ex.Message}); } return result; } } ``` 在上述代码中,我们创建了一个名为`GetSingleValueAsString`的静态方法。此方法使用SqlConnection打开数据库连接,并通过SqlCommand执行SQL查询。ExecuteScalar方法返回查询结果的第一行第一列的值;如果查询没有结果,则它将返回null。如果有可以转换为字符串类型的非空数据,那么就将其转储到result变量中。 在处理数据库操作时,请务必使用using语句来确保数据库连接和命令对象在不再需要它们的时候正确关闭并释放资源以避免内存泄漏。同时,在编写代码时要充分考虑异常处理机制的实现,这是保证程序健壮性的重要措施之一。 这个方法适用于简单的查询任务,例如获取单个字段值(如用户ID、产品价格等)。然而,如果查询返回多行或多列数据,则应使用`ExecuteReader`方法配合`SqlDataReader`进行迭代处理或者采用DataTable或DataSet来存储所有结果。在实际应用中,通常建议使用ORM框架(比如Entity Framework),这可以提供更高层次的抽象,并使数据库操作更为简便和安全。 理解基础的ADO.NET操作仍然非常重要,特别是在需要自定义SQL查询或是与现有非ORM系统集成的情况下。
  • Hive操作
    优质
    本教程深入讲解了Apache Hive中的查询操作,包括SQL语法、数据筛选、排序及连接等核心概念和实践技巧,帮助用户高效处理大规模数据集。 一、查询语法 Hive的查询语句遵循标准SQL的基本结构,并且有一些特有的扩展。基本语法如下: ```sql [WITH CommonTableExpression (, CommonTableExpression)*] SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [ORDER BY col_list] [CLUSTER BY col_list | [DISTRIBUTE BY col_list]] [SORT BY col_list] [LIMIT number] ``` - `WITH` 子句用于创建临时的结果表(Common Table Expressions,CTE),从这些结果表中可以进一步进行查询。 - `SELECT` 部分用于指定要从表中选择的列或表达式。使用 `ALL` 表示选择所有行,而用 `DISTINCT` 来去除重复行。 - 在 `FROM` 后跟的是你要查询的表名或者视图(table_reference)。 - 使用 `WHERE` 子句设置查询条件,只有满足这些条件的数据才会被返回。 - 通过使用 `GROUP BY` 对数据进行分组,并且通常与聚合函数如 COUNT, SUM, AVG 等一起使用。 - 使用 `ORDER BY` 对结果集中的行按照某一列排序。默认情况下是升序排列(ASC),也可以指定降序排列(DESC)。 - `CLUSTER BY` 和 `DISTRIBUTE BY` 主要用于分布式计算环境,控制数据如何分布到不同的分区或节点上。 - 使用 `SORT BY` 进行本地排序,只在单个节点内部有效。 - 最后通过使用 `LIMIT` 来限制返回的行数。 二、基本查询 1. **全表和特定列查询** - 全表查询:使用星号(*)代表所有列,例如 `SELECT * FROM emp;` - 特定列查询:列出需要的列名,如 `SELECT empno, ename FROM emp;` 2. **设置别名** 使用关键字`AS`可以为结果集中的字段提供更易理解的名字。比如,使用 `SELECT ename AS name, deptno dn FROM emp;` 可以使得查询输出更具可读性。 3. **算术运算符** Hive 支持基本的算数操作如加法(`+`)、减法(`-`)、乘法(`*`)、除法(`/`) 和取模 (`%`). 例如,执行 `SELECT sal + 1 AS sal FROM emp;` 将返回每个员工薪水增加一的结果。 4. **其他操作** - 聚合函数:如 COUNT, SUM, AVG, MIN, MAX 等用于统计或计算一组值。 - 比较运算符:包括 =、<、>、<=、>= 和 !=,用于比较两个值。 - 逻辑运算符 AND、OR 和 NOT 可以用来组合条件。 - 字符串函数:如 CONCAT, SUBSTRING, UPPER, LOWER 等来处理字符串数据。 三、注意事项 - Hive SQL 对大小写不敏感,但是为了提高代码的可读性,建议使用大写字母书写关键词。 - 语句可以写在一行或多行中。然而,为增加清晰度和易于理解复杂查询结构,推荐每条语句的关键部分独立成行展示。 - 关键词不应被缩写,并且不应当分行书写。 - 使用适当的缩进来提升代码的可读性。 实际操作时结合这些基本查询方法,可以构建满足各种需求复杂的查询以实现高效的大规模数据处理。